Bug 927349 part 26 - Add a test for compositor animations with a delay; r=nical
authorBrian Birtles <birtles@gmail.com>
Thu, 25 Dec 2014 16:28:25 +0900
changeset 221323 79cac8c71159fb782d5073b366bdc904b4c1e6d8
parent 221322 9bdf7c2279fa921bb39e4e39b99526beaaef79de
child 221324 cfe757e478d59cb02ced7a2f6fcfa897b9992b73
push id28016
push userphilringnalda@gmail.com
push dateThu, 25 Dec 2014 19:58:27 +0000
treeherdermozilla-central@3a86099219cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs927349
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 927349 part 26 - Add a test for compositor animations with a delay; r=nical This patch adds a test that we correctly incorporate the delay when setting a layer animation's initialCurrentTime. The notion of 'current time' on layer animations differs from that on main thread animations in that it does not incorporate the animation delay. Instead, we wait until an animation's delay has complete before putting it on the layer and then it we add without delay. For animations that are still waiting to start we need to factor this delay into the initialCurrentTime stored on the layer animation so that when we update the animation's start time it represents the time *after* the delay has finished. Previously we failed to do this but no tests failed since all existing tests for delay rely on DOMWindowUtils.advanceTimeAndRefresh which avoids this particular code path (since we don't add pending animations to layers while the refresh driver is under test control). This patch adds a test for animation delay that does not rely on DOMWindowUtils.advanceTimeAndRefresh which has been confirmed to fail if we don't incorporate the delay in our calculation of initialCurrentTime.
dom/animation/test/mochitest.ini
dom/animation/test/mozilla/test_deferred_start.html
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -14,8 +14,9 @@ skip-if = buildapp == 'mulet'
 skip-if = buildapp == 'mulet'
 [css-transitions/test_animation-effect-name.html]
 [css-transitions/test_animation-pausing.html]
 [css-transitions/test_animation-player-ready.html]
 [css-transitions/test_animation-target.html]
 [css-transitions/test_element-get-animation-players.html]
 skip-if = buildapp == 'mulet'
 [mozilla/test_deferred_start.html]
+skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # bug 1113425
--- a/dom/animation/test/mozilla/test_deferred_start.html
+++ b/dom/animation/test/mozilla/test_deferred_start.html
@@ -1,16 +1,26 @@
 <!doctype html>
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="../testcommon.js"></script>
 <div id="log"></div>
 <style>
 @keyframes empty { }
+@keyframes animTransform {
+  from { transform: translate(0px); }
+  to { transform: translate(100px); }
+}
+.target {
+  // Element needs geometry to be eligible for layerization
+  width: 100px;
+  height: 100px;
+  background-color: white;
+}
 </style>
 <script>
 'use strict';
 
 function waitForDocLoad() {
   return new Promise(function(resolve, reject) {
     if (document.readyState === 'complete') {
       resolve();
@@ -53,9 +63,53 @@ async_test(function(t) {
   }).then(waitForFrame).then(t.step_func(function() {
     assert_true(promiseCallbackDone,
                 'ready promise callback was called before the next'
                 + ' requestAnimationFrame callback');
     t.done();
   }));
 }, 'AnimationPlayer.ready is resolved for an empty animation');
 
+// Test that compositor animations with delays get synced correctly
+//
+// NOTE: It is important that we DON'T use
+// SpecialWindows.DOMWindowUtils.advanceTimeAndRefresh here since that takes
+// us through a different code path.
+async_test(function(t) {
+  // This test only applies to compositor animations
+  const OMTAPrefKey = 'layers.offmainthreadcomposition.async-animations';
+  var omtaEnabled = SpecialPowers.DOMWindowUtils.layerManagerRemote &&
+                    SpecialPowers.getBoolPref(OMTAPrefKey);
+  if (!omtaEnabled) {
+    t.done();
+    return;
+  }
+
+  // Setup animation
+  var div = addDiv(t);
+  div.classList.add('target');
+  div.style.animation = 'animTransform 100s -50s forwards';
+  var player = div.getAnimationPlayers()[0];
+
+  player.ready.then(t.step_func(function() {
+    var transformStr =
+      SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
+
+    var matrixComponents =
+      transformStr.startsWith('matrix(')
+      ? transformStr.substring('matrix('.length, transformStr.length-1)
+                    .split(',')
+                    .map(component => Number(component))
+      : [];
+    assert_equals(matrixComponents.length, 6,
+                  'Got a valid transform matrix on the compositor'
+                  + ' (got: "' + transformStr + '")');
+
+    // If the delay has been applied correctly we should be at least
+    // half-way through the animation
+    assert_true(matrixComponents[4] >= 50,
+                'Animation is at least half-way through on the compositor'
+                + ' (got translation of ' + matrixComponents[4] + ')');
+    t.done();
+  }));
+}, 'Starting an animation with a delay starts from the correct point');
+
 </script>