Bug 1442861 - Clear mNeedStyleFlush flag after ProcessPendingRestyles(). r?emilio draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Tue, 06 Mar 2018 06:34:02 +0900
changeset 763361 accd33b1268c88f772f0cdbdb9c18c0f0b8075bc
parent 763109 51200c0fdaddb2749549a82596da5323a4cbd499
push id101430
push userhikezoe@mozilla.com
push dateMon, 05 Mar 2018 21:34:23 +0000
reviewersemilio
bugs1442861
milestone60.0a1
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
dom/base/test/file_domwindowutils_animation.html
layout/base/PresShell.cpp
--- 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) {