diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-11-22 21:07:34 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-11-22 21:07:57 +0100 |
commit | b13f62714a98e873bd9a50b61210161b76294284 (patch) | |
tree | b54f3ad863ed4b235c624595a738c639e47d79c8 /ports | |
parent | a812af51d614bd96402da91d8f648ce51b301a1b (diff) | |
download | servo-b13f62714a98e873bd9a50b61210161b76294284.tar.gz servo-b13f62714a98e873bd9a50b61210161b76294284.zip |
stylo: Make TraverseSubtree cheaper in the initial styling case.
We assert against the display: none / unstyled parent already, so there's no
need to check it here as well.
Diffstat (limited to 'ports')
-rw-r--r-- | ports/geckolib/glue.rs | 80 |
1 files changed, 51 insertions, 29 deletions
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 15ee1e945fc..823461d9eec 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -228,24 +228,14 @@ fn create_shared_context<'a>(global_style_data: &GlobalStyleData, } } -fn traverse_subtree(element: GeckoElement, - raw_data: RawServoStyleSetBorrowed, - traversal_flags: TraversalFlags, - snapshots: &ServoElementSnapshotTable) { - // When new content is inserted in a display:none subtree, we will call into - // servo to try to style it. Detect that here and bail out. - if let Some(parent) = element.traversal_parent() { - if parent.borrow_data().map_or(true, |d| d.styles.is_display_none()) { - debug!("{:?} has unstyled parent {:?} - ignoring call to traverse_subtree", element, parent); - return; - } - } - - let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); - debug_assert!(!per_doc_data.stylist.stylesheets_have_changed()); - - let global_style_data = &*GLOBAL_STYLE_DATA; - let guard = global_style_data.shared_lock.read(); +fn traverse_subtree( + element: GeckoElement, + global_style_data: &GlobalStyleData, + per_doc_data: &PerDocumentStyleDataImpl, + guard: &SharedRwLockReadGuard, + traversal_flags: TraversalFlags, + snapshots: &ServoElementSnapshotTable, +) { let shared_style_context = create_shared_context( &global_style_data, &guard, @@ -295,23 +285,50 @@ pub extern "C" fn Servo_TraverseSubtree( debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags); debug!("{:?}", ShowSubtreeData(element.as_node())); + if cfg!(debug_assertions) { + if let Some(parent) = element.traversal_parent() { + let data = + parent.borrow_data().expect("Styling element with unstyled parent"); + assert!( + !data.styles.is_display_none(), + "Styling element with display: none parent" + ); + } + } + let needs_animation_only_restyle = element.has_animation_only_dirty_descendants() || element.has_animation_restyle_hints(); + let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); + debug_assert!(!per_doc_data.stylist.stylesheets_have_changed()); + + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + + let was_initial_style = element.get_data().is_none(); + if needs_animation_only_restyle { debug!("Servo_TraverseSubtree doing animation-only restyle (aodd={})", element.has_animation_only_dirty_descendants()); - traverse_subtree(element, - raw_data, - traversal_flags | TraversalFlags::AnimationOnly, - unsafe { &*snapshots }); + traverse_subtree( + element, + &global_style_data, + &per_doc_data, + &guard, + traversal_flags | TraversalFlags::AnimationOnly, + unsafe { &*snapshots }, + ); } - traverse_subtree(element, - raw_data, - traversal_flags, - unsafe { &*snapshots }); + traverse_subtree( + element, + &global_style_data, + &per_doc_data, + &guard, + traversal_flags, + unsafe { &*snapshots }, + ); debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, lfcd={}, lfc={}, data={:?})", element.has_dirty_descendants(), @@ -320,9 +337,14 @@ pub extern "C" fn Servo_TraverseSubtree( element.needs_frame(), element.borrow_data().unwrap()); - let element_was_restyled = - element.borrow_data().unwrap().contains_restyle_data(); - element_was_restyled + if was_initial_style { + debug_assert!(!element.borrow_data().unwrap().contains_restyle_data()); + false + } else { + let element_was_restyled = + element.borrow_data().unwrap().contains_restyle_data(); + element_was_restyled + } } /// Checks whether the rule tree has crossed its threshold for unused nodes, and |