mirror of
https://github.com/servo/servo.git
synced 2025-08-01 11:40:30 +01:00
Write animated values into the ComputedValues
structures when
animations complete or are interrupted. This adds a new pair of reader-writer locks. I measured the performance of style recalculation on Wikipedia and the overhead of the locks was not measurable. Closes #7816.
This commit is contained in:
parent
6f35b867c9
commit
e881f0feeb
5 changed files with 134 additions and 56 deletions
|
@ -414,6 +414,10 @@ trait PrivateMatchMethods {
|
|||
shareable: bool,
|
||||
animate_properties: bool)
|
||||
-> RestyleDamage;
|
||||
fn update_animations_for_cascade(&self,
|
||||
layout_context: &SharedLayoutContext,
|
||||
style: &mut Option<Arc<ComputedValues>>)
|
||||
-> bool;
|
||||
}
|
||||
|
||||
trait PrivateElementMatchMethods {
|
||||
|
@ -435,20 +439,12 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
|
|||
shareable: bool,
|
||||
animate_properties: bool)
|
||||
-> RestyleDamage {
|
||||
// Finish any transitions.
|
||||
let mut cacheable = true;
|
||||
if animate_properties {
|
||||
if let Some(ref mut style) = *style {
|
||||
let this_opaque = self.opaque();
|
||||
if let Some(ref animations) = layout_context.running_animations.get(&this_opaque) {
|
||||
for animation in *animations {
|
||||
animation.property_animation.update(&mut *Arc::make_mut(style), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
cacheable = !self.update_animations_for_cascade(layout_context, style) && cacheable;
|
||||
}
|
||||
|
||||
let mut this_style;
|
||||
let cacheable;
|
||||
match parent_style {
|
||||
Some(ref parent_style) => {
|
||||
let cache_entry = applicable_declarations_cache.find(applicable_declarations);
|
||||
|
@ -461,7 +457,7 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
|
|||
shareable,
|
||||
Some(&***parent_style),
|
||||
cached_computed_values);
|
||||
cacheable = is_cacheable;
|
||||
cacheable = cacheable && is_cacheable;
|
||||
this_style = the_style
|
||||
}
|
||||
None => {
|
||||
|
@ -470,7 +466,7 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
|
|||
shareable,
|
||||
None,
|
||||
None);
|
||||
cacheable = is_cacheable;
|
||||
cacheable = cacheable && is_cacheable;
|
||||
this_style = the_style
|
||||
}
|
||||
};
|
||||
|
@ -479,10 +475,12 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
|
|||
// it did trigger a transition.
|
||||
if animate_properties {
|
||||
if let Some(ref style) = *style {
|
||||
animation::start_transitions_if_applicable(new_animations_sender,
|
||||
self.opaque(),
|
||||
&**style,
|
||||
&mut this_style);
|
||||
let animations_started =
|
||||
animation::start_transitions_if_applicable(new_animations_sender,
|
||||
self.opaque(),
|
||||
&**style,
|
||||
&mut this_style);
|
||||
cacheable = cacheable && !animations_started
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,6 +498,50 @@ impl<'ln> PrivateMatchMethods for ServoLayoutNode<'ln> {
|
|||
*style = Some(this_style);
|
||||
damage
|
||||
}
|
||||
|
||||
fn update_animations_for_cascade(&self,
|
||||
layout_context: &SharedLayoutContext,
|
||||
style: &mut Option<Arc<ComputedValues>>)
|
||||
-> bool {
|
||||
let style = match *style {
|
||||
None => return false,
|
||||
Some(ref mut style) => style,
|
||||
};
|
||||
|
||||
// Finish any expired transitions.
|
||||
let this_opaque = self.opaque();
|
||||
let had_animations_to_expire;
|
||||
{
|
||||
let all_expired_animations = layout_context.expired_animations.read().unwrap();
|
||||
let animations_to_expire = all_expired_animations.get(&this_opaque);
|
||||
had_animations_to_expire = animations_to_expire.is_some();
|
||||
if let Some(ref animations) = animations_to_expire {
|
||||
for animation in *animations {
|
||||
animation.property_animation.update(&mut *Arc::make_mut(style), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if had_animations_to_expire {
|
||||
layout_context.expired_animations.write().unwrap().remove(&this_opaque);
|
||||
}
|
||||
|
||||
// Merge any running transitions into the current style, and cancel them.
|
||||
let had_running_animations = layout_context.running_animations
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&this_opaque)
|
||||
.is_some();
|
||||
if had_running_animations {
|
||||
let mut all_running_animations = layout_context.running_animations.write().unwrap();
|
||||
for running_animation in all_running_animations.get(&this_opaque).unwrap() {
|
||||
animation::update_style_for_animation(running_animation, style, None);
|
||||
}
|
||||
all_running_animations.remove(&this_opaque);
|
||||
}
|
||||
|
||||
had_animations_to_expire || had_running_animations
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ln> PrivateElementMatchMethods for ServoLayoutElement<'ln> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue