Bug 1293945 - Set zero playback rate when setting incomputable playbackRate. r?birtles draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Tue, 23 Aug 2016 14:07:04 +0900
changeset 404207 57e52e3dcd7ad3ee738ebda25317ee2b7cfd946d
parent 401500 fe895421dfbe1f1f8f1fc6a39bb20774423a6d74
child 529133 28ecb2b0c68679ef3ef6faa8de19c8968f77385b
push id27156
push usermantaroh@gmail.com
push dateTue, 23 Aug 2016 05:07:24 +0000
reviewersbirtles
bugs1293945
milestone51.0a1
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
dom/animation/Animation.cpp
dom/animation/test/mochitest.ini
dom/animation/test/mozilla/file_animate_with_small_negative_playbackrate.html
dom/animation/test/mozilla/test_animate_with_small_negative_playbackrate.html
--- 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>