Bug 1442861 - Clear mNeedStyleFlush flag after ProcessPendingRestyles(). r?emilio
mNeedStyleFlush is also set by animation restyle request. So it's possible
that the flag is set again in PostRestyleForThrottledAnimations() or in
sequential tasks for updating animations after the flag is cleared at the top
DoFlushPendingNotifications().
MozReview-Commit-ID: KPSS6cJb4HX
--- a/dom/base/test/file_domwindowutils_animation.html
+++ b/dom/base/test/file_domwindowutils_animation.html
@@ -1,13 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DOMWindowUtils test with animation</title>
+ <script src="/tests/SimpleTest/paint_listener.js"></script>
</head>
<body>
<script type="application/javascript">
const SimpleTest = window.opener.SimpleTest;
const utils = SpecialPowers.getDOMWindowUtils(window);
const next = window.opener.next;
const is = window.opener.is;
@@ -143,18 +144,17 @@ function test_getUnanimatedComputedStyle
is(utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_STYLE),
"0",
"getUnanimatedComputedStyle with FLUSH_STYLE should flush pending styles");
}
div.remove();
- next();
- window.close();
+ test_needsFlushWithThrottledAnimations();
}
function checkUnanimatedComputedStyle(property, initialStyle, pseudoType,
expectedBeforeAnimation,
expectedDuringAnimation,
animate, animationType) {
const div = document.createElement("div");
document.body.appendChild(div);
@@ -178,13 +178,45 @@ function checkUnanimatedComputedStyle(pr
expectedDuringAnimation,
`'${ property }' property with '${ initialStyle }' style `
+ `should be '${ expectedDuringAnimation }' `
+ `even while animating by ${ animationType }`);
div.remove();
}
+function test_needsFlushWithThrottledAnimations() {
+ const div = document.createElement("div");
+ div.style = "width: 100px; height: 100px; background-color: blue;";
+ document.body.appendChild(div);
+
+ const animation = div.animate({ opacity: [ 0, 1 ] },
+ { duration: 100000, iterations: Infinity });
+ animation.ready.then(() => {
+ // Make sure pending styles in the previous test has been already processed.
+ // (I.e. the target element in the test has surely removed.)
+ waitForAllPaintsFlushed(() => {
+ ok(SpecialPowers.wrap(animation).isRunningOnCompositor,
+ "Opacity animation should run on the compositor");
+
+ // FIXME! Bug 1442861: We should make sure needsFlush() returns true
+ // before flusing layout.
+ //ok(utils.needsFlush(SpecialPowers.Ci.nsIDOMWindowUtils.FLUSH_STYLE),
+ // "needsFlush should return true if there is an animation on the compositor");
+
+ // Flush layout.
+ document.documentElement.getBoundingClientRect();
+
+ ok(!utils.needsFlush(SpecialPowers.Ci.nsIDOMWindowUtils.FLUSH_STYLE),
+ "needsFlush should return false after flushing layout");
+
+ div.remove();
+ next();
+ window.close();
+ });
+ });
+}
+
window.addEventListener("load", test_getUnanimatedComputedStyle);
</script>
</body>
</html>
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4230,21 +4230,23 @@ PresShell::DoFlushPendingNotifications(m
nsAutoScriptBlocker scriptBlocker;
#ifdef MOZ_GECKO_PROFILER
AutoProfilerTracing tracingStyleFlush("Paint", "Styles",
Move(mStyleCause));
mStyleCause = nullptr;
#endif
mPresContext->RestyleManager()->ProcessPendingRestyles();
+ // Clear mNeedStyleFlush here agagin to make this flag work properly for
+ // optimization since the flag might have set in ProcessPendingRestyles().
+ mNeedStyleFlush = false;
}
didStyleFlush = true;
-
// There might be more pending constructors now, but we're not going to
// worry about them. They can't be triggered during reflow, so we should
// be good.
if (flushType >= (SuppressInterruptibleReflows()
? FlushType::Layout
: FlushType::InterruptibleLayout) &&
!mIsDestroying) {