aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_thread_2020/lib.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2020-02-24 01:12:15 -0500
committerGitHub <noreply@github.com>2020-02-24 01:12:15 -0500
commit2d1ec68d319f3eb2f612b2b698168c8ddbec557d (patch)
tree47b4b26db54da616edaa34858a27c5d37813b308 /components/layout_thread_2020/lib.rs
parent08c7d084e52e5c686ccaef0a9cbff73727a34cb1 (diff)
parent5e76c93cc79613d5845fc726be5e420e431fea04 (diff)
downloadservo-2d1ec68d319f3eb2f612b2b698168c8ddbec557d.tar.gz
servo-2d1ec68d319f3eb2f612b2b698168c8ddbec557d.zip
Auto merge of #25803 - ferjm:layout_debug, r=SimonSapin
Layout viewer for layout 2020 - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors This PR makes layout 2020 dump the box and fragment tree states into json files that can be visualized with the layout viewer tool. This tool has not much functionality other than displaying these trees and allowing to inspect each node additional data, so there is a lot of room for improvements. Some ideas for follow-ups: - Make the tool create and display diffs between tree states. - Actually allow creating new debug scopes during box tree and fragment tree construction. Right now there is a single scope created after constructing both trees, which is not ideal as it only allows looking at the reflow result. - Right now an independent JSON file is created per reflow. It would be nice to unify the data obtained on each reflow on a single JSON, so diffs between reflows can be displayed as well. - Dump and display the DOM tree. Link boxes to DOM nodes. - #23339
Diffstat (limited to 'components/layout_thread_2020/lib.rs')
-rw-r--r--components/layout_thread_2020/lib.rs52
1 files changed, 35 insertions, 17 deletions
diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs
index 2972f7ef46f..1a150401296 100644
--- a/components/layout_thread_2020/lib.rs
+++ b/components/layout_thread_2020/lib.rs
@@ -36,6 +36,7 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use layout::context::LayoutContext;
use layout::display_list::{DisplayListBuilder, WebRenderImageInfo};
+use layout::layout_debug;
use layout::query::{
process_content_box_request, process_content_boxes_request, LayoutRPCImpl, LayoutThreadData,
};
@@ -172,10 +173,10 @@ pub struct LayoutThread {
outstanding_web_fonts: Arc<AtomicUsize>,
/// The root of the box tree.
- box_tree_root: RefCell<Option<BoxTreeRoot>>,
+ box_tree_root: RefCell<Option<Arc<BoxTreeRoot>>>,
/// The root of the fragment tree.
- fragment_tree_root: RefCell<Option<FragmentTreeRoot>>,
+ fragment_tree_root: RefCell<Option<Arc<FragmentTreeRoot>>>,
/// The document-specific shared lock used for author-origin stylesheets
document_shared_lock: Option<SharedRwLock>,
@@ -234,6 +235,10 @@ pub struct LayoutThread {
/// Emits notifications when there is a relayout.
relayout_event: bool,
+
+ /// True if each step of layout is traced to an external JSON file
+ /// for debugging purposes.
+ trace_layout: bool,
}
impl LayoutThreadFactory for LayoutThread {
@@ -266,7 +271,7 @@ impl LayoutThreadFactory for LayoutThread {
dump_rule_tree: bool,
relayout_event: bool,
_nonincremental_layout: bool,
- _trace_layout: bool,
+ trace_layout: bool,
dump_flow_tree: bool,
) {
thread::Builder::new()
@@ -315,6 +320,7 @@ impl LayoutThreadFactory for LayoutThread {
dump_style_tree,
dump_rule_tree,
dump_flow_tree,
+ trace_layout,
);
let reporter_name = format!("layout-reporter-{}", id);
@@ -483,6 +489,7 @@ impl LayoutThread {
dump_style_tree: bool,
dump_rule_tree: bool,
dump_flow_tree: bool,
+ trace_layout: bool,
) -> LayoutThread {
// Let webrender know about this pipeline by sending an empty display list.
webrender_api_sender.send_initial_transaction(webrender_document, id.to_webrender());
@@ -568,6 +575,7 @@ impl LayoutThread {
dump_style_tree,
dump_rule_tree,
dump_flow_tree,
+ trace_layout,
}
}
@@ -870,9 +878,9 @@ impl LayoutThread {
self.dump_style_tree,
self.dump_rule_tree,
self.relayout_event,
- true, // nonincremental_layout
- false, // trace_layout
- self.dump_flow_tree,
+ true, // nonincremental_layout
+ self.trace_layout, // trace_layout
+ self.dump_flow_tree, // dump_flow_tree
);
}
@@ -1152,7 +1160,8 @@ impl LayoutThread {
} else {
build_box_tree()
};
- Some(box_tree)
+
+ Some(Arc::new(box_tree))
} else {
None
};
@@ -1165,11 +1174,11 @@ impl LayoutThread {
self.viewport_size.height.to_f32_px(),
);
let run_layout = || box_tree.layout(&layout_context, viewport_size);
- let fragment_tree = if let Some(pool) = rayon_pool {
+ let fragment_tree = Arc::new(if let Some(pool) = rayon_pool {
pool.install(run_layout)
} else {
run_layout()
- };
+ });
*self.box_tree_root.borrow_mut() = Some(box_tree);
*self.fragment_tree_root.borrow_mut() = Some(fragment_tree);
}
@@ -1201,7 +1210,7 @@ impl LayoutThread {
// Perform post-style recalculation layout passes.
if let Some(root) = &*self.fragment_tree_root.borrow() {
self.perform_post_style_recalc_layout_passes(
- root,
+ root.clone(),
&data.reflow_goal,
Some(&document),
&mut layout_context,
@@ -1232,10 +1241,8 @@ impl LayoutThread {
match *reflow_goal {
ReflowGoal::LayoutQuery(ref querymsg, _) => match querymsg {
&QueryMsg::ContentBoxQuery(node) => {
- rw_data.content_box_response = process_content_box_request(
- node,
- (&*self.fragment_tree_root.borrow()).as_ref(),
- );
+ rw_data.content_box_response =
+ process_content_box_request(node, self.fragment_tree_root.borrow().clone());
},
&QueryMsg::ContentBoxesQuery(node) => {
rw_data.content_boxes_response = process_content_boxes_request(node);
@@ -1250,7 +1257,7 @@ impl LayoutThread {
&QueryMsg::ClientRectQuery(node) => {
rw_data.client_rect_response = process_node_geometry_request(
node,
- (&*self.fragment_tree_root.borrow()).as_ref(),
+ self.fragment_tree_root.borrow().clone(),
);
},
&QueryMsg::NodeScrollGeometryQuery(node) => {
@@ -1364,7 +1371,7 @@ impl LayoutThread {
let mut layout_context = self.build_layout_context(guards, false, &snapshots, origin);
self.perform_post_style_recalc_layout_passes(
- root,
+ root.clone(),
&ReflowGoal::TickAnimations,
None,
&mut layout_context,
@@ -1375,11 +1382,17 @@ impl LayoutThread {
fn perform_post_style_recalc_layout_passes(
&self,
- fragment_tree: &FragmentTreeRoot,
+ fragment_tree: Arc<FragmentTreeRoot>,
reflow_goal: &ReflowGoal,
document: Option<&ServoLayoutDocument>,
context: &mut LayoutContext,
) {
+ if self.trace_layout {
+ if let Some(box_tree) = &*self.box_tree_root.borrow() {
+ layout_debug::begin_trace(box_tree.clone(), fragment_tree.clone());
+ }
+ }
+
if !reflow_goal.needs_display() {
// Defer the paint step until the next ForDisplay.
//
@@ -1390,6 +1403,7 @@ impl LayoutThread {
.needs_paint_from_layout();
return;
}
+
if let Some(document) = document {
document.will_paint();
}
@@ -1432,6 +1446,10 @@ impl LayoutThread {
display_list.wr.finalize(),
);
+ if self.trace_layout {
+ layout_debug::end_trace(self.generation.get());
+ }
+
self.generation.set(self.generation.get() + 1);
}