Commit ae0aee38 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Merge SVGSMILElement progress update functions (again)

After having been separated for a bit, CalculateAnimationRepeat(...) and
its companion CalculateAnimationPercent(...) can now be merged again.
While doing this, eliminate the float epsilon tricks in favor of integer
epsilon tricks (and attempt to comment on what is being done).

Bug: 998526
Change-Id: Id1d7367672f46886e466b42e49be8dd968fbd1cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1833587
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#701716}
parent ebe890d7
...@@ -66,6 +66,9 @@ class SMILTime { ...@@ -66,6 +66,9 @@ class SMILTime {
return base::TimeDelta::Max() - base::TimeDelta::FromMicroseconds(2); return base::TimeDelta::Max() - base::TimeDelta::FromMicroseconds(2);
} }
static constexpr SMILTime Earliest() { return base::TimeDelta::Min(); } static constexpr SMILTime Earliest() { return base::TimeDelta::Min(); }
static constexpr SMILTime Epsilon() {
return base::TimeDelta::FromMicroseconds(1);
}
static constexpr SMILTime FromSecondsD(double seconds) { static constexpr SMILTime FromSecondsD(double seconds) {
return base::TimeDelta::FromSecondsD(seconds); return base::TimeDelta::FromSecondsD(seconds);
} }
......
...@@ -959,62 +959,51 @@ const SMILInterval& SVGSMILElement::GetActiveInterval(SMILTime elapsed) const { ...@@ -959,62 +959,51 @@ const SMILInterval& SVGSMILElement::GetActiveInterval(SMILTime elapsed) const {
return interval_; return interval_;
} }
unsigned SVGSMILElement::CalculateAnimationRepeat(SMILTime elapsed) const { SVGSMILElement::ProgressState SVGSMILElement::CalculateProgressState(
SMILTime presentation_time) const {
const SMILTime simple_duration = SimpleDuration(); const SMILTime simple_duration = SimpleDuration();
if (simple_duration.IsIndefinite())
return {0.0f, 0};
if (!simple_duration) if (!simple_duration)
return 0; return {1.0f, 0};
DCHECK(simple_duration.IsFinite()); DCHECK(simple_duration.IsFinite());
const SMILInterval& active_interval = GetActiveInterval(elapsed); const SMILInterval& active_interval = GetActiveInterval(presentation_time);
DCHECK(active_interval.begin.IsFinite());
SMILTime active_time = elapsed - active_interval.begin;
SMILTime repeating_duration = RepeatingDuration();
int64_t repeat;
if (elapsed >= active_interval.end || active_time > repeating_duration) {
if (!repeating_duration.IsFinite())
return 0;
repeat = repeating_duration / simple_duration;
if (!(repeating_duration % simple_duration))
repeat--;
} else {
repeat = active_time / simple_duration;
}
return clampTo<unsigned>(repeat);
}
float SVGSMILElement::CalculateAnimationPercent(SMILTime elapsed) const {
SMILTime simple_duration = SimpleDuration();
if (simple_duration.IsIndefinite()) {
return 0.f;
}
if (!simple_duration) {
return 1.f;
}
DCHECK(simple_duration.IsFinite());
const SMILInterval& active_interval = GetActiveInterval(elapsed);
DCHECK(active_interval.IsResolved()); DCHECK(active_interval.IsResolved());
const SMILTime active_time = presentation_time - active_interval.begin;
SMILTime repeating_duration = RepeatingDuration(); const SMILTime repeating_duration = RepeatingDuration();
SMILTime active_time = elapsed - active_interval.begin; int64_t repeat;
if (elapsed >= active_interval.end || active_time > repeating_duration) { SMILTime simple_time;
if (presentation_time >= active_interval.end ||
active_time > repeating_duration) {
// Use the interval to compute the interval position if we've passed the // Use the interval to compute the interval position if we've passed the
// interval end, otherwise use the "repeating duration". This prevents a // interval end, otherwise use the "repeating duration". This prevents a
// stale interval (with for instance an 'indefinite' end) from yielding an // stale interval (with for instance an 'indefinite' end) from yielding an
// invalid interval position. // invalid interval position.
SMILTime last_active_duration = repeating_duration; SMILTime last_active_duration =
if (elapsed >= active_interval.end) presentation_time >= active_interval.end
last_active_duration = active_interval.end - active_interval.begin; ? active_interval.end - active_interval.begin
double percent = last_active_duration.InternalValueAsDouble() / : repeating_duration;
simple_duration.InternalValueAsDouble(); if (!last_active_duration.IsFinite())
percent = percent - floor(percent); return {0.0f, 0};
float epsilon = std::numeric_limits<float>::epsilon(); // If the repeat duration is a multiple of the simple duration, we should
if (percent < epsilon || 1 - percent < epsilon) // use a progress value of 1.0, otherwise we should return a value that is
return 1.0f; // within the interval (< 1.0), so subtract the smallest representable time
return clampTo<float>(percent); // delta in that case.
repeat = last_active_duration / simple_duration;
simple_time = last_active_duration % simple_duration;
if (simple_time) {
simple_time = simple_time - SMILTime::Epsilon();
} else {
simple_time = simple_duration;
repeat--;
}
} else {
repeat = active_time / simple_duration;
simple_time = active_time % simple_duration;
} }
SMILTime simple_time = active_time % simple_duration; return {clampTo<float>(simple_time.InternalValueAsDouble() /
return clampTo<float>(simple_time.InternalValueAsDouble() / simple_duration.InternalValueAsDouble()),
simple_duration.InternalValueAsDouble()); clampTo<unsigned>(repeat)};
} }
SMILTime SVGSMILElement::NextProgressTime(SMILTime presentation_time) const { SMILTime SVGSMILElement::NextProgressTime(SMILTime presentation_time) const {
...@@ -1111,14 +1100,13 @@ void SVGSMILElement::UpdateActiveState(SMILTime elapsed) { ...@@ -1111,14 +1100,13 @@ void SVGSMILElement::UpdateActiveState(SMILTime elapsed) {
StartedActiveInterval(); StartedActiveInterval();
} }
unsigned repeat = CalculateAnimationRepeat(elapsed); ProgressState progress_state = CalculateProgressState(elapsed);
if (repeat && repeat != last_repeat_) { if (progress_state.repeat && progress_state.repeat != last_repeat_) {
last_repeat_ = repeat; last_repeat_ = progress_state.repeat;
NotifyDependentsOnRepeat(repeat, elapsed); NotifyDependentsOnRepeat(last_repeat_, elapsed);
ScheduleRepeatEvents(); ScheduleRepeatEvents();
} }
last_percent_ = progress_state.progress;
last_percent_ = CalculateAnimationPercent(elapsed);
} }
} }
......
...@@ -240,8 +240,12 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { ...@@ -240,8 +240,12 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
return static_cast<ActiveState>(active_state_); return static_cast<ActiveState>(active_state_);
} }
ActiveState DetermineActiveState(SMILTime elapsed) const; ActiveState DetermineActiveState(SMILTime elapsed) const;
float CalculateAnimationPercent(SMILTime elapsed) const;
unsigned CalculateAnimationRepeat(SMILTime elapsed) const; struct ProgressState {
float progress;
unsigned repeat;
};
ProgressState CalculateProgressState(SMILTime presentation_time) const;
Member<SVGElement> target_element_; Member<SVGElement> target_element_;
Member<IdTargetObserver> target_id_observer_; Member<IdTargetObserver> target_id_observer_;
......
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