mirror of
https://github.com/servo/servo.git
synced 2025-07-03 05:23:38 +01:00
Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`. `malloc_size_of` is better -- it handles various cases that `heapsize` does not -- so this patch changes Servo to use `malloc_size_of`. This patch makes the following changes to the `malloc_size_of` crate. - Adds `MallocSizeOf` trait implementations for numerous types, some built-in (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`). - Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't support that operation. - For `HashSet`/`HashMap`, falls back to a computed estimate when `enclosing_size_of_op` isn't available. - Adds an extern "C" `malloc_size_of` function that does the actual heap measurement; this is based on the same functions from the `heapsize` crate. This patch makes the following changes elsewhere. - Converts all the uses of `heapsize` to instead use `malloc_size_of`. - Disables the "heapsize"/"heap_size" feature for the external crates that provide it. - Removes the `HeapSizeOf` implementation from `hashglobe`. - Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of` doesn't derive those types, unlike `heapsize`.
188 lines
6.1 KiB
Rust
188 lines
6.1 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
//! Animated types for CSS values related to effects.
|
|
|
|
use properties::longhands::box_shadow::computed_value::T as ComputedBoxShadowList;
|
|
use properties::longhands::filter::computed_value::T as ComputedFilterList;
|
|
use properties::longhands::text_shadow::computed_value::T as ComputedTextShadowList;
|
|
use std::cmp;
|
|
#[cfg(not(feature = "gecko"))]
|
|
use values::Impossible;
|
|
use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
|
use values::animated::color::RGBA;
|
|
use values::computed::{Angle, NonNegativeNumber};
|
|
use values::computed::length::{Length, NonNegativeLength};
|
|
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
|
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
|
use values::generics::effects::Filter as GenericFilter;
|
|
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
|
|
|
/// An animated value for the `box-shadow` property.
|
|
pub type BoxShadowList = ShadowList<BoxShadow>;
|
|
|
|
/// An animated value for the `text-shadow` property.
|
|
pub type TextShadowList = ShadowList<SimpleShadow>;
|
|
|
|
/// An animated value for shadow lists.
|
|
///
|
|
/// <https://drafts.csswg.org/css-transitions/#animtype-shadow-list>
|
|
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ShadowList<Shadow>(Vec<Shadow>);
|
|
|
|
/// An animated value for a single `box-shadow`.
|
|
pub type BoxShadow = GenericBoxShadow<Option<RGBA>, Length, NonNegativeLength, Length>;
|
|
|
|
/// An animated value for the `filter` property.
|
|
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct FilterList(pub Vec<Filter>);
|
|
|
|
/// An animated value for a single `filter`.
|
|
#[cfg(feature = "gecko")]
|
|
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow>;
|
|
|
|
/// An animated value for a single `filter`.
|
|
#[cfg(not(feature = "gecko"))]
|
|
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible>;
|
|
|
|
/// An animated value for the `drop-shadow()` filter.
|
|
pub type SimpleShadow = GenericSimpleShadow<Option<RGBA>, Length, NonNegativeLength>;
|
|
|
|
impl ToAnimatedValue for ComputedBoxShadowList {
|
|
type AnimatedValue = BoxShadowList;
|
|
|
|
#[inline]
|
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
|
ShadowList(self.0.to_animated_value())
|
|
}
|
|
|
|
#[inline]
|
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
ComputedBoxShadowList(ToAnimatedValue::from_animated_value(animated.0))
|
|
}
|
|
}
|
|
|
|
impl<S> Animate for ShadowList<S>
|
|
where
|
|
S: Animate + Clone + ToAnimatedZero,
|
|
{
|
|
#[inline]
|
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
|
if procedure == Procedure::Add {
|
|
return Ok(ShadowList(
|
|
self.0.iter().chain(&other.0).cloned().collect(),
|
|
));
|
|
}
|
|
// FIXME(nox): Use itertools here, to avoid the need for `unreachable!`.
|
|
let max_len = cmp::max(self.0.len(), other.0.len());
|
|
let mut shadows = Vec::with_capacity(max_len);
|
|
for i in 0..max_len {
|
|
shadows.push(match (self.0.get(i), other.0.get(i)) {
|
|
(Some(shadow), Some(other)) => {
|
|
shadow.animate(other, procedure)?
|
|
},
|
|
(Some(shadow), None) => {
|
|
shadow.animate(&shadow.to_animated_zero()?, procedure)?
|
|
},
|
|
(None, Some(shadow)) => {
|
|
shadow.to_animated_zero()?.animate(shadow, procedure)?
|
|
},
|
|
(None, None) => unreachable!(),
|
|
});
|
|
}
|
|
Ok(ShadowList(shadows))
|
|
}
|
|
}
|
|
|
|
impl<S> ComputeSquaredDistance for ShadowList<S>
|
|
where
|
|
S: ComputeSquaredDistance + ToAnimatedZero,
|
|
{
|
|
#[inline]
|
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
|
use itertools::{EitherOrBoth, Itertools};
|
|
|
|
self.0.iter().zip_longest(other.0.iter()).map(|it| {
|
|
match it {
|
|
EitherOrBoth::Both(from, to) => {
|
|
from.compute_squared_distance(to)
|
|
},
|
|
EitherOrBoth::Left(list) | EitherOrBoth::Right(list) => {
|
|
list.compute_squared_distance(&list.to_animated_zero()?)
|
|
},
|
|
}
|
|
}).sum()
|
|
}
|
|
}
|
|
|
|
impl<S> ToAnimatedZero for ShadowList<S> {
|
|
#[inline]
|
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
|
Ok(ShadowList(vec![]))
|
|
}
|
|
}
|
|
|
|
impl ToAnimatedValue for ComputedTextShadowList {
|
|
type AnimatedValue = TextShadowList;
|
|
|
|
#[inline]
|
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
|
ShadowList(self.0.to_animated_value())
|
|
}
|
|
|
|
#[inline]
|
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
ComputedTextShadowList(ToAnimatedValue::from_animated_value(animated.0))
|
|
}
|
|
}
|
|
|
|
impl ComputeSquaredDistance for BoxShadow {
|
|
#[inline]
|
|
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
|
|
if self.inset != other.inset {
|
|
return Err(());
|
|
}
|
|
Ok(
|
|
self.base.compute_squared_distance(&other.base)? +
|
|
self.spread.compute_squared_distance(&other.spread)?,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl ToAnimatedValue for ComputedFilterList {
|
|
type AnimatedValue = FilterList;
|
|
|
|
#[cfg(not(feature = "gecko"))]
|
|
#[inline]
|
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
|
FilterList(self.0)
|
|
}
|
|
|
|
#[cfg(feature = "gecko")]
|
|
#[inline]
|
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
|
FilterList(self.0.to_animated_value())
|
|
}
|
|
|
|
#[cfg(not(feature = "gecko"))]
|
|
#[inline]
|
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
ComputedFilterList(animated.0)
|
|
}
|
|
|
|
#[cfg(feature = "gecko")]
|
|
#[inline]
|
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
ComputedFilterList(ToAnimatedValue::from_animated_value(animated.0))
|
|
}
|
|
}
|
|
|
|
impl ToAnimatedZero for FilterList {
|
|
#[inline]
|
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
|
Ok(FilterList(vec![]))
|
|
}
|
|
}
|