Bug 1510026 - Send a sync IPC round-trip to the compositor after every crashtest. r=mattwoodrow
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 27 Nov 2018 19:46:23 +0000
changeset 504812 2d25f33db080c14c8058a8e10c394a9139a9ea42
parent 504811 cd420001c8ea7a9bb54ae85e95d9fad271ebfcf7
child 504813 f2de4c97890147585a46ba5fad12cdf5244a54b1
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1510026
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1510026 - Send a sync IPC round-trip to the compositor after every crashtest. r=mattwoodrow This sends a sync IPC message to the compositor after each crashtest, to ensure that any stuff inflight in the compositor settles down. In particular this should round-trip through all of the relevant compositor threads (i.e. for WebRender it should ensure the scene builder, render backend, and renderer threads all get flushed). Differential Revision: https://phabricator.services.mozilla.com/D13033
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/tools/reftest/reftest-content.js
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -282,16 +282,29 @@ nsDOMWindowUtils::GetWebRenderBridge()
         return wrlm->WrBridge();
       }
     }
   }
   return nullptr;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::SyncFlushCompositor()
+{
+  if (nsIWidget* widget = GetWidget()) {
+    if (LayerManager* lm = widget->GetLayerManager()) {
+      if (KnowsCompositor* kc = lm->AsKnowsCompositor()) {
+        kc->SyncWithCompositor();
+      }
+    }
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
 {
   NS_ENSURE_ARG_POINTER(aMode);
   *aMode = 0;
   nsPresContext* presContext = GetPresContext();
   if (presContext) {
     *aMode = presContext->ImageAnimationMode();
     return NS_OK;
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1989,16 +1989,18 @@ interface nsIDOMWindowUtils : nsISupport
   const long MOUSE_BUTTONS_5TH_BUTTON = 0x10;
   // Buttons are not specified, will be calculated from |aButton|.
   const long MOUSE_BUTTONS_NOT_SPECIFIED = -1;
 
   // Return values for getDirectionFromText().
   const long DIRECTION_LTR = 0;
   const long DIRECTION_RTL = 1;
   const long DIRECTION_NOT_SET = 2;
+
+  void syncFlushCompositor();
 };
 
 [scriptable, uuid(c694e359-7227-4392-a138-33c0cc1f15a6)]
 interface nsITranslationNodeList : nsISupports {
   readonly attribute unsigned long length;
   Node item(in unsigned long index);
 
   // A translation root is a block element, or an inline element
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -688,19 +688,17 @@ function WaitForTestEnd(contentRootEleme
             var flushWaiter = function(aSubject, aTopic, aData) {
                 if (aTopic) LogInfo("MakeProgress: apz-repaints-flushed fired");
                 os.removeObserver(flushWaiter, "apz-repaints-flushed");
                 state = STATE_WAITING_TO_FINISH;
                 MakeProgress();
             };
             os.addObserver(flushWaiter, "apz-repaints-flushed");
 
-            var willSnapshot = (gCurrentTestType != TYPE_SCRIPT) &&
-                               (gCurrentTestType != TYPE_LOAD) &&
-                               (gCurrentTestType != TYPE_PRINT);
+            var willSnapshot = IsSnapshottableTestType();
             var noFlush =
                 !(contentRootElement &&
                   contentRootElement.classList.contains("reftest-no-flush"));
             if (noFlush && willSnapshot && windowUtils().flushApzRepaints()) {
                 LogInfo("MakeProgress: done requesting APZ flush");
             } else {
                 LogInfo("MakeProgress: APZ flush not required");
                 flushWaiter(null, null, null);
@@ -749,16 +747,27 @@ function WaitForTestEnd(contentRootEleme
                 for (var i = 0; i < elements.length; ++i) {
                     if (!windowUtils().checkAndClearDisplayListState(elements[i])) {
                         SendFailedDisplayList();
                     }
                 }
               }
               CheckLayerAssertions(contentRootElement);
             }
+
+            if (!IsSnapshottableTestType()) {
+              // If we're not snapshotting the test, at least do a sync round-trip
+              // to the compositor to ensure that all the rendering messages
+              // related to this test get processed. Otherwise problems triggered
+              // by this test may only manifest as failures in a later test.
+              LogInfo("MakeProgress: Doing sync flush to compositor");
+              gFailureReason = "timed out while waiting for sync compositor flush"
+              windowUtils().syncFlushCompositor();
+            }
+
             LogInfo("MakeProgress: Completed");
             state = STATE_COMPLETED;
             gFailureReason = "timed out while taking snapshot (bug in harness?)";
             RemoveListeners();
             CheckForProcessCrashExpectation();
             setTimeout(RecordResult, 0);
             return;
         }
@@ -1089,24 +1098,29 @@ function LogInfo(str)
 {
     if (gVerbose) {
         sendSyncMessage("reftest:Log", { type: "info", msg: str });
     } else {
         sendAsyncMessage("reftest:Log", { type: "info", msg: str });
     }
 }
 
+function IsSnapshottableTestType()
+{
+    // Script, load-only, and PDF-print tests do not need any snapshotting.
+    return !(gCurrentTestType == TYPE_SCRIPT ||
+             gCurrentTestType == TYPE_LOAD ||
+             gCurrentTestType == TYPE_PRINT);
+}
+
 const SYNC_DEFAULT = 0x0;
 const SYNC_ALLOW_DISABLE = 0x1;
 function SynchronizeForSnapshot(flags)
 {
-    if (gCurrentTestType == TYPE_SCRIPT ||
-        gCurrentTestType == TYPE_LOAD ||
-        gCurrentTestType == TYPE_PRINT) {
-        // Script, load-only, and PDF-print tests do not need any snapshotting.
+    if (!IsSnapshottableTestType()) {
         return;
     }
 
     if (flags & SYNC_ALLOW_DISABLE) {
         var docElt = content.document.documentElement;
         if (docElt &&
             (docElt.hasAttribute("reftest-no-sync-layers") ||
              docElt.classList.contains("reftest-no-flush"))) {