Commit 08d1887f authored by Sergio Villar Senin's avatar Sergio Villar Senin Committed by Commit Bot

Make CalculateActiveTime() return AnimationTimeDelta

It's currently returning a double. As part of the process of rewriting the
animation engine we're replacing doubles by base::Time* alternatives.

Bug: 737867
Change-Id: I9d6cca66354ec22f5387ce7328b92c5c396ce283
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1819243Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Commit-Queue: Sergio Villar <svillar@igalia.com>
Cr-Commit-Position: refs/heads/master@{#699657}
parent 8e7f720c
......@@ -1230,9 +1230,10 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition(
// Per the css-transitions-2 spec, transitioncancel is fired with the
// "active time of the animation at the moment it was cancelled,
// calculated using a fill mode of both".
base::Optional<double> cancel_active_time = CalculateActiveTime(
animation_node.SpecifiedTiming().ActiveDuration(),
Timing::FillMode::BOTH, animation_node.LocalTime(), previous_phase_,
base::Optional<AnimationTimeDelta> cancel_active_time =
CalculateActiveTime(animation_node.SpecifiedTiming().ActiveDuration(),
Timing::FillMode::BOTH,
animation_node.LocalTime(), previous_phase_,
animation_node.SpecifiedTiming());
// Being the FillMode::BOTH the only possibility to get a null
// cancel_active_time is that previous_phase_ is kPhaseNone. This cannot
......@@ -1240,7 +1241,7 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition(
// current_phase != previous_phase_ (see early return at the beginning).
DCHECK(cancel_active_time);
EnqueueEvent(event_type_names::kTransitioncancel,
cancel_active_time.value());
cancel_active_time->InSecondsF());
}
}
......
......@@ -160,7 +160,7 @@ Timing::CalculatedTiming Timing::CalculateTimings(
const Timing::Phase current_phase =
CalculatePhase(active_duration, local_time, animation_direction, *this);
const base::Optional<double> active_time =
const base::Optional<AnimationTimeDelta> active_time =
CalculateActiveTime(active_duration, ResolvedFillMode(is_keyframe_effect),
local_time, current_phase, *this);
......@@ -204,7 +204,7 @@ Timing::CalculatedTiming Timing::CalculateTimings(
DCHECK(active_time);
time_to_next_iteration =
iteration_duration - iteration_time->InSecondsF();
if (active_duration - active_time.value() < time_to_next_iteration)
if (active_duration - active_time->InSecondsF() < time_to_next_iteration)
time_to_next_iteration = std::numeric_limits<double>::infinity();
}
}
......
......@@ -94,7 +94,7 @@ static inline Timing::Phase CalculatePhase(double active_duration,
}
// https://drafts.csswg.org/web-animations/#calculating-the-active-time
static inline base::Optional<double> CalculateActiveTime(
static inline base::Optional<AnimationTimeDelta> CalculateActiveTime(
double active_duration,
Timing::FillMode fill_mode,
double local_time,
......@@ -105,16 +105,20 @@ static inline base::Optional<double> CalculateActiveTime(
switch (phase) {
case Timing::kPhaseBefore:
if (fill_mode == Timing::FillMode::BACKWARDS ||
fill_mode == Timing::FillMode::BOTH)
return std::max(local_time - specified.start_delay, 0.0);
fill_mode == Timing::FillMode::BOTH) {
return AnimationTimeDelta::FromSecondsD(
std::max(local_time - specified.start_delay, 0.0));
}
return base::nullopt;
case Timing::kPhaseActive:
return local_time - specified.start_delay;
return AnimationTimeDelta::FromSecondsD(local_time -
specified.start_delay);
case Timing::kPhaseAfter:
if (fill_mode == Timing::FillMode::FORWARDS ||
fill_mode == Timing::FillMode::BOTH) {
return std::max(
0.0, std::min(active_duration, local_time - specified.start_delay));
return AnimationTimeDelta::FromSecondsD(std::max(
0.0,
std::min(active_duration, local_time - specified.start_delay)));
}
return base::nullopt;
case Timing::kPhaseNone:
......@@ -131,7 +135,7 @@ static inline base::Optional<double> CalculateActiveTime(
// https://drafts.csswg.org/web-animations/#calculating-the-overall-progress
static inline base::Optional<double> CalculateOverallProgress(
Timing::Phase phase,
base::Optional<double> active_time,
base::Optional<AnimationTimeDelta> active_time,
double iteration_duration,
double iteration_count,
double iteration_start) {
......@@ -145,7 +149,7 @@ static inline base::Optional<double> CalculateOverallProgress(
if (phase != Timing::kPhaseBefore)
overall_progress = iteration_count;
} else {
overall_progress = active_time.value() / iteration_duration;
overall_progress = active_time->InSecondsF() / iteration_duration;
}
return overall_progress + iteration_start;
......@@ -161,7 +165,7 @@ static inline base::Optional<double> CalculateSimpleIterationProgress(
Timing::Phase phase,
base::Optional<double> overall_progress,
double iteration_start,
base::Optional<double> active_time,
base::Optional<AnimationTimeDelta> active_time,
double active_duration,
double iteration_count) {
// 1. If the overall progress is unresolved, return unresolved.
......@@ -187,7 +191,7 @@ static inline base::Optional<double> CalculateSimpleIterationProgress(
// let the simple iteration progress be 1.0.
if (IsWithinEpsilon(simple_iteration_progress, 0.0) &&
(phase == Timing::kPhaseActive || phase == Timing::kPhaseAfter) &&
IsWithinEpsilon(active_time.value(), active_duration) &&
IsWithinEpsilon(active_time->InSecondsF(), active_duration) &&
!IsWithinEpsilon(iteration_count, 0.0)) {
simple_iteration_progress = 1.0;
}
......@@ -199,7 +203,7 @@ static inline base::Optional<double> CalculateSimpleIterationProgress(
// https://drafts.csswg.org/web-animations/#calculating-the-current-iteration
static inline base::Optional<double> CalculateCurrentIteration(
Timing::Phase phase,
base::Optional<double> active_time,
base::Optional<AnimationTimeDelta> active_time,
double iteration_count,
base::Optional<double> overall_progress,
base::Optional<double> simple_iteration_progress) {
......@@ -316,7 +320,7 @@ static inline base::Optional<double> CalculateTransformedProgress(
// iteration to optimize scheduling.
static inline base::Optional<AnimationTimeDelta> CalculateOffsetActiveTime(
double active_duration,
base::Optional<double> active_time,
base::Optional<AnimationTimeDelta> active_time,
double start_offset) {
DCHECK_GE(active_duration, 0);
DCHECK_GE(start_offset, 0);
......@@ -324,13 +328,14 @@ static inline base::Optional<AnimationTimeDelta> CalculateOffsetActiveTime(
if (!active_time)
return base::nullopt;
DCHECK(active_time.value() >= 0 &&
LessThanOrEqualToWithinEpsilon(active_time.value(), active_duration));
DCHECK(active_time.value() >= AnimationTimeDelta() &&
LessThanOrEqualToWithinEpsilon(active_time->InSecondsF(),
active_duration));
if (!std::isfinite(active_time.value()))
if (active_time->is_max())
return AnimationTimeDelta::Max();
return AnimationTimeDelta::FromSecondsD(active_time.value() + start_offset);
return active_time.value() + AnimationTimeDelta::FromSecondsD(start_offset);
}
// Maps the offset active time into 'iteration time space'[0], aka the offset
......
......@@ -47,24 +47,30 @@ TEST(AnimationTimingCalculationsTest, ActiveTime) {
Timing::kPhaseBefore, timing));
EXPECT_FALSE(CalculateActiveTime(20, Timing::FillMode::NONE, 0,
Timing::kPhaseBefore, timing));
EXPECT_EQ(0, CalculateActiveTime(20, Timing::FillMode::BACKWARDS, 0,
EXPECT_EQ(AnimationTimeDelta(),
CalculateActiveTime(20, Timing::FillMode::BACKWARDS, 0,
Timing::kPhaseBefore, timing));
EXPECT_EQ(0, CalculateActiveTime(20, Timing::FillMode::BOTH, 0,
EXPECT_EQ(AnimationTimeDelta(),
CalculateActiveTime(20, Timing::FillMode::BOTH, 0,
Timing::kPhaseBefore, timing));
timing.start_delay = -10;
EXPECT_EQ(5, CalculateActiveTime(20, Timing::FillMode::BACKWARDS, -5,
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5),
CalculateActiveTime(20, Timing::FillMode::BACKWARDS, -5,
Timing::kPhaseBefore, timing));
// Active Phase
timing.start_delay = 10;
EXPECT_EQ(5, CalculateActiveTime(20, Timing::FillMode::FORWARDS, 15,
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5),
CalculateActiveTime(20, Timing::FillMode::FORWARDS, 15,
Timing::kPhaseActive, timing));
// After Phase
timing.start_delay = 10;
EXPECT_EQ(21, CalculateActiveTime(21, Timing::FillMode::FORWARDS, 45,
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21),
CalculateActiveTime(21, Timing::FillMode::FORWARDS, 45,
Timing::kPhaseAfter, timing));
EXPECT_EQ(21, CalculateActiveTime(21, Timing::FillMode::BOTH, 45,
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21),
CalculateActiveTime(21, Timing::FillMode::BOTH, 45,
Timing::kPhaseAfter, timing));
EXPECT_FALSE(CalculateActiveTime(21, Timing::FillMode::BACKWARDS, 45,
Timing::kPhaseAfter, timing));
......@@ -81,20 +87,20 @@ TEST(AnimationTimingCalculationsTest, OffsetActiveTime) {
EXPECT_FALSE(CalculateOffsetActiveTime(4, base::nullopt, 5));
// normal case
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(15),
CalculateOffsetActiveTime(40, 10, 5));
EXPECT_EQ(
AnimationTimeDelta::FromSecondsD(15),
CalculateOffsetActiveTime(40, AnimationTimeDelta::FromSecondsD(10), 5));
// infinte activeTime
// infinite activeTime
EXPECT_TRUE(CalculateOffsetActiveTime(std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity(),
0)
AnimationTimeDelta::Max(), 0)
->is_max());
// Edge case for active_time being within epsilon of active_duration.
// https://crbug.com/962138
const double active_time = 1.3435713716800004;
auto active_time = AnimationTimeDelta::FromSecondsD(1.3435713716800004);
const double active_duration = 1.3435713716800002;
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(active_time),
EXPECT_EQ(active_time,
CalculateOffsetActiveTime(active_duration, active_time, 0));
}
......@@ -154,28 +160,32 @@ TEST(AnimationTimingCalculationsTest, OverallProgress) {
/*iteration_start=*/1.0));
// If iteration duration is zero, calculate progress based on iteration count.
EXPECT_EQ(3, CalculateOverallProgress(Timing::kPhaseActive,
/*active_time=*/3.0,
EXPECT_EQ(3, CalculateOverallProgress(
Timing::kPhaseActive,
/*active_time=*/AnimationTimeDelta::FromSecondsD(3.0),
/*iteration_duration=*/0.0,
/*iteration_count=*/3.0,
/*iteration_start=*/0.0));
// ...unless in before phase, in which case progress is zero.
EXPECT_EQ(0, CalculateOverallProgress(Timing::kPhaseBefore,
/*active_time=*/3.0,
EXPECT_EQ(0, CalculateOverallProgress(
Timing::kPhaseBefore,
/*active_time=*/AnimationTimeDelta::FromSecondsD(3.0),
/*iteration_duration=*/0.0,
/*iteration_count=*/3.0,
/*iteration_start=*/0.0));
// Edge case for duration being within Epsilon of zero.
// crbug.com/954558
EXPECT_EQ(1, CalculateOverallProgress(Timing::kPhaseActive,
/*active_time=*/3.0,
EXPECT_EQ(1, CalculateOverallProgress(
Timing::kPhaseActive,
/*active_time=*/AnimationTimeDelta::FromSecondsD(3.0),
/*iteration_duration=*/1e-18,
/*iteration_count=*/1.0,
/*iteration_start=*/0.0));
// Otherwise.
EXPECT_EQ(3.0, CalculateOverallProgress(Timing::kPhaseAfter,
/*active_time=*/2.5,
EXPECT_EQ(3.0, CalculateOverallProgress(
Timing::kPhaseAfter,
/*active_time=*/AnimationTimeDelta::FromSecondsD(2.5),
/*iteration_duration=*/1.0,
/*iteration_count=*/0.0,
/*iteration_start=*/0.5));
......@@ -193,26 +203,29 @@ TEST(AnimationTimingCalculationsTest, CalculateSimpleIterationProgress) {
// If the overall progress is infinite.
const double inf = std::numeric_limits<double>::infinity();
EXPECT_EQ(0.5, CalculateSimpleIterationProgress(Timing::kPhaseAfter,
EXPECT_EQ(0.5, CalculateSimpleIterationProgress(
Timing::kPhaseAfter,
/*overall_progress=*/inf,
/*iteration_start=*/1.5,
/*active_time=*/0.0,
/*active_time=*/AnimationTimeDelta(),
/*active_duration=*/0.0,
/*iteration_count=*/inf));
// Precisely on an iteration boundary.
EXPECT_EQ(1.0, CalculateSimpleIterationProgress(Timing::kPhaseAfter,
EXPECT_EQ(1.0, CalculateSimpleIterationProgress(
Timing::kPhaseAfter,
/*overall_progress=*/3.0,
/*iteration_start=*/0.0,
/*active_time=*/3.0,
/*active_time=*/AnimationTimeDelta::FromSecondsD(3.0),
/*active_duration=*/3.0,
/*iteration_count=*/3.0));
// Otherwise.
EXPECT_EQ(0.5, CalculateSimpleIterationProgress(Timing::kPhaseAfter,
EXPECT_EQ(0.5, CalculateSimpleIterationProgress(
Timing::kPhaseAfter,
/*overall_progress=*/2.5,
/*iteration_start=*/0.0,
/*active_time=*/2.5,
/*active_time=*/AnimationTimeDelta::FromSecondsD(2.5),
/*active_duration=*/0.0,
/*iteration_count=*/0.0));
}
......@@ -227,16 +240,18 @@ TEST(AnimationTimingCalculationsTest, CurrentIteration) {
// If the iteration count is infinite.
const double inf = std::numeric_limits<double>::infinity();
EXPECT_EQ(inf, CalculateCurrentIteration(Timing::kPhaseAfter,
/*active_time=*/1.0,
EXPECT_EQ(inf, CalculateCurrentIteration(
Timing::kPhaseAfter,
/*active_time=*/AnimationTimeDelta::FromSecondsD(1.0),
/*iteration_count=*/inf,
/*overall_progress=*/inf,
/*simple_iteration_progress=*/0.0));
// Hold the endpoint of the final iteration of ending precisely on an
// iteration boundary.
EXPECT_EQ(2, CalculateCurrentIteration(Timing::kPhaseAfter,
/*active_time=*/3.0,
EXPECT_EQ(2, CalculateCurrentIteration(
Timing::kPhaseAfter,
/*active_time=*/AnimationTimeDelta::FromSecondsD(3.0),
/*iteration_count=*/3.0,
/*overall_progress=*/3.0,
/*simple_iteration_progress=*/1.0));
......@@ -244,14 +259,15 @@ TEST(AnimationTimingCalculationsTest, CurrentIteration) {
// Edge case for zero-duration animation.
// crbug.com/954558
EXPECT_EQ(0, CalculateCurrentIteration(Timing::kPhaseAfter,
/*active_time=*/0.0,
/*active_time=*/AnimationTimeDelta(),
/*iteration_count=*/1.0,
/*overall_progress=*/0.0,
/*simple_iteration_progress=*/1.0));
// Otherwise.
EXPECT_EQ(2, CalculateCurrentIteration(Timing::kPhaseAfter,
/*active_time=*/2.5,
EXPECT_EQ(2, CalculateCurrentIteration(
Timing::kPhaseAfter,
/*active_time=*/AnimationTimeDelta::FromSecondsD(2.5),
/*iteration_count=*/0.0,
/*overall_progress=*/2.5,
/*simple_iteration_progress=*/0.5));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment