servo: Merge #19341 - stylo: Make TraverseSubtree cheaper in the initial styling case (from emilio:traversal-new-faster); r=heycam

This helps with bug 1419694.

Source-Repo: https://github.com/servo/servo
Source-Revision: cd70a01d327d4e690626b4ce6f301d4cc6ae9a87

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 1f52f926d453a5038f4c9f160150196bf3059c42
This commit is contained in:
Emilio Cobos Álvarez 2017-11-23 05:44:09 -06:00
Родитель e8f6af16d7
Коммит d417e50177
1 изменённых файлов: 64 добавлений и 41 удалений

Просмотреть файл

@ -211,41 +211,32 @@ unsafe fn dummy_url_data() -> &'static RefPtr<URLExtraData> {
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
}
fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
guard: &'a SharedRwLockReadGuard,
per_doc_data: &'a PerDocumentStyleDataImpl,
traversal_flags: TraversalFlags,
snapshot_map: &'a ServoElementSnapshotTable)
-> SharedStyleContext<'a> {
fn create_shared_context<'a>(
global_style_data: &GlobalStyleData,
guard: &'a SharedRwLockReadGuard,
per_doc_data: &'a PerDocumentStyleDataImpl,
traversal_flags: TraversalFlags,
snapshot_map: &'a ServoElementSnapshotTable,
) -> SharedStyleContext<'a> {
SharedStyleContext {
stylist: &per_doc_data.stylist,
visited_styles_enabled: per_doc_data.visited_styles_enabled(),
options: global_style_data.options.clone(),
guards: StylesheetGuards::same(guard),
timer: Timer::new(),
traversal_flags: traversal_flags,
snapshot_map: snapshot_map,
traversal_flags,
snapshot_map,
}
}
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 +286,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 +338,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
@ -740,10 +763,10 @@ pub extern "C" fn Servo_AnimationValue_Transform(
}
#[no_mangle]
pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBorrowed,
other: RawServoAnimationValueBorrowed)
-> bool
{
pub extern "C" fn Servo_AnimationValue_DeepEqual(
this: RawServoAnimationValueBorrowed,
other: RawServoAnimationValueBorrowed,
) -> bool {
let this_value = AnimationValue::as_arc(&this);
let other_value = AnimationValue::as_arc(&other);
this_value == other_value