Auto merge of #15175 - BorisChiou:animation/interpolate_and_cascade, r=heycam

Interpolate servo animation values and add them to the cascade

These are the servo-side changes for [bug 1317209](https://bugzilla.mozilla.org/show_bug.cgi?id=1317209). @Manishearth, @emilio, and @heycam have already reviewed them there. Please merge these patches until the gecko-side changes for [bug 1317209](https://bugzilla.mozilla.org/show_bug.cgi?id=1317209) is landed.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix [bug 1317209](https://bugzilla.mozilla.org/show_bug.cgi?id=1317209).
- [X] These changes do not require tests because there are existing tests for this in mozilla-central

<!-- 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/15175)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-01-25 23:36:33 -08:00 committed by GitHub
commit e4a1cb6f87
9 changed files with 133 additions and 7 deletions

View file

@ -491,6 +491,7 @@ mod bindings {
"RawGeckoNode", "RawGeckoNode",
"RawGeckoAnimationValueList", "RawGeckoAnimationValueList",
"RawServoAnimationValue", "RawServoAnimationValue",
"RawServoAnimationValueList",
"RawGeckoPresContext", "RawGeckoPresContext",
"RawGeckoPresContextOwned", "RawGeckoPresContextOwned",
"ThreadSafeURIHolder", "ThreadSafeURIHolder",
@ -593,6 +594,7 @@ mod bindings {
let servo_borrow_types = [ let servo_borrow_types = [
"nsCSSValue", "nsCSSValue",
"RawGeckoAnimationValueList", "RawGeckoAnimationValueList",
"RawServoAnimationValueList",
]; ];
for &ty in structs_types.iter() { for &ty in structs_types.iter() {
builder = builder.hide_type(ty) builder = builder.hide_type(ty)

View file

@ -227,6 +227,11 @@ pub trait PresentationalHintsSynthetizer {
where V: Push<ApplicableDeclarationBlock>; where V: Push<ApplicableDeclarationBlock>;
} }
/// The animation rules. The first one is for Animation cascade level, and the second one is for
/// Transition cascade level.
pub struct AnimationRules(pub Option<Arc<RwLock<PropertyDeclarationBlock>>>,
pub Option<Arc<RwLock<PropertyDeclarationBlock>>>);
/// The element trait, the main abstraction the style crate acts over. /// The element trait, the main abstraction the style crate acts over.
pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer { pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer {
/// The concrete node type. /// The concrete node type.
@ -248,6 +253,11 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
/// Get this element's style attribute. /// Get this element's style attribute.
fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>>; fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>>;
/// Get this element's animation rules.
fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules {
AnimationRules(None, None)
}
/// Get this element's state, for non-tree-structural pseudos. /// Get this element's state, for non-tree-structural pseudos.
fn get_state(&self) -> ElementState; fn get_state(&self) -> ElementState;

View file

@ -16,7 +16,7 @@
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use data::ElementData; use data::ElementData;
use dom::{LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode}; use dom::{AnimationRules, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
use dom::{OpaqueNode, PresentationalHintsSynthetizer}; use dom::{OpaqueNode, PresentationalHintsSynthetizer};
use element_state::ElementState; use element_state::ElementState;
use error_reporting::StdoutErrorReporter; use error_reporting::StdoutErrorReporter;
@ -30,10 +30,12 @@ use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_MatchesE
use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink, Gecko_Namespace}; use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink, Gecko_Namespace};
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
use gecko_bindings::bindings::Gecko_ClassOrClassList; use gecko_bindings::bindings::Gecko_ClassOrClassList;
use gecko_bindings::bindings::Gecko_GetAnimationRule;
use gecko_bindings::bindings::Gecko_GetStyleContext; use gecko_bindings::bindings::Gecko_GetStyleContext;
use gecko_bindings::structs; use gecko_bindings::structs;
use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode};
use gecko_bindings::structs::{nsIAtom, nsIContent, nsStyleContext}; use gecko_bindings::structs::{nsIAtom, nsIContent, nsStyleContext};
use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
use gecko_bindings::structs::NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO; use gecko_bindings::structs::NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use parking_lot::RwLock; use parking_lot::RwLock;
@ -335,6 +337,15 @@ impl<'le> TElement for GeckoElement<'le> {
declarations.map(|s| s.as_arc_opt()).unwrap_or(None) declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
} }
fn get_animation_rules(&self, pseudo: Option<&PseudoElement>) -> AnimationRules {
let atom_ptr = pseudo.map(|p| p.as_atom().as_ptr()).unwrap_or(ptr::null_mut());
unsafe {
AnimationRules(
Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Animations).into_arc_opt(),
Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Transitions).into_arc_opt())
}
}
fn get_state(&self) -> ElementState { fn get_state(&self) -> ElementState {
unsafe { unsafe {
ElementState::from_bits_truncate(Gecko_ElementState(self.0)) ElementState::from_bits_truncate(Gecko_ElementState(self.0))

View file

@ -3,11 +3,13 @@
pub use nsstring::{nsACString, nsAString}; pub use nsstring::{nsACString, nsAString};
type nsACString_internal = nsACString; type nsACString_internal = nsACString;
type nsAString_internal = nsAString; type nsAString_internal = nsAString;
use gecko_bindings::structs::EffectCompositor_CascadeLevel;
use gecko_bindings::structs::RawGeckoDocument; use gecko_bindings::structs::RawGeckoDocument;
use gecko_bindings::structs::RawGeckoElement; use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoNode; use gecko_bindings::structs::RawGeckoNode;
use gecko_bindings::structs::RawGeckoAnimationValueList; use gecko_bindings::structs::RawGeckoAnimationValueList;
use gecko_bindings::structs::RawServoAnimationValue; use gecko_bindings::structs::RawServoAnimationValue;
use gecko_bindings::structs::RawServoAnimationValueBorrowedList;
use gecko_bindings::structs::RawGeckoPresContext; use gecko_bindings::structs::RawGeckoPresContext;
use gecko_bindings::structs::RawGeckoPresContextOwned; use gecko_bindings::structs::RawGeckoPresContextOwned;
use gecko_bindings::structs::ThreadSafeURIHolder; use gecko_bindings::structs::ThreadSafeURIHolder;
@ -224,6 +226,8 @@ pub type RawGeckoAnimationValueListBorrowed<'a> = &'a RawGeckoAnimationValueList
pub type RawGeckoAnimationValueListBorrowedOrNull<'a> = Option<&'a RawGeckoAnimationValueList>; pub type RawGeckoAnimationValueListBorrowedOrNull<'a> = Option<&'a RawGeckoAnimationValueList>;
pub type RawGeckoAnimationValueListBorrowedMut<'a> = &'a mut RawGeckoAnimationValueList; pub type RawGeckoAnimationValueListBorrowedMut<'a> = &'a mut RawGeckoAnimationValueList;
pub type RawGeckoAnimationValueListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoAnimationValueList>; pub type RawGeckoAnimationValueListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoAnimationValueList>;
pub type RawServoAnimationValueBorrowedListBorrowed<'a> = &'a RawServoAnimationValueBorrowedList;
pub type RawServoAnimationValueBorrowedListBorrowedOrNull<'a> = Option<&'a RawServoAnimationValueBorrowedList>;
extern "C" { extern "C" {
pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void, pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void,
@ -498,6 +502,12 @@ extern "C" {
pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed) pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed)
-> RawServoDeclarationBlockStrongBorrowedOrNull; -> RawServoDeclarationBlockStrongBorrowedOrNull;
} }
extern "C" {
pub fn Gecko_GetAnimationRule(element: RawGeckoElementBorrowed,
aAtom: *mut nsIAtom,
aCascadeLevel: EffectCompositor_CascadeLevel)
-> RawServoDeclarationBlockStrong;
}
extern "C" { extern "C" {
pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32) pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32)
-> *mut nsIAtom; -> *mut nsIAtom;
@ -1217,6 +1227,16 @@ extern "C" {
ServoComputedValuesBorrowed) ServoComputedValuesBorrowed)
-> ServoComputedValuesStrong; -> ServoComputedValuesStrong;
} }
extern "C" {
pub fn Servo_AnimationValues_Interpolate(from: RawServoAnimationValueBorrowed,
to: RawServoAnimationValueBorrowed,
progress: f64)
-> RawServoAnimationValueStrong;
}
extern "C" {
pub fn Servo_AnimationValues_Uncompute(value: RawServoAnimationValueBorrowedListBorrowed)
-> RawServoDeclarationBlockStrong;
}
extern "C" { extern "C" {
pub fn Servo_AnimationValues_Populate(arg1: pub fn Servo_AnimationValues_Populate(arg1:
RawGeckoAnimationValueListBorrowedMut, RawGeckoAnimationValueListBorrowedMut,

View file

@ -5273,6 +5273,12 @@ pub mod root {
impl Clone for StyleComplexColor { impl Clone for StyleComplexColor {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum EffectCompositor_CascadeLevel {
Animations = 0,
Transitions = 1,
}
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct PropertyStyleAnimationValuePair { pub struct PropertyStyleAnimationValuePair {
@ -17953,6 +17959,10 @@ pub mod root {
pub type RawGeckoPresContextBorrowedMut = *mut root::RawGeckoPresContext; pub type RawGeckoPresContextBorrowedMut = *mut root::RawGeckoPresContext;
pub type RawGeckoAnimationValueListBorrowedMut = pub type RawGeckoAnimationValueListBorrowedMut =
*mut root::RawGeckoAnimationValueList; *mut root::RawGeckoAnimationValueList;
pub type RawServoAnimationValueBorrowedList =
root::nsTArray<*const root::RawServoAnimationValue>;
pub type RawServoAnimationValueBorrowedListBorrowed =
*const root::RawServoAnimationValueBorrowedList;
#[repr(u32)] #[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum nsCSSTokenSerializationType { pub enum nsCSSTokenSerializationType {

View file

@ -5191,6 +5191,12 @@ pub mod root {
impl Clone for StyleComplexColor { impl Clone for StyleComplexColor {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum EffectCompositor_CascadeLevel {
Animations = 0,
Transitions = 1,
}
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct PropertyStyleAnimationValuePair { pub struct PropertyStyleAnimationValuePair {
@ -17726,6 +17732,10 @@ pub mod root {
pub type RawGeckoPresContextBorrowedMut = *mut root::RawGeckoPresContext; pub type RawGeckoPresContextBorrowedMut = *mut root::RawGeckoPresContext;
pub type RawGeckoAnimationValueListBorrowedMut = pub type RawGeckoAnimationValueListBorrowedMut =
*mut root::RawGeckoAnimationValueList; *mut root::RawGeckoAnimationValueList;
pub type RawServoAnimationValueBorrowedList =
root::nsTArray<*const root::RawServoAnimationValue>;
pub type RawServoAnimationValueBorrowedListBorrowed =
*const root::RawServoAnimationValueBorrowedList;
#[repr(u32)] #[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum nsCSSTokenSerializationType { pub enum nsCSSTokenSerializationType {

View file

@ -589,12 +589,14 @@ pub trait MatchMethods : TElement {
let mut applicable_declarations: Vec<ApplicableDeclarationBlock> = Vec::with_capacity(16); let mut applicable_declarations: Vec<ApplicableDeclarationBlock> = Vec::with_capacity(16);
let stylist = &context.shared.stylist; let stylist = &context.shared.stylist;
let style_attribute = self.style_attribute(); let style_attribute = self.style_attribute();
let animation_rules = self.get_animation_rules(None);
// Compute the primary rule node. // Compute the primary rule node.
let mut primary_relations = let mut primary_relations =
stylist.push_applicable_declarations(self, stylist.push_applicable_declarations(self,
parent_bf, parent_bf,
style_attribute, style_attribute,
animation_rules,
None, None,
&mut applicable_declarations, &mut applicable_declarations,
MatchingReason::ForStyling); MatchingReason::ForStyling);
@ -604,7 +606,9 @@ pub trait MatchMethods : TElement {
let mut per_pseudo: PseudoRuleNodes = HashMap::with_hasher(Default::default()); let mut per_pseudo: PseudoRuleNodes = HashMap::with_hasher(Default::default());
SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| { SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
debug_assert!(applicable_declarations.is_empty()); debug_assert!(applicable_declarations.is_empty());
let pseudo_animation_rules = self.get_animation_rules(Some(&pseudo));
stylist.push_applicable_declarations(self, parent_bf, None, stylist.push_applicable_declarations(self, parent_bf, None,
pseudo_animation_rules,
Some(&pseudo.clone()), Some(&pseudo.clone()),
&mut applicable_declarations, &mut applicable_declarations,
MatchingReason::ForStyling); MatchingReason::ForStyling);

View file

@ -8,7 +8,7 @@
use {Atom, LocalName}; use {Atom, LocalName};
use data::ComputedStyle; use data::ComputedStyle;
use dom::{PresentationalHintsSynthetizer, TElement}; use dom::{AnimationRules, PresentationalHintsSynthetizer, TElement};
use error_reporting::StdoutErrorReporter; use error_reporting::StdoutErrorReporter;
use keyframes::KeyframesAnimation; use keyframes::KeyframesAnimation;
use media_queries::Device; use media_queries::Device;
@ -21,6 +21,7 @@ use rule_tree::{RuleTree, StrongRuleNode, StyleSource};
use selector_parser::{ElementExt, SelectorImpl, PseudoElement, Snapshot}; use selector_parser::{ElementExt, SelectorImpl, PseudoElement, Snapshot};
use selectors::Element; use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use selectors::matching::{AFFECTED_BY_ANIMATIONS, AFFECTED_BY_TRANSITIONS};
use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS}; use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS};
use selectors::matching::{MatchingReason, StyleRelations, matches_complex_selector}; use selectors::matching::{MatchingReason, StyleRelations, matches_complex_selector};
use selectors::parser::{Selector, SimpleSelector, LocalName as LocalNameSelector, ComplexSelector}; use selectors::parser::{Selector, SimpleSelector, LocalName as LocalNameSelector, ComplexSelector};
@ -386,6 +387,7 @@ impl Stylist {
self.push_applicable_declarations(element, self.push_applicable_declarations(element,
None, None,
None, None,
AnimationRules(None, None),
Some(pseudo), Some(pseudo),
&mut declarations, &mut declarations,
MatchingReason::ForStyling); MatchingReason::ForStyling);
@ -490,6 +492,7 @@ impl Stylist {
element: &E, element: &E,
parent_bf: Option<&BloomFilter>, parent_bf: Option<&BloomFilter>,
style_attribute: Option<&Arc<RwLock<PropertyDeclarationBlock>>>, style_attribute: Option<&Arc<RwLock<PropertyDeclarationBlock>>>,
animation_rules: AnimationRules,
pseudo_element: Option<&PseudoElement>, pseudo_element: Option<&PseudoElement>,
applicable_declarations: &mut V, applicable_declarations: &mut V,
reason: MatchingReason) -> StyleRelations reason: MatchingReason) -> StyleRelations
@ -560,7 +563,18 @@ impl Stylist {
debug!("style attr: {:?}", relations); debug!("style attr: {:?}", relations);
// Step 5: Author-supplied `!important` rules. // Step 5: Animations.
// The animations sheet (CSS animations, script-generated animations,
// and CSS transitions that are no longer tied to CSS markup)
if let Some(anim) = animation_rules.0 {
relations |= AFFECTED_BY_ANIMATIONS;
Push::push(
applicable_declarations,
ApplicableDeclarationBlock::from_declarations(anim.clone(), Importance::Normal));
}
debug!("animation: {:?}", relations);
// Step 6: Author-supplied `!important` rules.
map.author.get_all_matching_rules(element, map.author.get_all_matching_rules(element,
parent_bf, parent_bf,
applicable_declarations, applicable_declarations,
@ -570,7 +584,7 @@ impl Stylist {
debug!("author important: {:?}", relations); debug!("author important: {:?}", relations);
// Step 6: `!important` style attributes. // Step 7: `!important` style attributes.
if let Some(sa) = style_attribute { if let Some(sa) = style_attribute {
if sa.read().any_important() { if sa.read().any_important() {
relations |= AFFECTED_BY_STYLE_ATTRIBUTE; relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
@ -582,7 +596,7 @@ impl Stylist {
debug!("style attr important: {:?}", relations); debug!("style attr important: {:?}", relations);
// Step 7: User `!important` rules. // Step 8: User `!important` rules.
map.user.get_all_matching_rules(element, map.user.get_all_matching_rules(element,
parent_bf, parent_bf,
applicable_declarations, applicable_declarations,
@ -595,7 +609,7 @@ impl Stylist {
debug!("skipping non-agent rules"); debug!("skipping non-agent rules");
} }
// Step 8: UA `!important` rules. // Step 9: UA `!important` rules.
map.user_agent.get_all_matching_rules(element, map.user_agent.get_all_matching_rules(element,
parent_bf, parent_bf,
applicable_declarations, applicable_declarations,
@ -605,6 +619,16 @@ impl Stylist {
debug!("UA important: {:?}", relations); debug!("UA important: {:?}", relations);
// Step 10: Transitions.
// The transitions sheet (CSS transitions that are tied to CSS markup)
if let Some(anim) = animation_rules.1 {
relations |= AFFECTED_BY_TRANSITIONS;
Push::push(
applicable_declarations,
ApplicableDeclarationBlock::from_declarations(anim.clone(), Importance::Normal));
}
debug!("transition: {:?}", relations);
debug!("push_applicable_declarations: shareable: {:?}", relations); debug!("push_applicable_declarations: shareable: {:?}", relations);
relations relations

View file

@ -39,6 +39,8 @@ use style::gecko_bindings::bindings::RawGeckoAnimationValueListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoElementBorrowed; use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
use style::gecko_bindings::bindings::RawGeckoPresContextBorrowed; use style::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowedListBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
use style::gecko_bindings::bindings::RawServoImportRuleBorrowed; use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t; use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
@ -58,7 +60,7 @@ use style::parser::{ParserContext, ParserContextExtraData};
use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration}; use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration};
use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock, PropertyId}; use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock, PropertyId};
use style::properties::{apply_declarations, parse_one_declaration}; use style::properties::{apply_declarations, parse_one_declaration};
use style::properties::animated_properties::AnimationValue; use style::properties::animated_properties::{AnimationValue, Interpolate};
use style::restyle_hints::RestyleHint; use style::restyle_hints::RestyleHint;
use style::selector_parser::PseudoElementCascadeType; use style::selector_parser::PseudoElementCascadeType;
use style::sequential; use style::sequential;
@ -165,6 +167,39 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed,
behavior == structs::TraversalRootBehavior::UnstyledChildrenOnly); behavior == structs::TraversalRootBehavior::UnstyledChildrenOnly);
} }
#[no_mangle]
pub extern "C" fn Servo_AnimationValues_Interpolate(from: RawServoAnimationValueBorrowed,
to: RawServoAnimationValueBorrowed,
progress: f64)
-> RawServoAnimationValueStrong
{
let from_value = AnimationValue::as_arc(&from);
let to_value = AnimationValue::as_arc(&to);
if let Ok(value) = from_value.interpolate(to_value, progress) {
Arc::new(value).into_strong()
} else {
RawServoAnimationValueStrong::null()
}
}
#[no_mangle]
pub extern "C" fn Servo_AnimationValues_Uncompute(value: RawServoAnimationValueBorrowedListBorrowed)
-> RawServoDeclarationBlockStrong
{
let uncomputed_values = value.into_iter()
.map(|v| {
let raw_anim = unsafe { v.as_ref().unwrap() };
let anim = AnimationValue::as_arc(&raw_anim);
(anim.uncompute(), Importance::Normal)
})
.collect();
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: uncomputed_values,
important_count: 0,
})).into_strong()
}
/// Takes a ServoAnimationValues and populates it with the animation values corresponding /// Takes a ServoAnimationValues and populates it with the animation values corresponding
/// to a given property declaration block /// to a given property declaration block
#[no_mangle] #[no_mangle]