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

Refactor finding of instance times

Make FindInstanceTime(...) only handle the "strictly greater than" case
and rename it to NextAfter(...), adjusting the implementation
accordingly. This can be used for all the callers of
FindInstanceTime(...) except ResolveInterval(...).
Fold FindInstanceTime(...) with the "greater or equal" case into
ResolveInterval(...).

Bug: 1029573
Change-Id: Id727514e10586576796ecfacc5a045114217050c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1944473
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720892}
parent ffb1dff5
...@@ -691,34 +691,28 @@ void SVGSMILElement::AddInstanceTimeAndUpdate(BeginOrEnd begin_or_end, ...@@ -691,34 +691,28 @@ void SVGSMILElement::AddInstanceTimeAndUpdate(BeginOrEnd begin_or_end,
InstanceListChanged(); InstanceListChanged();
} }
SMILTime SVGSMILElement::FindInstanceTime(BeginOrEnd begin_or_end, SMILTime SVGSMILElement::NextAfter(BeginOrEnd begin_or_end,
SMILTime minimum_time, SMILTime time) const {
bool equals_minimum_ok) const {
const Vector<SMILTimeWithOrigin>& list = const Vector<SMILTimeWithOrigin>& list =
begin_or_end == kBegin ? begin_times_ : end_times_; begin_or_end == kBegin ? begin_times_ : end_times_;
if (list.IsEmpty()) {
if (list.IsEmpty())
return begin_or_end == kBegin ? SMILTime::Unresolved() return begin_or_end == kBegin ? SMILTime::Unresolved()
: SMILTime::Indefinite(); : SMILTime::Indefinite();
}
// If an equal value is not accepted, return the next bigger item in the list, // Find the value in |list| that is strictly greater than |time|.
// if any. auto* next_item = std::lower_bound(
auto predicate = [equals_minimum_ok](const SMILTimeWithOrigin& instance_time, list.begin(), list.end(), time,
const SMILTime& time) { [](const SMILTimeWithOrigin& instance_time, const SMILTime& time) {
return equals_minimum_ok ? instance_time.Time() < time return instance_time.Time() <= time;
: instance_time.Time() <= time; });
}; if (next_item == list.end())
auto* item =
std::lower_bound(list.begin(), list.end(), minimum_time, predicate);
if (item == list.end())
return SMILTime::Unresolved(); return SMILTime::Unresolved();
SMILTime next = next_item->Time();
// The special value "indefinite" does not yield an instance time in the begin // The special value "indefinite" does not yield an instance time in the
// list. // begin list.
if (item->Time().IsIndefinite() && begin_or_end == kBegin) if (begin_or_end == kBegin && next.IsIndefinite())
return SMILTime::Unresolved(); return SMILTime::Unresolved();
return next;
return item->Time();
} }
SMILTime SVGSMILElement::RepeatingDuration() const { SMILTime SVGSMILElement::RepeatingDuration() const {
...@@ -738,7 +732,7 @@ SMILTime SVGSMILElement::RepeatingDuration() const { ...@@ -738,7 +732,7 @@ SMILTime SVGSMILElement::RepeatingDuration() const {
} }
SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin) const { SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin) const {
SMILTime resolved_end = FindInstanceTime(kEnd, resolved_begin, false); SMILTime resolved_end = NextAfter(kEnd, resolved_begin);
if (resolved_end.IsUnresolved()) { if (resolved_end.IsUnresolved()) {
// If we have no pending end conditions, don't generate a new interval. // If we have no pending end conditions, don't generate a new interval.
if (!end_times_.IsEmpty() && !has_end_event_conditions_) if (!end_times_.IsEmpty() && !has_end_event_conditions_)
...@@ -770,22 +764,31 @@ SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin) const { ...@@ -770,22 +764,31 @@ SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin) const {
SMILInterval SVGSMILElement::ResolveInterval(SMILTime begin_after, SMILInterval SVGSMILElement::ResolveInterval(SMILTime begin_after,
SMILTime end_after) const { SMILTime end_after) const {
if (begin_times_.IsEmpty())
return SMILInterval::Unresolved();
// Simplified version of the pseudocode in // Simplified version of the pseudocode in
// http://www.w3.org/TR/SMIL3/smil-timing.html#q90. // http://www.w3.org/TR/SMIL3/smil-timing.html#q90.
const size_t kMaxIterations = std::max(begin_times_.size() * 4, 1000000u); const size_t kMaxIterations = std::max(begin_times_.size() * 4, 1000000u);
size_t current_iteration = 0; size_t current_iteration = 0;
while (true) { while (true) {
SMILTime temp_begin = FindInstanceTime(kBegin, begin_after, true); // Find the (next) instance time in the 'begin' list that is greater or
if (temp_begin.IsUnresolved()) // equal to |begin_after|.
auto* begin_item = std::lower_bound(
begin_times_.begin(), begin_times_.end(), begin_after,
[](const SMILTimeWithOrigin& instance_time, const SMILTime& time) {
return instance_time.Time() < time;
});
// If there are no more 'begin' instance times, or we encountered the
// special value "indefinite" (which doesn't yield an instance time in the
// 'begin' list), we're done.
if (begin_item == begin_times_.end() || begin_item->Time().IsIndefinite())
break; break;
SMILTime temp_end = ResolveActiveEnd(temp_begin); SMILTime temp_end = ResolveActiveEnd(begin_item->Time());
if (temp_end.IsUnresolved()) if (temp_end.IsUnresolved())
break; break;
// Don't allow the interval to end in the past. // Don't allow the interval to end in the past.
if (temp_end > end_after) { if (temp_end > end_after)
DCHECK(!temp_begin.IsIndefinite()); return SMILInterval(begin_item->Time(), temp_end);
return SMILInterval(temp_begin, temp_end);
}
// Ensure forward progress. // Ensure forward progress.
if (begin_after == temp_end) if (begin_after == temp_end)
temp_end = begin_after + SMILTime::Epsilon(); temp_end = begin_after + SMILTime::Epsilon();
...@@ -821,8 +824,7 @@ SMILTime SVGSMILElement::ComputeNextIntervalTime( ...@@ -821,8 +824,7 @@ SMILTime SVGSMILElement::ComputeNextIntervalTime(
next_interval_time = interval_.end; next_interval_time = interval_.end;
} }
} }
return std::min(next_interval_time, return std::min(next_interval_time, NextAfter(kBegin, presentation_time));
FindInstanceTime(kBegin, presentation_time, false));
} }
void SVGSMILElement::InstanceListChanged() { void SVGSMILElement::InstanceListChanged() {
...@@ -884,7 +886,7 @@ bool SVGSMILElement::HandleIntervalRestart(SMILTime presentation_time) { ...@@ -884,7 +886,7 @@ bool SVGSMILElement::HandleIntervalRestart(SMILTime presentation_time) {
if (!interval_.IsResolved() || interval_.EndsBefore(presentation_time)) if (!interval_.IsResolved() || interval_.EndsBefore(presentation_time))
return true; return true;
if (restart == kRestartAlways) { if (restart == kRestartAlways) {
SMILTime next_begin = FindInstanceTime(kBegin, interval_.begin, false); SMILTime next_begin = NextAfter(kBegin, interval_.begin);
if (interval_.EndsAfter(next_begin)) { if (interval_.EndsAfter(next_begin)) {
SetNewIntervalEnd(next_begin); SetNewIntervalEnd(next_begin);
return interval_.EndsBefore(presentation_time); return interval_.EndsBefore(presentation_time);
......
...@@ -140,9 +140,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { ...@@ -140,9 +140,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
return false; return false;
} }
SMILTime FindInstanceTime(BeginOrEnd, SMILTime NextAfter(BeginOrEnd, SMILTime time) const;
SMILTime minimum_time,
bool equals_minimum_ok) const;
SMILTime BeginTimeForPrioritization(SMILTime presentation_time) const; SMILTime BeginTimeForPrioritization(SMILTime presentation_time) const;
SMILInterval ResolveInterval(SMILTime begin_after, SMILTime end_after) const; SMILInterval ResolveInterval(SMILTime begin_after, SMILTime end_after) const;
......
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