--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -127,26 +127,26 @@ function waitForWheelEvent(aTarget) {
sendWheelAndPaintNoFlush(aTarget, centerX, centerY,
{ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaY: targetRect.height },
resolve);
});
}
-function tweakExpectedRestyleCount(aAnimation, aExpectedRestyleCount) {
+async function waitForAnimationReadyToRestyle(aAnimation) {
+ await aAnimation.ready;
// If |aAnimation| begins at the current timeline time, we will not process
// restyling in the initial frame because of aligning with the refresh driver,
// the animation frame in which the ready promise is resolved happens to
// coincide perfectly with the start time of the animation. In this case no
- // restyling is needed so we won't observe an additional restyle.
+ // restyling is needed in the frame so we have to wait one more frame.
if (animationStartsRightNow(aAnimation)) {
- return aExpectedRestyleCount - 1;
+ await waitForNextFrame();
}
- return aExpectedRestyleCount;
}
var omtaEnabled = isOMTAEnabled();
var isAndroid = !!navigator.userAgent.includes("Android");
const isWebRender =
SpecialPowers.DOMWindowUtils.layerManagerType == 'WebRender';
@@ -160,24 +160,22 @@ function add_task_if_omta_enabled(test)
// We need to wait for all paints before running tests to avoid contaminations
// from styling of this document itself.
waitForAllPaints(() => {
add_task(async function restyling_for_main_thread_animations() {
var div = addDiv(null, { style: 'animation: background-color 100s' });
var animation = div.getAnimations()[0];
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
+
ok(!SpecialPowers.wrap(animation).isRunningOnCompositor);
- // We need to tweak expected restyle count depending on animation state and
- // micro task handling.
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'CSS animations running on the main-thread should update style ' +
'on the main thread');
await ensureElementRemoval(div);
});
add_task_if_omta_enabled(async function no_restyling_for_compositor_animations() {
var div = addDiv(null, { style: 'animation: opacity 100s' });
var animation = div.getAnimations()[0];
@@ -474,23 +472,21 @@ waitForAllPaints(() => {
var div = addDiv(null);
var animation =
div.animate({ transform: [ 'translateX(120%)', 'translateX(100%)' ] },
// This animation will move a bit but
// will remain out-of-view.
100 * MS_PER_SEC);
parentElement.appendChild(div);
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
ok(!SpecialPowers.wrap(animation).isRunningOnCompositor);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 20);
-
var markers = await observeStyling(20);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 20,
'Finite transform animation in out-of-view element should never be ' +
'throttled');
await ensureElementRemoval(parentElement);
});
add_task(async function restyling_main_thread_animations_in_scrolled_out_element() {
var parentElement = addDiv(null,
@@ -1220,59 +1216,56 @@ waitForAllPaints(() => {
add_task(
async function no_throttling_additive_animations_out_of_view_element() {
var div = addDiv(null, { style: 'transform: translateY(-400px);' });
var animation =
div.animate([{ visibility: 'visible' }],
{ duration: 100 * MS_PER_SEC, composite: 'add' });
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'Additive animation has no keyframe whose offset is 0 or 1 in an ' +
'out-of-view element should not be throttled');
await ensureElementRemoval(div);
}
);
// Tests that missing keyframes animations don't throttle at all.
add_task(async function no_throttling_animations_out_of_view_element() {
var div = addDiv(null, { style: 'transform: translateY(-400px);' });
var animation =
div.animate([{ visibility: 'visible' }], 100 * MS_PER_SEC);
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'Discrete animation has has no keyframe whose offset is 0 or 1 in an ' +
'out-of-view element should not be throttled');
await ensureElementRemoval(div);
});
// Tests that missing keyframes animation on scrolled out element that the
// animation is not able to be throttled.
add_task(
async function no_throttling_missing_keyframe_animations_out_of_view_element() {
var div =
addDiv(null, { style: 'transform: translateY(-400px);' +
'visibility: collapse;' });
var animation =
div.animate([{ visibility: 'visible' }], 100 * MS_PER_SEC);
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'visibility animation has no keyframe whose offset is 0 or 1 in an ' +
'out-of-view element and produces change hint other than paint-only ' +
'change hint should not be throttled');
await ensureElementRemoval(div);
}
);
// Counter part of the above test.
@@ -1314,21 +1307,20 @@ waitForAllPaints(() => {
width: '50px',
height: '50px' });
var rect = addSVGElement(svg, 'rect', { x: '-10',
y: '-10',
width: '10',
height: '10',
fill: 'red' });
var animation = rect.animate({ fill: ['blue', 'lime'] }, 100 * MS_PER_SEC);
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'CSS animations on an in-view svg element with post-transform should ' +
'not be throttled.');
await ensureElementRemoval(div);
});
add_task(async function no_throttling_animations_in_transformed_parent() {
var div = addDiv(null, { style: 'overflow: scroll;' +
@@ -1337,21 +1329,20 @@ waitForAllPaints(() => {
width: '40px',
height: '40px' });
var rect = addSVGElement(svg, 'rect', { x: '0',
y: '0',
width: '1250',
height: '1250',
fill: 'red' });
var animation = rect.animate({ fill: ['blue', 'lime'] }, 100 * MS_PER_SEC);
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'CSS animations on an in-view svg element which is inside transformed ' +
'parent should not be throttled.');
await ensureElementRemoval(div);
});
add_task(async function throttling_animations_out_of_view_svg() {
var div = addDiv(null, { style: 'overflow: scroll;' +
@@ -1378,21 +1369,20 @@ waitForAllPaints(() => {
var scrollDiv = addDiv(null, { style: 'overflow: scroll; ' +
'height: 100px; width: 100px;' });
var targetDiv = addDiv(null,
{ style: 'animation: background-color 100s;' +
'transform: translate(-50px, -50px);' });
scrollDiv.appendChild(targetDiv);
var animation = targetDiv.getAnimations()[0];
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'CSS animation on an in-view element with pre-transform should not ' +
'be throttled.');
await ensureElementRemoval(scrollDiv);
});
add_task(async function throttling_animations_out_of_view_css_transform() {
var scrollDiv = addDiv(null, { style: 'overflow: scroll;' +
@@ -1524,21 +1514,20 @@ waitForAllPaints(() => {
var parent = addDiv(null, { style: 'overflow: scroll; height: 0px;' });
var target = addDiv(null,
{ style: 'animation: background-color 100s infinite;' +
'position: absolute; top: 50%;' +
'width: 100px; height: 100px;' });
parent.appendChild(target);
var animation = target.getAnimations()[0];
- await animation.ready;
+ await waitForAnimationReadyToRestyle(animation);
- const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
var markers = await observeStyling(5);
- is(markers.length, expectedRestyleCount,
+ is(markers.length, 5,
'Animation on position:absolute element in collapsed element ' +
'should not be throttled');
await ensureElementRemoval(parent);
}
);
add_task(