Bug 1437272 - Don't throttle transform animations in out-of-view element if the animations are not infinite. r?
MozReview-Commit-ID: HaMjmxqXPIK
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -1452,22 +1452,26 @@ KeyframeEffectReadOnly::CanThrottle() co
// Unless we are newly in-effect, we can throttle the animation if the
// animation is paint only and the target frame is out of view or the document
// is in background tabs.
if (mInEffectOnLastAnimationTimingUpdate && CanIgnoreIfNotVisible()) {
nsIPresShell* presShell = GetPresShell();
if (presShell && !presShell->IsActive()) {
return true;
}
+
if (frame->IsScrolledOutOfView()) {
// If there are transform change hints, unthrottle the animation
// periodically since it might affect the overflow region.
if (mCumulativeChangeHint & (nsChangeHint_UpdatePostTransformOverflow |
nsChangeHint_AddOrRemoveTransform |
nsChangeHint_UpdateTransformLayer)) {
+ if (SpecifiedTiming().ActiveDuration() != TimeDuration::Forever()) {
+ return false;
+ }
return CanThrottleTransformChanges(*frame);
}
return true;
}
}
// First we need to check layer generation and transform overflow
// prior to the property.mIsRunningOnCompositor check because we should
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -409,17 +409,17 @@ waitForAllPaints(() => {
return;
}
await SpecialPowers.pushPrefEnv({ set: [["ui.showHideScrollbars", 1]] });
var parentElement = addDiv(null,
{ style: 'overflow-y: scroll; height: 20px;' });
var div = addDiv(null,
- { style: 'animation: rotate 100s; position: relative; top: 100px;' });
+ { style: 'animation: rotate 100s infinite; position: relative; top: 100px;' });
parentElement.appendChild(div);
var animation = div.getAnimations()[0];
var timeAtStart = document.timeline.currentTime;
ok(!animation.isRunningOnCompositor,
'The transform animation is not running on the compositor');
var markers;
@@ -455,17 +455,17 @@ waitForAllPaints(() => {
await SpecialPowers.pushPrefEnv({ set: [["ui.showHideScrollbars", 1]] });
// Make sure we start from the state right after requestAnimationFrame.
await waitForFrame();
var parentElement = addDiv(null,
{ style: 'overflow-y: scroll; height: 20px;' });
var div = addDiv(null,
- { style: 'animation: rotate 100s; position: relative; top: 100px;' });
+ { style: 'animation: rotate 100s infinite; position: relative; top: 100px;' });
parentElement.appendChild(div);
var animation = div.getAnimations()[0];
var timeAtStart = document.timeline.currentTime;
ok(!animation.isRunningOnCompositor,
'The transform animation is not running on the compositor');
var markers;
@@ -511,41 +511,25 @@ waitForAllPaints(() => {
}
var parentElement = addDiv(null,
{ style: 'overflow: hidden;' });
var div = addDiv(null,
{ style: 'animation: move-in 100s;' });
parentElement.appendChild(div);
var animation = div.getAnimations()[0];
- var timeAtStart = document.timeline.currentTime;
- ok(!animation.isRunningOnCompositor,
- 'The transform animation on out of view element ' +
- 'is not running on the compositor');
+ await animation.ready;
+ ok(!SpecialPowers.wrap(animation).isRunningOnCompositor);
- var markers;
- var now;
- while (true) {
- markers = await observeStyling(1);
- // Check restyle markers until 200ms is elapsed.
- now = document.timeline.currentTime;
- if ((now - timeAtStart) >= 200) {
- break;
- }
-
- is(markers.length, 0,
- 'Transform animation running on out of view element ' +
- 'should be throttled until 200ms is elapsed');
- }
-
- is(markers.length, 1,
- 'Transform animation running on out of view element ' +
- 'should be unthrottled after around 200ms have elapsed. now: ' +
- now + ' start time: ' + timeAtStart);
+ const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
+ var markers = await observeStyling(5);
+ is(markers.length, expectedRestyleCount,
+ 'Finite transform animation running on out of view element ' +
+ 'should never be throttled');
await ensureElementRemoval(parentElement);
}
);
add_task(
async function restyling_out_of_view_transform_animations_in_another_element() {
if (!hasConformantPromiseHandling) {
@@ -556,45 +540,25 @@ waitForAllPaints(() => {
await waitForFrame();
var parentElement = addDiv(null,
{ style: 'overflow: hidden;' });
var div = addDiv(null,
{ style: 'animation: move-in 100s;' });
parentElement.appendChild(div);
var animation = div.getAnimations()[0];
- var timeAtStart = document.timeline.currentTime;
- ok(!animation.isRunningOnCompositor,
- 'The transform animation on out of view element ' +
- 'is not running on the compositor');
+ await animation.ready;
+ ok(!SpecialPowers.wrap(animation).isRunningOnCompositor);
- var markers;
- var now;
- while (true) {
- now = document.timeline.currentTime;
- if ((now - timeAtStart) >= 200) {
- // If the current time has elapsed over 200ms since the animation was
- // created, it means that the animation should have already
- // unthrottled in this tick, let's see what we observe in this tick's
- // restyling process.
- markers = await observeStyling(1);
- break;
- }
-
- markers = await observeStyling(1);
- is(markers.length, 0,
- 'Transform animation running on out of view element ' +
- 'should be throttled until 200ms is elapsed');
- }
-
- is(markers.length, 1,
- 'Transform animation running on out of view element ' +
- 'should be unthrottled after around 200ms have elapsed. now: ' +
- now + ' start time: ' + timeAtStart);
+ const expectedRestyleCount = tweakExpectedRestyleCount(animation, 5);
+ var markers = await observeStyling(5);
+ is(markers.length, expectedRestyleCount,
+ 'Finite transform animation running on 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,
{ style: 'overflow-y: scroll; height: 20px;' });