Bug 1293945 - Set zero playback rate when setting incomputable playbackRate. r?birtles
The calculated current time will be overflow when setting too small negative playback rate, because the gecko have current time as TimeDuration.
We set zero to the playback rate when setting too small negative playback rate in order to prevent this overflow.
MozReview-Commit-ID: 9SMqWWaQkOr
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -282,16 +282,21 @@ Animation::SetPlaybackRate(double aPlayb
{
if (aPlaybackRate == mPlaybackRate) {
return;
}
AutoMutationBatchForAnimation mb(*this);
Nullable<TimeDuration> previousTime = GetCurrentTime();
+ TimeDuration experimental = previousTime.Value().MultDouble(1/aPlaybackRate);
+ if (aPlaybackRate < 0 && (experimental == -TimeDuration::Forever())) {
+ aPlaybackRate = 0.0;
+ }
+
mPlaybackRate = aPlaybackRate;
if (!previousTime.IsNull()) {
SetCurrentTime(previousTime.Value());
}
// In the case where GetCurrentTime() returns the same result before and
// after updating mPlaybackRate, SetCurrentTime will return early since,
// as far as it can tell, nothing has changed.
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -30,16 +30,17 @@ support-files =
css-transitions/file_animation-starttime.html
css-transitions/file_csstransition-transitionproperty.html
css-transitions/file_document-get-animations.html
css-transitions/file_effect-target.html
css-transitions/file_element-get-animations.html
css-transitions/file_keyframeeffect-getkeyframes.html
css-transitions/file_pseudoElement-get-animations.html
document-timeline/file_document-timeline.html
+ mozilla/file_animate_with_small_negative_playbackrate.html
mozilla/file_cubic_bezier_limits.html
mozilla/file_deferred_start.html
mozilla/file_disabled_properties.html
mozilla/file_document-timeline-origin-time-range.html
mozilla/file_hide_and_show.html
mozilla/file_partial_keyframes.html
mozilla/file_transform_limits.html
mozilla/file_underlying-discrete-value.html
@@ -77,16 +78,17 @@ skip-if = buildapp == 'mulet'
[css-transitions/test_document-get-animations.html]
[css-transitions/test_effect-target.html]
[css-transitions/test_element-get-animations.html]
skip-if = buildapp == 'mulet'
[css-transitions/test_keyframeeffect-getkeyframes.html]
[css-transitions/test_pseudoElement-get-animations.html]
[document-timeline/test_document-timeline.html]
[document-timeline/test_request_animation_frame.html]
+[mozilla/test_animate_with_small_negative_playbackrate.html]
skip-if = buildapp == 'mulet'
[mozilla/test_cubic_bezier_limits.html]
[mozilla/test_deferred_start.html]
skip-if = (toolkit == 'gonk' && debug)
[mozilla/test_disabled_properties.html]
[mozilla/test_document-timeline-origin-time-range.html]
[mozilla/test_hide_and_show.html]
[mozilla/test_partial_keyframes.html]
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/file_animate_with_small_negative_playbackrate.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../testcommon.js"></script>
+<body>
+<script>
+'use strict';
+
+// If the playback rate is too small negative value, the Gecko will clamp
+// playback rate to 0. Because calculated current time from playback rate
+// will be overflow, and we can't get correct current time. [1]
+// Furthermore, the gecko have current time as TimeDuration. This TimeDuration
+// have internal variable value as int64_t, so we can't hold calculated current
+// time as fractional number.
+//
+// [1] https://dxr.mozilla.org/mozilla-central/rev/f97a056ae6235de7855fd8aaa04fb1c8d183bd06/dom/animation/Animation.cpp#237
+// [2] https://dxr.mozilla.org/mozilla-central/rev/f97a056ae6235de7855fd8aaa04fb1c8d183bd06/mozglue/misc/TimeStamp.h#315
+
+
+promise_test(function(t) {
+ var div = addDiv(t);
+ var animation = div.animate(null, 100 * MS_PER_SEC);
+
+ return animation.ready.then(function() {
+ var max = 9223372036854775807; // INT64_MAX
+ var playbackRate = 0.1 / max;
+ animation.playbackRate = -1 * playbackRate;
+
+ assert_equals(animation.playbackRate, 0);
+ assert_equals(animation.playState, 'running');
+ });
+}, 'Test the setting small negative playbackRate which we can\'t dealing with.');
+
+done();
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/mozilla/test_animate_with_small_negative_playbackrate.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+'use strict';
+setup({explicit_done: true});
+SpecialPowers.pushPrefEnv(
+ { "set": [["dom.animations-api.core.enabled", true]]},
+ function() {
+ window.open("file_animate_with_small_negative_playbackrate.html");
+ });
+</script>