зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #6894 - style: Switch animation timestamps to be doubles instead of floats (from pcwalton:double-precision-timestamps); r=metajack
32-bit floats are not enough to hold timestamps since the epoch and result in jank. r? @metajack Source-Repo: https://github.com/servo/servo Source-Revision: 92cbb9368471d12f0d5492abd7e04b16df549366
This commit is contained in:
Родитель
fa993d4367
Коммит
9fc5bcecfb
|
@ -33,15 +33,16 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>
|
|||
property_animation.update(new_style, 0.0);
|
||||
|
||||
// Kick off the animation.
|
||||
let now = clock_ticks::precise_time_s() as f32;
|
||||
let now = clock_ticks::precise_time_s();
|
||||
let animation_style = new_style.get_animation();
|
||||
let start_time = now + animation_style.transition_delay.0.get_mod(i).seconds();
|
||||
let start_time =
|
||||
now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
|
||||
new_animations_sender.send(Animation {
|
||||
node: node.id(),
|
||||
property_animation: property_animation,
|
||||
start_time: start_time,
|
||||
end_time: start_time +
|
||||
animation_style.transition_duration.0.get_mod(i).seconds(),
|
||||
(animation_style.transition_duration.0.get_mod(i).seconds() as f64),
|
||||
}).unwrap()
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ pub fn recalc_style_for_animation(flow: &mut Flow, animation: &Animation) {
|
|||
return
|
||||
}
|
||||
|
||||
let now = clock_ticks::precise_time_s() as f32;
|
||||
let now = clock_ticks::precise_time_s() as f64;
|
||||
let mut progress = (now - animation.start_time) / animation.duration();
|
||||
if progress > 1.0 {
|
||||
progress = 1.0
|
||||
|
@ -100,7 +101,7 @@ pub fn recalc_style_for_animation(flow: &mut Flow, animation: &Animation) {
|
|||
/// Handles animation updates.
|
||||
pub fn tick_all_animations(layout_task: &LayoutTask, rw_data: &mut LayoutTaskData) {
|
||||
let running_animations = mem::replace(&mut rw_data.running_animations, Vec::new());
|
||||
let now = clock_ticks::precise_time_s() as f32;
|
||||
let now = clock_ticks::precise_time_s() as f64;
|
||||
for running_animation in running_animations.into_iter() {
|
||||
layout_task.tick_animation(&running_animation, rw_data);
|
||||
|
||||
|
|
|
@ -208,15 +208,15 @@ pub struct Animation {
|
|||
/// A description of the property animation that is occurring.
|
||||
pub property_animation: PropertyAnimation,
|
||||
/// The start time of the animation, as returned by `time::precise_time_s()`.
|
||||
pub start_time: f32,
|
||||
pub start_time: f64,
|
||||
/// The end time of the animation, as returned by `time::precise_time_s()`.
|
||||
pub end_time: f32,
|
||||
pub end_time: f64,
|
||||
}
|
||||
|
||||
impl Animation {
|
||||
/// Returns the duration of this animation in seconds.
|
||||
#[inline]
|
||||
pub fn duration(&self) -> f32 {
|
||||
pub fn duration(&self) -> f64 {
|
||||
self.end_time - self.start_time
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ use values::computed::{LengthOrPercentage, Length, Time};
|
|||
use values::CSSFloat;
|
||||
use cssparser::{RGBA, Color};
|
||||
|
||||
use euclid::point::Point2D;
|
||||
use std::cmp::Ordering;
|
||||
use std::iter::repeat;
|
||||
use util::bezier::Bezier;
|
||||
|
@ -170,18 +171,19 @@ impl PropertyAnimation {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&self, style: &mut ComputedValues, time: f32) {
|
||||
pub fn update(&self, style: &mut ComputedValues, time: f64) {
|
||||
let progress = match self.timing_function {
|
||||
TransitionTimingFunction::CubicBezier(p1, p2) => {
|
||||
// See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit.
|
||||
let epsilon = 1.0 / (200.0 * self.duration.seconds());
|
||||
Bezier::new(p1, p2).solve(time, epsilon)
|
||||
let epsilon = 1.0 / (200.0 * (self.duration.seconds() as f64));
|
||||
Bezier::new(Point2D::new(p1.x as f64, p1.y as f64),
|
||||
Point2D::new(p2.x as f64, p2.y as f64)).solve(time, epsilon)
|
||||
}
|
||||
TransitionTimingFunction::Steps(steps, StartEnd::Start) => {
|
||||
(time * (steps as f32)).ceil() / (steps as f32)
|
||||
(time * (steps as f64)).ceil() / (steps as f64)
|
||||
}
|
||||
TransitionTimingFunction::Steps(steps, StartEnd::End) => {
|
||||
(time * (steps as f32)).floor() / (steps as f32)
|
||||
(time * (steps as f64)).floor() / (steps as f64)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -366,19 +368,19 @@ impl AnimatedProperty {
|
|||
}
|
||||
|
||||
trait Interpolate {
|
||||
fn interpolate(&self, other: &Self, time: f32) -> Option<Self>;
|
||||
fn interpolate(&self, other: &Self, time: f64) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl Interpolate for Au {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Au, time: f32) -> Option<Au> {
|
||||
Some(Au((self.0 as f32 + (other.0 as f32 - self.0 as f32) * time).round() as i32))
|
||||
fn interpolate(&self, other: &Au, time: f64) -> Option<Au> {
|
||||
Some(Au((self.0 as f64 + (other.0 as f64 - self.0 as f64) * time).round() as i32))
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> Interpolate for Option<T> where T:Interpolate {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Option<T>, time: f32) -> Option<Option<T>> {
|
||||
fn interpolate(&self, other: &Option<T>, time: f64) -> Option<Option<T>> {
|
||||
match (self, other) {
|
||||
(&Some(ref this), &Some(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
|
@ -392,30 +394,30 @@ impl <T> Interpolate for Option<T> where T:Interpolate {
|
|||
|
||||
impl Interpolate for f32 {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &f32, time: f32) -> Option<f32> {
|
||||
Some(*self + (*other - *self) * time)
|
||||
fn interpolate(&self, other: &f32, time: f64) -> Option<f32> {
|
||||
Some(((*self as f64) + ((*other as f64) - (*self as f64)) * time) as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpolate for f64 {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &f64, time: f32) -> Option<f64> {
|
||||
Some(*self + (*other - *self) * (time as f64))
|
||||
fn interpolate(&self, other: &f64, time: f64) -> Option<f64> {
|
||||
Some(*self + (*other - *self) * time)
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpolate for i32 {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &i32, time: f32) -> Option<i32> {
|
||||
let a = *self as f32;
|
||||
let b = *other as f32;
|
||||
fn interpolate(&self, other: &i32, time: f64) -> Option<i32> {
|
||||
let a = *self as f64;
|
||||
let b = *other as f64;
|
||||
Some((a + (b - a) * time).round() as i32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpolate for Visibility {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Visibility, time: f32)
|
||||
fn interpolate(&self, other: &Visibility, time: f64)
|
||||
-> Option<Visibility> {
|
||||
match (*self, *other) {
|
||||
(Visibility::visible, _) | (_, Visibility::visible) => {
|
||||
|
@ -434,7 +436,7 @@ impl Interpolate for Visibility {
|
|||
|
||||
impl Interpolate for ZIndex {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &ZIndex, time: f32)
|
||||
fn interpolate(&self, other: &ZIndex, time: f64)
|
||||
-> Option<ZIndex> {
|
||||
match (*self, *other) {
|
||||
(ZIndex::Number(ref this),
|
||||
|
@ -450,7 +452,7 @@ impl Interpolate for ZIndex {
|
|||
|
||||
impl Interpolate for VerticalAlign {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &VerticalAlign, time: f32)
|
||||
fn interpolate(&self, other: &VerticalAlign, time: f64)
|
||||
-> Option<VerticalAlign> {
|
||||
match (*self, *other) {
|
||||
(VerticalAlign::Length(ref this),
|
||||
|
@ -466,7 +468,7 @@ impl Interpolate for VerticalAlign {
|
|||
|
||||
impl Interpolate for BorderSpacing {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &BorderSpacing, time: f32)
|
||||
fn interpolate(&self, other: &BorderSpacing, time: f64)
|
||||
-> Option<BorderSpacing> {
|
||||
self.horizontal.interpolate(&other.horizontal, time).and_then(|horizontal| {
|
||||
self.vertical.interpolate(&other.vertical, time).and_then(|vertical| {
|
||||
|
@ -478,7 +480,7 @@ impl Interpolate for BorderSpacing {
|
|||
|
||||
impl Interpolate for RGBA {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &RGBA, time: f32) -> Option<RGBA> {
|
||||
fn interpolate(&self, other: &RGBA, time: f64) -> Option<RGBA> {
|
||||
match (self.red.interpolate(&other.red, time),
|
||||
self.green.interpolate(&other.green, time),
|
||||
self.blue.interpolate(&other.blue, time),
|
||||
|
@ -493,7 +495,7 @@ impl Interpolate for RGBA {
|
|||
|
||||
impl Interpolate for Color {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &Color, time: f32) -> Option<Color> {
|
||||
fn interpolate(&self, other: &Color, time: f64) -> Option<Color> {
|
||||
match (*self, *other) {
|
||||
(Color::RGBA(ref this), Color::RGBA(ref other)) => {
|
||||
this.interpolate(other, time).and_then(|value| {
|
||||
|
@ -507,7 +509,7 @@ impl Interpolate for Color {
|
|||
|
||||
impl Interpolate for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LengthOrPercentage, time: f32)
|
||||
fn interpolate(&self, other: &LengthOrPercentage, time: f64)
|
||||
-> Option<LengthOrPercentage> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentage::Length(ref this),
|
||||
|
@ -529,7 +531,7 @@ impl Interpolate for LengthOrPercentage {
|
|||
|
||||
impl Interpolate for LengthOrPercentageOrAuto {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LengthOrPercentageOrAuto, time: f32)
|
||||
fn interpolate(&self, other: &LengthOrPercentageOrAuto, time: f64)
|
||||
-> Option<LengthOrPercentageOrAuto> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrAuto::Length(ref this),
|
||||
|
@ -554,7 +556,7 @@ impl Interpolate for LengthOrPercentageOrAuto {
|
|||
|
||||
impl Interpolate for LengthOrPercentageOrNone {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LengthOrPercentageOrNone, time: f32)
|
||||
fn interpolate(&self, other: &LengthOrPercentageOrNone, time: f64)
|
||||
-> Option<LengthOrPercentageOrNone> {
|
||||
match (*self, *other) {
|
||||
(LengthOrPercentageOrNone::Length(ref this),
|
||||
|
@ -579,7 +581,7 @@ impl Interpolate for LengthOrPercentageOrNone {
|
|||
|
||||
impl Interpolate for LineHeight {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &LineHeight, time: f32)
|
||||
fn interpolate(&self, other: &LineHeight, time: f64)
|
||||
-> Option<LineHeight> {
|
||||
match (*self, *other) {
|
||||
(LineHeight::Length(ref this),
|
||||
|
@ -605,10 +607,10 @@ impl Interpolate for LineHeight {
|
|||
/// http://dev.w3.org/csswg/css-transitions/#animtype-font-weight
|
||||
impl Interpolate for FontWeight {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &FontWeight, time: f32)
|
||||
fn interpolate(&self, other: &FontWeight, time: f64)
|
||||
-> Option<FontWeight> {
|
||||
let a = (*self as u32) as f32;
|
||||
let b = (*other as u32) as f32;
|
||||
let a = (*self as u32) as f64;
|
||||
let b = (*other as u32) as f64;
|
||||
let weight = a + (b - a) * time;
|
||||
Some(if weight < 150. {
|
||||
FontWeight::Weight100
|
||||
|
@ -634,7 +636,7 @@ impl Interpolate for FontWeight {
|
|||
|
||||
impl Interpolate for ClipRect {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &ClipRect, time: f32)
|
||||
fn interpolate(&self, other: &ClipRect, time: f64)
|
||||
-> Option<ClipRect> {
|
||||
match (self.top.interpolate(&other.top, time),
|
||||
self.right.interpolate(&other.right, time),
|
||||
|
@ -650,7 +652,7 @@ impl Interpolate for ClipRect {
|
|||
|
||||
impl Interpolate for BackgroundPosition {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &BackgroundPosition, time: f32)
|
||||
fn interpolate(&self, other: &BackgroundPosition, time: f64)
|
||||
-> Option<BackgroundPosition> {
|
||||
match (self.horizontal.interpolate(&other.horizontal, time),
|
||||
self.vertical.interpolate(&other.vertical, time)) {
|
||||
|
@ -664,7 +666,7 @@ impl Interpolate for BackgroundPosition {
|
|||
|
||||
impl Interpolate for TextShadow {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &TextShadow, time: f32)
|
||||
fn interpolate(&self, other: &TextShadow, time: f64)
|
||||
-> Option<TextShadow> {
|
||||
match (self.offset_x.interpolate(&other.offset_x, time),
|
||||
self.offset_y.interpolate(&other.offset_y, time),
|
||||
|
@ -680,7 +682,7 @@ impl Interpolate for TextShadow {
|
|||
|
||||
impl Interpolate for TextShadowList {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &TextShadowList, time: f32)
|
||||
fn interpolate(&self, other: &TextShadowList, time: f64)
|
||||
-> Option<TextShadowList> {
|
||||
let zero = TextShadow {
|
||||
offset_x: Au(0),
|
||||
|
@ -734,7 +736,7 @@ fn can_interpolate_list(from_list: &Vec<TransformOperation>,
|
|||
/// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
||||
fn interpolate_transform_list(from_list: &Vec<TransformOperation>,
|
||||
to_list: &Vec<TransformOperation>,
|
||||
time: f32) -> TransformList {
|
||||
time: f64) -> TransformList {
|
||||
let mut result = vec!();
|
||||
|
||||
if can_interpolate_list(from_list, to_list) {
|
||||
|
@ -828,7 +830,7 @@ fn build_identity_transform_list(list: &Vec<TransformOperation>) -> Vec<Transfor
|
|||
|
||||
impl Interpolate for TransformList {
|
||||
#[inline]
|
||||
fn interpolate(&self, other: &TransformList, time: f32) -> Option<TransformList> {
|
||||
fn interpolate(&self, other: &TransformList, time: f64) -> Option<TransformList> {
|
||||
// http://dev.w3.org/csswg/css-transforms/#interpolation-of-transforms
|
||||
let result = match (&self.0, &other.0) {
|
||||
(&Some(ref from_list), &Some(ref to_list)) => {
|
||||
|
|
|
@ -11,17 +11,17 @@ use euclid::point::Point2D;
|
|||
const NEWTON_METHOD_ITERATIONS: u8 = 8;
|
||||
|
||||
pub struct Bezier {
|
||||
ax: f32,
|
||||
bx: f32,
|
||||
cx: f32,
|
||||
ay: f32,
|
||||
by: f32,
|
||||
cy: f32,
|
||||
ax: f64,
|
||||
bx: f64,
|
||||
cx: f64,
|
||||
ay: f64,
|
||||
by: f64,
|
||||
cy: f64,
|
||||
}
|
||||
|
||||
impl Bezier {
|
||||
#[inline]
|
||||
pub fn new(p1: Point2D<f32>, p2: Point2D<f32>) -> Bezier {
|
||||
pub fn new(p1: Point2D<f64>, p2: Point2D<f64>) -> Bezier {
|
||||
let cx = 3.0 * p1.x;
|
||||
let bx = 3.0 * (p2.x - p1.x) - cx;
|
||||
|
||||
|
@ -39,23 +39,23 @@ impl Bezier {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn sample_curve_x(&self, t: f32) -> f32 {
|
||||
fn sample_curve_x(&self, t: f64) -> f64 {
|
||||
// ax * t^3 + bx * t^2 + cx * t
|
||||
((self.ax * t + self.bx) * t + self.cx) * t
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sample_curve_y(&self, t: f32) -> f32 {
|
||||
fn sample_curve_y(&self, t: f64) -> f64 {
|
||||
((self.ay * t + self.by) * t + self.cy) * t
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sample_curve_derivative_x(&self, t: f32) -> f32 {
|
||||
fn sample_curve_derivative_x(&self, t: f64) -> f64 {
|
||||
(3.0 * self.ax * t + 2.0 * self.bx) * t + self.cx
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn solve_curve_x(&self, x: f32, epsilon: f32) -> f32 {
|
||||
fn solve_curve_x(&self, x: f64, epsilon: f64) -> f64 {
|
||||
// Fast path: Use Newton's method.
|
||||
let mut t = x;
|
||||
for _ in 0..NEWTON_METHOD_ITERATIONS {
|
||||
|
@ -97,7 +97,7 @@ impl Bezier {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn solve(&self, x: f32, epsilon: f32) -> f32 {
|
||||
pub fn solve(&self, x: f64, epsilon: f64) -> f64 {
|
||||
self.sample_curve_y(self.solve_curve_x(x, epsilon))
|
||||
}
|
||||
}
|
||||
|
@ -106,9 +106,9 @@ trait ApproxEq {
|
|||
fn approx_eq(self, value: Self, epsilon: Self) -> bool;
|
||||
}
|
||||
|
||||
impl ApproxEq for f32 {
|
||||
impl ApproxEq for f64 {
|
||||
#[inline]
|
||||
fn approx_eq(self, value: f32, epsilon: f32) -> bool {
|
||||
fn approx_eq(self, value: f64, epsilon: f64) -> bool {
|
||||
(self - value).abs() < epsilon
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче