Auto merge of #7879 - mrobinson:layer-tree-dump, r=glennw

Improve layer tree debugging output

Add an option to dump the layer tree, which activates the previously
unused layer tree debugging code. Also improve the output using the
PrintTree struct.

Previous output:
```
Layer tree:
Layer 7f63b45b2010: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 0-FragmentBody, wants_scroll_events: WantsScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(4), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(800, PhantomData)×Length(600, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: true establishes 3D context: true
  Layer 7f63b45b2290: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919922672-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(800, PhantomData)×Length(650, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: false establishes 3D context: true
    Layer 7f63b45b3410: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919923248-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: FixedPosition, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(18, PhantomData),Length(10, PhantomData))) masks to bounds: false establishes 3D context: false
    Layer 7f63b45b3190: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919923872-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: FixedPosition, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(93, PhantomData),Length(10, PhantomData))) masks to bounds: false establishes 3D context: false
    Layer 7f63b45b2f10: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919924496-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: Some((PipelineId(0), SubpageId(0))) } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(168, PhantomData),Length(10, PhantomData))) masks to bounds: false establishes 3D context: false
      Layer 7f63b45b3b90: RefCell { value: CompositorData { pipeline_id: PipelineId(1), id: 0-FragmentBody, wants_scroll_events: WantsScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(3), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: Some((PipelineId(0), SubpageId(0))) } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: true establishes 3D context: true
        Layer 7f63b45b3e10: RefCell { value: CompositorData { pipeline_id: PipelineId(1), id: 140065901048256-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(4), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(50, PhantomData)×Length(58, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: false establishes 3D context: true
    Layer 7f63b45b2c90: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919925168-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: Some((PipelineId(0), SubpageId(1))) } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(243, PhantomData),Length(10, PhantomData))) masks to bounds: false establishes 3D context: false
      Layer 7f63b45b2790: RefCell { value: CompositorData { pipeline_id: PipelineId(2), id: 0-FragmentBody, wants_scroll_events: WantsScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(3), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: Some((PipelineId(0), SubpageId(1))) } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: true establishes 3D context: true
        Layer 7f63b45b2510: RefCell { value: CompositorData { pipeline_id: PipelineId(2), id: 140065880076736-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(4), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(50, PhantomData)×Length(58, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: false establishes 3D context: true
    Layer 7f63b45b3910: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919925168-FragmentBody-companion, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(800, PhantomData)×Length(650, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: false establishes 3D context: false
    Layer 7f63b45b2a10: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919924064-FragmentBody, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(50, PhantomData)×Length(50, PhantomData) at (Length(103, PhantomData),Length(30, PhantomData))) masks to bounds: false establishes 3D context: false
    Layer 7f63b45b3690: RefCell { value: CompositorData { pipeline_id: PipelineId(0), id: 140065919924064-FragmentBody-companion, wants_scroll_events: DoesntWantScrollEvents, scroll_policy: Scrollable, requested_epoch: Epoch(5), painted_epoch: Epoch(0), scroll_offset: (Length(0, PhantomData),Length(0, PhantomData)), subpage_info: None } } @ Rect(Length(800, PhantomData)×Length(650, PhantomData) at (Length(0, PhantomData),Length(0, PhantomData))) masks to bounds: false establishes 3D context: false
```

New output:
```
┌ Layer tree
│  ├─ Root Layer (pipeline=0) (0-FragmentBody) (800,600 at 0,0) (masks children) (3D context)
│  │  ├─ Layer (140279059771888-FragmentBody) (800,650 at 0,0) (3D context)
│  │  │  ├─ Layer (140279059772464-FragmentBody) (50,50 at 18,10) (fixed)
│  │  │  ├─ Layer (140279059773088-FragmentBody) (50,50 at 93,10) (fixed)
│  │  │  ├─ Layer (140279059773712-FragmentBody) (50,50 at 168,10)
│  │  │  │  ├─ Root Layer (pipeline=1) (0-FragmentBody) (50,50 at 0,0) (masks children) (3D context)
│  │  │  │  │  └─ Layer (140278833279472-FragmentBody) (50,58 at 0,0) (3D context)
│  │  │  ├─ Layer (140279059774384-FragmentBody) (50,50 at 243,10)
│  │  │  │  ├─ Root Layer (pipeline=2) (0-FragmentBody) (50,50 at 0,0) (masks children) (3D context)
│  │  │  │  │  └─ Layer (140279013634496-FragmentBody) (50,58 at 0,0) (3D context)
│  │  │  ├─ Layer (140279059774384-FragmentBody-companion) (800,650 at 0,0)
│  │  │  ├─ Layer (140279059773280-FragmentBody) (50,50 at 103,30)
│  │  │  └─ Layer (140279059773280-FragmentBody-companion) (800,650 at 0,0)
```

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7879)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-10-06 17:20:50 -06:00
commit 507beda4c7
2 changed files with 65 additions and 16 deletions

View file

@ -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<Window: WindowMethods> IOCompositor<Window> {
}
self.send_buffer_requests_for_all_layers();
self.dump_layer_tree();
}
(Msg::GetNativeDisplay(chan),
@ -876,6 +878,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.pending_subpages.insert(subpage_pipeline_id);
}
}
self.dump_layer_tree();
}
fn send_window_size(&self) {
@ -1573,6 +1577,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
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<Window: WindowMethods> IOCompositor<Window> {
#[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<CompositorData>, level: u32) {
let mut indentation = String::new();
for _ in 0..level {
indentation.push_str(" ");
}
fn dump_layer_tree_layer(&self, layer: &Layer<CompositorData>, 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);
}
}
}

View file

@ -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"),