Bug 1878361 - Fix animation throttling to properly consider opacity animations on the root of the opacity: 0 subtree. r=boris

We had a test for this but it didn't get to the buggy line because the
opacity animation in the test started at 1. Fixed, and also added a test
for a compositor animation.

Differential Revision: https://phabricator.services.mozilla.com/D201355
This commit is contained in:
Emilio Cobos Álvarez 2024-02-12 04:56:35 +00:00
Родитель 6678244978
Коммит a4f3e104b7
2 изменённых файлов: 23 добавлений и 21 удалений

Просмотреть файл

@ -1341,7 +1341,8 @@ KeyframeEffect::OverflowRegionRefreshInterval() {
return kOverflowRegionRefreshInterval;
}
static bool IsDefinitivelyInvisibleDueToOpacity(const nsIFrame& aFrame) {
static bool CanOptimizeAwayDueToOpacity(const KeyframeEffect& aEffect,
const nsIFrame& aFrame) {
if (!aFrame.Style()->IsInOpacityZeroSubtree()) {
return false;
}
@ -1358,27 +1359,11 @@ static bool IsDefinitivelyInvisibleDueToOpacity(const nsIFrame& aFrame) {
MOZ_ASSERT(root && root->Style()->IsInOpacityZeroSubtree());
// If aFrame is the root of the opacity: zero subtree, we can't prove we can
// optimize it away, because it may have an opacity animation itself.
if (root == &aFrame) {
return false;
}
// Even if we're in an opacity: zero subtree, if the root of the subtree may
// have an opacity animation, we can't optimize us away, as we may become
// visible ourselves.
return !root->HasAnimationOfOpacity();
}
static bool CanOptimizeAwayDueToOpacity(const KeyframeEffect& aEffect,
const nsIFrame& aFrame) {
if (!aFrame.Style()->IsInOpacityZeroSubtree()) {
return false;
}
if (IsDefinitivelyInvisibleDueToOpacity(aFrame)) {
return true;
}
return !aEffect.HasOpacityChange() && !aFrame.HasAnimationOfOpacity();
return (root != &aFrame || !aEffect.HasOpacityChange()) &&
!root->HasAnimationOfOpacity();
}
bool KeyframeEffect::CanThrottleIfNotVisible(nsIFrame& aFrame) const {

Просмотреть файл

@ -36,6 +36,10 @@ SimpleTest.finish = function finish() {
from { opacity: 1; }
to { opacity: 0; }
}
@keyframes opacity-from-zero {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes opacity-without-end-value {
from { opacity: 0; }
}
@ -2191,7 +2195,7 @@ waitForAllPaints(() => {
});
add_task_if_omta_enabled(async function restyling_main_thread_animations_in_opacity_zero_descendant_during_root_opacity_animation() {
const container = addDiv(null, { style: 'opacity: 0; animation: opacity 100s infinite' });
const container = addDiv(null, { style: 'opacity: 0; animation: opacity-from-zero 100s infinite' });
const child = addDiv(null, { style: 'animation: on-main-thread 100s infinite;' });
container.appendChild(child);
@ -2207,6 +2211,19 @@ waitForAllPaints(() => {
await ensureElementRemoval(container);
});
add_task_if_omta_enabled(async function restyling_omt_animations_in_opacity_zero_descendant_during_root_opacity_animation() {
const container = addDiv(null, { style: 'opacity: 0; animation: opacity-from-zero 100s infinite' });
const child = addDiv(null, { style: 'animation: rotate 100s infinite' });
container.appendChild(child);
const animation = child.getAnimations()[0];
await waitForAnimationReadyToRestyle(animation);
ok(SpecialPowers.wrap(animation).isRunningOnCompositor);
await ensureElementRemoval(container);
});
add_task_if_omta_enabled(async function transparent_background_color_animations() {
const div = addDiv(null);
const animation =
@ -2243,7 +2260,7 @@ waitForAllPaints(() => {
await SpecialPowers.spawn(iframe, [MS_PER_SEC], async (MS_PER_SEC) => {
// Create a flex item with "preserve-3d" having an abs-pos child inside
// a grid container.
// These styles make the the flex item size (0x0).
// These styles make the flex item size (0x0).
const gridContainer = content.document.createElement("div");
gridContainer.style.display = "grid";
gridContainer.style.placeItems = "center";