Bug 1348414 Always snapshot after no more paints are pending if WR is enabled. r=mattwoodrow
authorMason Chang <mchang@mozilla.com>
Wed, 22 Mar 2017 12:20:00 -0700
changeset 349765 f39045b90aa9b12cefbe7842155471fe676be93f
parent 349188 283ca0666c06b05616e23af2f873652c30d54988
child 349766 fabfa956af08398c59db5a2a051035bb36284b74
push id31561
push userkwierso@gmail.com
push dateMon, 27 Mar 2017 21:21:48 +0000
treeherdermozilla-central@a6f35285bd1e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1348414
milestone55.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 1348414 Always snapshot after no more paints are pending if WR is enabled. r=mattwoodrow
layout/tools/reftest/reftest-content.js
widget/GfxInfoBase.cpp
widget/GfxInfoBase.h
widget/nsIGfxInfo.idl
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -19,16 +19,17 @@ const NS_GFXINFO_CONTRACTID = "@mozilla.
 
 // "<!--CLEAR-->"
 const BLANK_URL_FOR_CLEARING = "data:text/html;charset=UTF-8,%3C%21%2D%2DCLEAR%2D%2D%3E";
 
 CU.import("resource://gre/modules/Timer.jsm");
 CU.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm");
 
 var gBrowserIsRemote;
+var gIsWebRenderEnabled;
 var gHaveCanvasSnapshot = false;
 // Plugin layers can be updated asynchronously, so to make sure that all
 // layer surfaces have the right content, we need to listen for explicit
 // "MozPaintWait" and "MozPaintWaitFinished" events that signal when it's OK
 // to take snapshots. We cannot take a snapshot while the number of
 // "MozPaintWait" events fired exceeds the number of "MozPaintWaitFinished"
 // events fired. We count the number of such excess events here. When
 // the counter reaches zero we call gExplicitPendingPaintsCompleteHook.
@@ -1019,16 +1020,25 @@ function SendAssertionCount(numAssertion
 {
     sendAsyncMessage("reftest:AssertionCount", { count: numAssertions });
 }
 
 function SendContentReady()
 {
     let gfxInfo = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo);
     let info = gfxInfo.getInfo();
+
+    // The webrender check has to be separate from the d2d checks
+    // since the d2d checks will throw an exception on non-windows platforms.
+    try {
+        gIsWebRenderEnabled = gfxInfo.WebRenderEnabled;
+    } catch (e) {
+        gIsWebRenderEnabled = false;
+    }
+
     try {
         info.D2DEnabled = gfxInfo.D2DEnabled;
         info.DWriteEnabled = gfxInfo.DWriteEnabled;
     } catch (e) {
         info.D2DEnabled = false;
         info.DWriteEnabled = false;
     }
 
@@ -1126,38 +1136,50 @@ function SendUpdateCanvasForEvent(event,
       if (!gBrowserIsRemote) {
           sendSyncMessage("reftest:UpdateWholeCanvasForInvalidation");
       } else {
           SynchronizeForSnapshot(SYNC_ALLOW_DISABLE);
           sendAsyncMessage("reftest:UpdateWholeCanvasForInvalidation");
       }
       return;
     }
-    
-    var rectList = event.clientRects;
-    LogInfo("SendUpdateCanvasForEvent with " + rectList.length + " rects");
-    for (var i = 0; i < rectList.length; ++i) {
-        var r = rectList[i];
-        // Set left/top/right/bottom to "device pixel" boundaries
-        var left = Math.floor(roundTo(r.left*scale, 0.001));
-        var top = Math.floor(roundTo(r.top*scale, 0.001));
-        var right = Math.ceil(roundTo(r.right*scale, 0.001));
-        var bottom = Math.ceil(roundTo(r.bottom*scale, 0.001));
-        LogInfo("Rect: " + left + " " + top + " " + right + " " + bottom);
+
+    var message;
+    if (gIsWebRenderEnabled && !windowUtils().isMozAfterPaintPending) {
+        // Webrender doesn't have invalidation, so we just invalidate the whole
+        // screen once we don't have anymore paints pending. This will force
+        // the snapshot.
 
-        rects.push({ left: left, top: top, right: right, bottom: bottom });
+        LogInfo("Webrender enabled, sending update whole canvas for invalidation");
+        message = "reftest:UpdateWholeCanvasForInvalidation";
+    } else {
+        var rectList = event.clientRects;
+        LogInfo("SendUpdateCanvasForEvent with " + rectList.length + " rects");
+        for (var i = 0; i < rectList.length; ++i) {
+            var r = rectList[i];
+            // Set left/top/right/bottom to "device pixel" boundaries
+            var left = Math.floor(roundTo(r.left * scale, 0.001));
+            var top = Math.floor(roundTo(r.top * scale, 0.001));
+            var right = Math.ceil(roundTo(r.right * scale, 0.001));
+            var bottom = Math.ceil(roundTo(r.bottom * scale, 0.001));
+            LogInfo("Rect: " + left + " " + top + " " + right + " " + bottom);
+
+            rects.push({ left: left, top: top, right: right, bottom: bottom });
+        }
+
+        message = "reftest:UpdateCanvasForInvalidation";
     }
 
     // See comments in SendInitCanvasWithSnapshot() re: the split
     // logic here.
     if (!gBrowserIsRemote) {
-        sendSyncMessage("reftest:UpdateCanvasForInvalidation", { rects: rects });
+        sendSyncMessage(message, { rects: rects });
     } else {
         SynchronizeForSnapshot(SYNC_ALLOW_DISABLE);
-        sendAsyncMessage("reftest:UpdateCanvasForInvalidation", { rects: rects });
+        sendAsyncMessage(message, { rects: rects });
     }
 }
 if (content.document.readyState == "complete") {
   // load event has already fired for content, get started
   OnInitialLoad();
 } else {
   addEventListener("load", OnInitialLoad, true);
 }
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -27,16 +27,17 @@
 #include "nsTArray.h"
 #include "nsXULAppAPI.h"
 #include "nsIXULAppInfo.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/gfx/Logging.h"
+#include "mozilla/gfx/gfxVars.h"
 #include "MediaPrefs.h"
 #include "gfxPrefs.h"
 #include "gfxPlatform.h"
 #include "gfxConfig.h"
 #include "DriverCrashGuard.h"
 
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
@@ -1435,16 +1436,23 @@ GfxInfoBase::GetActiveCrashGuards(JSCont
       return;
     }
   });
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+GfxInfoBase::GetWebRenderEnabled(bool* aWebRenderEnabled)
+{
+  *aWebRenderEnabled = gfxVars::UseWebRender();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 GfxInfoBase::GetContentBackend(nsAString & aContentBackend)
 {
   BackendType backend = gfxPlatform::GetPlatform()->GetDefaultContentBackend();
   nsString outStr;
 
   switch (backend) {
   case BackendType::DIRECT2D1_1: {
     outStr.AppendPrintf("Direct2D 1.1");
--- a/widget/GfxInfoBase.h
+++ b/widget/GfxInfoBase.h
@@ -56,16 +56,17 @@ public:
   NS_IMETHOD GetFailures(uint32_t *failureCount, int32_t** indices, char ***failures) override;
   NS_IMETHOD_(void) LogFailure(const nsACString &failure) override;
   NS_IMETHOD GetInfo(JSContext*, JS::MutableHandle<JS::Value>) override;
   NS_IMETHOD GetFeatures(JSContext*, JS::MutableHandle<JS::Value>) override;
   NS_IMETHOD GetFeatureLog(JSContext*, JS::MutableHandle<JS::Value>) override;
   NS_IMETHOD GetActiveCrashGuards(JSContext*, JS::MutableHandle<JS::Value>) override;
   NS_IMETHOD GetContentBackend(nsAString & aContentBackend) override;
   NS_IMETHOD GetUsingGPUProcess(bool *aOutValue) override;
+  NS_IMETHOD GetWebRenderEnabled(bool* aWebRenderEnabled) override;
 
   // Initialization function. If you override this, you must call this class's
   // version of Init first.
   // We need Init to be called separately from the constructor so we can
   // register as an observer after all derived classes have been constructed
   // and we know we have a non-zero refcount.
   // Ideally, Init() would be void-return, but the rules of
   // NS_GENERIC_FACTORY_CONSTRUCTOR_INIT require it be nsresult return.
--- a/widget/nsIGfxInfo.idl
+++ b/widget/nsIGfxInfo.idl
@@ -18,16 +18,17 @@ interface nsIGfxInfo : nsISupports
   readonly attribute boolean usingGPUProcess;
   readonly attribute DOMString DWriteVersion;
   readonly attribute DOMString cleartypeParameters;
 
   /*
    * These are valid across all platforms.
    */
   readonly attribute DOMString ContentBackend;
+  readonly attribute boolean WebRenderEnabled;
 
   // XXX: Switch to a list of devices, rather than explicitly numbering them.
 
   /**
    * The name of the display adapter.
    */
   readonly attribute DOMString adapterDescription;
   readonly attribute DOMString adapterDescription2;