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

Check active/previous interval when rescheduling after interval update

When nudging the presentation time back in InstanceListChanged(), the
previous interval could be the active one, so we need to consider it
when updating the active state and when compute the next interval time.

Bug: 1030309
Change-Id: I5d20878f45dd4e26c5966c816b9ff5c82e4c40b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1948938Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#721129}
parent caa8db68
......@@ -839,14 +839,24 @@ void SVGSMILElement::InstanceListChanged() {
// care of updating the active state and send events as needed.
SMILTime previous_presentation_time =
current_presentation_time - SMILTime::Epsilon();
if (was_active && interval_.BeginsAfter(previous_presentation_time)) {
active_state_ = DetermineActiveState(previous_presentation_time);
if (was_active) {
const SMILInterval& active_interval =
GetActiveInterval(previous_presentation_time);
active_state_ =
DetermineActiveState(active_interval, previous_presentation_time);
if (GetActiveState() != kActive)
EndedActiveInterval();
}
if (time_container_) {
time_container_->Reschedule(
this, ComputeNextIntervalTime(previous_presentation_time));
SMILTime next_interval_time;
// If we switched interval and the previous interval did not end yet, we
// need to consider it when computing the next interval time.
if (previous_interval_.IsResolved() &&
previous_interval_.EndsAfter(previous_presentation_time))
next_interval_time = previous_interval_.end;
else
next_interval_time = ComputeNextIntervalTime(previous_presentation_time);
time_container_->Reschedule(this, next_interval_time);
}
}
......@@ -931,7 +941,7 @@ void SVGSMILElement::AddedToTimeContainer() {
// care of updating the active state and send events as needed.
SMILTime previous_presentation_time =
current_presentation_time - SMILTime::Epsilon();
active_state_ = DetermineActiveState(previous_presentation_time);
active_state_ = DetermineActiveState(interval_, previous_presentation_time);
time_container_->Reschedule(
this, ComputeNextIntervalTime(previous_presentation_time));
......@@ -1028,8 +1038,9 @@ SMILTime SVGSMILElement::NextProgressTime(SMILTime presentation_time) const {
}
SVGSMILElement::ActiveState SVGSMILElement::DetermineActiveState(
const SMILInterval& interval,
SMILTime elapsed) const {
if (interval_.Contains(elapsed))
if (interval.Contains(elapsed))
return kActive;
if (is_waiting_for_first_interval_)
return kInactive;
......@@ -1047,7 +1058,7 @@ bool SVGSMILElement::IsContributing(SMILTime elapsed) const {
void SVGSMILElement::UpdateActiveState(SMILTime elapsed) {
const bool was_active = GetActiveState() == kActive;
active_state_ = DetermineActiveState(elapsed);
active_state_ = DetermineActiveState(interval_, elapsed);
const bool is_active = GetActiveState() == kActive;
const bool interval_restart =
interval_has_changed_ && previous_interval_.end == interval_.begin;
......
......@@ -227,7 +227,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
ActiveState GetActiveState() const {
return static_cast<ActiveState>(active_state_);
}
ActiveState DetermineActiveState(SMILTime elapsed) const;
ActiveState DetermineActiveState(const SMILInterval& interval,
SMILTime elapsed) const;
ProgressState CalculateProgressState(SMILTime presentation_time) const;
......
<!DOCTYPE html>
<title>Cyclic syncbase dependency with syncbase trigger - event dispatching</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<svg>
<rect width="100" height="100" fill="blue">
<animate attributeName="fill" from="yellow" to="blue" id="a"
begin="c.end; b.begin" dur="10ms"/>
</rect>
<rect width="100" height="100" x="100" fill="blue">
<animate attributeName="fill" from="yellow" to="blue" id="b"
begin="c.end; a.begin" dur="10ms"/>
</rect>
<rect width="100" height="100" x="200" fill="blue">
<animate attributeName="fill" from="yellow" to="blue" id="c"
begin="0; 15ms" dur="10ms"/>
</rect>
</svg>
<script>
promise_test(function(t) {
// Wait for two beginEvent/endEvent pairs on all the timed elements.
let promises = ['a', 'b', 'c'].map(function(id) {
return new EventWatcher(t, document.getElementById(id),
['beginEvent', 'endEvent'])
.wait_for(['beginEvent', 'endEvent',
'beginEvent', 'endEvent']);
});
return Promise.all(promises);
});
</script>
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