mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 20:49:27 +00:00
servo: Merge #20017 - Optimise more AnimationValue methods 🐉🐲 (from servo:derive-all-the-things); r=emilio
Optimise more AnimationValue methods 🐉🐲 ``` __TEXT __DATA __OBJC others dec hex 87101440 5226496 0 64122880 156450816 9534000 XUL.old 87072768 5226496 0 64122880 156422144 952d000 XUL.new ``` Source-Repo: https://github.com/servo/servo Source-Revision: 9c94fe427942fd73cc641e28c13ec9fa9305a01d --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 392398e22c97bfe97e5fbace1c77d5cdd9f4d2b0
This commit is contained in:
parent
e878eeef74
commit
7af0ffd626
@ -24,11 +24,11 @@ use properties::longhands::visibility::computed_value::T as Visibility;
|
||||
#[cfg(feature = "gecko")]
|
||||
use properties::PropertyId;
|
||||
use properties::{LonghandId, ShorthandId};
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
use servo_arc::Arc;
|
||||
use smallvec::SmallVec;
|
||||
use std::{cmp, mem, ptr};
|
||||
use std::{cmp, ptr};
|
||||
use std::fmt::{self, Write};
|
||||
use std::mem::{self, ManuallyDrop};
|
||||
#[cfg(feature = "gecko")] use hash::FnvHashMap;
|
||||
use style_traits::{CssWriter, ParseError, ToCss};
|
||||
use super::ComputedValues;
|
||||
@ -141,21 +141,42 @@ impl TransitionProperty {
|
||||
|
||||
/// Parse a transition-property value.
|
||||
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this
|
||||
// enum and use PropertyId when stable Rust allows destructors in
|
||||
// statics.
|
||||
//
|
||||
// FIXME: This should handle aliases too.
|
||||
pub enum StaticId {
|
||||
All,
|
||||
Longhand(LonghandId),
|
||||
Shorthand(ShorthandId),
|
||||
}
|
||||
ascii_case_insensitive_phf_map! {
|
||||
static_id -> StaticId = {
|
||||
"all" => StaticId::All,
|
||||
% for prop in data.shorthands_except_all():
|
||||
"${prop.name}" => StaticId::Shorthand(ShorthandId::${prop.camel_case}),
|
||||
% endfor
|
||||
% for prop in data.longhands:
|
||||
"${prop.name}" => StaticId::Longhand(LonghandId::${prop.camel_case}),
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
let location = input.current_source_location();
|
||||
let ident = input.expect_ident()?;
|
||||
match_ignore_ascii_case! { &ident,
|
||||
"all" => Ok(TransitionProperty::All),
|
||||
% for prop in data.shorthands_except_all():
|
||||
"${prop.name}" => Ok(TransitionProperty::Shorthand(ShorthandId::${prop.camel_case})),
|
||||
% endfor
|
||||
% for prop in data.longhands:
|
||||
"${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})),
|
||||
% endfor
|
||||
"none" => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||
_ => CustomIdent::from_ident(location, ident, &[]).map(TransitionProperty::Unsupported),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(match static_id(&ident) {
|
||||
Some(&StaticId::All) => TransitionProperty::All,
|
||||
Some(&StaticId::Longhand(id)) => TransitionProperty::Longhand(id),
|
||||
Some(&StaticId::Shorthand(id)) => TransitionProperty::Shorthand(id),
|
||||
None => {
|
||||
TransitionProperty::Unsupported(
|
||||
CustomIdent::from_ident(location, ident, &["none"])?,
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert TransitionProperty to nsCSSPropertyID.
|
||||
#[cfg(feature = "gecko")]
|
||||
@ -345,8 +366,8 @@ unsafe impl HasSimpleFFI for AnimationValueMap {}
|
||||
///
|
||||
/// FIXME: We need to add a path for custom properties, but that's trivial after
|
||||
/// this (is a similar path to that of PropertyDeclaration).
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||
#[derive(Debug)]
|
||||
#[repr(u16)]
|
||||
pub enum AnimationValue {
|
||||
% for prop in data.longhands:
|
||||
@ -370,6 +391,95 @@ pub enum AnimationValue {
|
||||
unanimated.append(prop)
|
||||
%>
|
||||
|
||||
#[repr(C)]
|
||||
struct AnimationValueVariantRepr<T> {
|
||||
tag: u16,
|
||||
value: T
|
||||
}
|
||||
|
||||
impl Clone for AnimationValue {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
use self::AnimationValue::*;
|
||||
|
||||
<%
|
||||
[copy, others] = [list(g) for _, g in groupby(animated, key=lambda x: not x.specified_is_copy())]
|
||||
%>
|
||||
|
||||
let self_tag = unsafe { *(self as *const _ as *const u16) };
|
||||
if self_tag <= LonghandId::${copy[-1].camel_case} as u16 {
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(u16)]
|
||||
enum CopyVariants {
|
||||
% for prop in copy:
|
||||
_${prop.camel_case}(${prop.animated_type()}),
|
||||
% endfor
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut out = mem::uninitialized();
|
||||
ptr::write(
|
||||
&mut out as *mut _ as *mut CopyVariants,
|
||||
*(self as *const _ as *const CopyVariants),
|
||||
);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
match *self {
|
||||
% for ty, props in groupby(others, key=lambda x: x.animated_type()):
|
||||
<% props = list(props) %>
|
||||
${" |\n".join("{}(ref value)".format(prop.camel_case) for prop in props)} => {
|
||||
% if len(props) == 1:
|
||||
${props[0].camel_case}(value.clone())
|
||||
% else:
|
||||
unsafe {
|
||||
let mut out = ManuallyDrop::new(mem::uninitialized());
|
||||
ptr::write(
|
||||
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
|
||||
AnimationValueVariantRepr {
|
||||
tag: *(self as *const _ as *const u16),
|
||||
value: value.clone(),
|
||||
},
|
||||
);
|
||||
ManuallyDrop::into_inner(out)
|
||||
}
|
||||
% endif
|
||||
}
|
||||
% endfor
|
||||
_ => unsafe { debug_unreachable!() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for AnimationValue {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
use self::AnimationValue::*;
|
||||
|
||||
unsafe {
|
||||
let this_tag = *(self as *const _ as *const u16);
|
||||
let other_tag = *(other as *const _ as *const u16);
|
||||
if this_tag != other_tag {
|
||||
return false;
|
||||
}
|
||||
|
||||
match *self {
|
||||
% for ty, props in groupby(animated, key=lambda x: x.animated_type()):
|
||||
${" |\n".join("{}(ref this)".format(prop.camel_case) for prop in props)} => {
|
||||
let other_repr =
|
||||
&*(other as *const _ as *const AnimationValueVariantRepr<${ty}>);
|
||||
*this == other_repr.value
|
||||
}
|
||||
% endfor
|
||||
${" |\n".join("{}(void)".format(prop.camel_case) for prop in unanimated)} => {
|
||||
void::unreachable(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AnimationValue {
|
||||
/// Returns the longhand id this animated value corresponds to.
|
||||
#[inline]
|
||||
@ -564,12 +674,6 @@ fn animate_discrete<T: Clone>(this: &T, other: &T, procedure: Procedure) -> Resu
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct AnimationValueVariantRepr<T> {
|
||||
tag: u16,
|
||||
value: T
|
||||
}
|
||||
|
||||
impl Animate for AnimationValue {
|
||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||
Ok(unsafe {
|
||||
|
@ -88,7 +88,7 @@ impl ToAnimatedZero for BorderCornerRadius {
|
||||
/// The computed value of the `border-image-repeat` property:
|
||||
///
|
||||
/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
|
||||
pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub BorderImageRepeatKeyword);
|
||||
|
||||
impl BorderImageRepeat {
|
||||
|
Loading…
x
Reference in New Issue
Block a user