mirror of
https://github.com/servo/servo.git
synced 2025-07-10 00:43:39 +01:00
Auto merge of #19341 - emilio:traversal-new-faster, r=heycam
stylo: Make TraverseSubtree cheaper in the initial styling case. This helps with bug 1419694. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19341) <!-- Reviewable:end -->
This commit is contained in:
commit
cd70a01d32
1 changed files with 64 additions and 41 deletions
|
@ -211,41 +211,32 @@ unsafe fn dummy_url_data() -> &'static RefPtr<URLExtraData> {
|
||||||
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
|
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
|
fn create_shared_context<'a>(
|
||||||
guard: &'a SharedRwLockReadGuard,
|
global_style_data: &GlobalStyleData,
|
||||||
per_doc_data: &'a PerDocumentStyleDataImpl,
|
guard: &'a SharedRwLockReadGuard,
|
||||||
traversal_flags: TraversalFlags,
|
per_doc_data: &'a PerDocumentStyleDataImpl,
|
||||||
snapshot_map: &'a ServoElementSnapshotTable)
|
traversal_flags: TraversalFlags,
|
||||||
-> SharedStyleContext<'a> {
|
snapshot_map: &'a ServoElementSnapshotTable,
|
||||||
|
) -> SharedStyleContext<'a> {
|
||||||
SharedStyleContext {
|
SharedStyleContext {
|
||||||
stylist: &per_doc_data.stylist,
|
stylist: &per_doc_data.stylist,
|
||||||
visited_styles_enabled: per_doc_data.visited_styles_enabled(),
|
visited_styles_enabled: per_doc_data.visited_styles_enabled(),
|
||||||
options: global_style_data.options.clone(),
|
options: global_style_data.options.clone(),
|
||||||
guards: StylesheetGuards::same(guard),
|
guards: StylesheetGuards::same(guard),
|
||||||
timer: Timer::new(),
|
timer: Timer::new(),
|
||||||
traversal_flags: traversal_flags,
|
traversal_flags,
|
||||||
snapshot_map: snapshot_map,
|
snapshot_map,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse_subtree(element: GeckoElement,
|
fn traverse_subtree(
|
||||||
raw_data: RawServoStyleSetBorrowed,
|
element: GeckoElement,
|
||||||
traversal_flags: TraversalFlags,
|
global_style_data: &GlobalStyleData,
|
||||||
snapshots: &ServoElementSnapshotTable) {
|
per_doc_data: &PerDocumentStyleDataImpl,
|
||||||
// When new content is inserted in a display:none subtree, we will call into
|
guard: &SharedRwLockReadGuard,
|
||||||
// servo to try to style it. Detect that here and bail out.
|
traversal_flags: TraversalFlags,
|
||||||
if let Some(parent) = element.traversal_parent() {
|
snapshots: &ServoElementSnapshotTable,
|
||||||
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();
|
|
||||||
let shared_style_context = create_shared_context(
|
let shared_style_context = create_shared_context(
|
||||||
&global_style_data,
|
&global_style_data,
|
||||||
&guard,
|
&guard,
|
||||||
|
@ -295,23 +286,50 @@ pub extern "C" fn Servo_TraverseSubtree(
|
||||||
debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags);
|
debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags);
|
||||||
debug!("{:?}", ShowSubtreeData(element.as_node()));
|
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 =
|
let needs_animation_only_restyle =
|
||||||
element.has_animation_only_dirty_descendants() ||
|
element.has_animation_only_dirty_descendants() ||
|
||||||
element.has_animation_restyle_hints();
|
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 {
|
if needs_animation_only_restyle {
|
||||||
debug!("Servo_TraverseSubtree doing animation-only restyle (aodd={})",
|
debug!("Servo_TraverseSubtree doing animation-only restyle (aodd={})",
|
||||||
element.has_animation_only_dirty_descendants());
|
element.has_animation_only_dirty_descendants());
|
||||||
traverse_subtree(element,
|
traverse_subtree(
|
||||||
raw_data,
|
element,
|
||||||
traversal_flags | TraversalFlags::AnimationOnly,
|
&global_style_data,
|
||||||
unsafe { &*snapshots });
|
&per_doc_data,
|
||||||
|
&guard,
|
||||||
|
traversal_flags | TraversalFlags::AnimationOnly,
|
||||||
|
unsafe { &*snapshots },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
traverse_subtree(element,
|
traverse_subtree(
|
||||||
raw_data,
|
element,
|
||||||
traversal_flags,
|
&global_style_data,
|
||||||
unsafe { &*snapshots });
|
&per_doc_data,
|
||||||
|
&guard,
|
||||||
|
traversal_flags,
|
||||||
|
unsafe { &*snapshots },
|
||||||
|
);
|
||||||
|
|
||||||
debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, lfcd={}, lfc={}, data={:?})",
|
debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, lfcd={}, lfc={}, data={:?})",
|
||||||
element.has_dirty_descendants(),
|
element.has_dirty_descendants(),
|
||||||
|
@ -320,9 +338,14 @@ pub extern "C" fn Servo_TraverseSubtree(
|
||||||
element.needs_frame(),
|
element.needs_frame(),
|
||||||
element.borrow_data().unwrap());
|
element.borrow_data().unwrap());
|
||||||
|
|
||||||
let element_was_restyled =
|
if was_initial_style {
|
||||||
element.borrow_data().unwrap().contains_restyle_data();
|
debug_assert!(!element.borrow_data().unwrap().contains_restyle_data());
|
||||||
element_was_restyled
|
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
|
/// 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]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBorrowed,
|
pub extern "C" fn Servo_AnimationValue_DeepEqual(
|
||||||
other: RawServoAnimationValueBorrowed)
|
this: RawServoAnimationValueBorrowed,
|
||||||
-> bool
|
other: RawServoAnimationValueBorrowed,
|
||||||
{
|
) -> bool {
|
||||||
let this_value = AnimationValue::as_arc(&this);
|
let this_value = AnimationValue::as_arc(&this);
|
||||||
let other_value = AnimationValue::as_arc(&other);
|
let other_value = AnimationValue::as_arc(&other);
|
||||||
this_value == other_value
|
this_value == other_value
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue