aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/css/matching.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2015-11-25 08:00:14 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2015-11-25 08:00:14 +0530
commit4f625d3ab67bc14b1563f90c48cf97ca59dc1a28 (patch)
treec21358898bfb9ed2746c9bc29f1e073ffae2e26b /components/layout/css/matching.rs
parent13a96fcaf78c299beb2021d3ae9dae8d9e916762 (diff)
parente881f0feebeec31582b3fbb848aeeb8b7ed70a32 (diff)
downloadservo-4f625d3ab67bc14b1563f90c48cf97ca59dc1a28.tar.gz
servo-4f625d3ab67bc14b1563f90c48cf97ca59dc1a28.zip
Auto merge of #8670 - pcwalton:animation-expiration, r=glennw
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. cc @paulrouget r? @glennw <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8670) <!-- Reviewable:end -->
Diffstat (limited to 'components/layout/css/matching.rs')
-rw-r--r--components/layout/css/matching.rs74
1 files changed, 58 insertions, 16 deletions
diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs
index fc5e7aadb14..4d969e00fd8 100644
--- a/components/layout/css/matching.rs
+++ b/components/layout/css/matching.rs
@@ -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> {