Merge autoland to mozilla-central. a=merge PRE_TREEWIDE_PRETTIER_FORMAT
authorOana Pop Rus <opoprus@mozilla.com>
Fri, 05 Jul 2019 09:45:22 +0300
changeset 481349 b7030ce607ec56690829e8fb6dbcd27dd54a044c
parent 481305 ac50a7bd09b0a9262eed73f9dee2ffbd0e1a33b2 (current diff)
parent 481348 b367977ca6982996789cb331fda493dd097aa716 (diff)
child 481350 8484541d66d7f30289f295c2f72c79ac660b6560
push id36239
push useropoprus@mozilla.com
push dateFri, 05 Jul 2019 06:46:18 +0000
treeherdermozilla-central@b7030ce607ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone69.0a1
first release with
nightly linux32
b7030ce607ec / 69.0a1 / 20190705064618 / files
nightly linux64
b7030ce607ec / 69.0a1 / 20190705064618 / files
nightly mac
b7030ce607ec / 69.0a1 / 20190705064618 / files
nightly win32
b7030ce607ec / 69.0a1 / 20190705064618 / files
nightly win64
b7030ce607ec / 69.0a1 / 20190705064618 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
build/unix/build-gcc/PR64905.patch
taskcluster/scripts/misc/build-gcc-4.9-linux.sh
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1737,18 +1737,21 @@ pref("extensions.pocket.api", "api.getpo
 pref("extensions.pocket.enabled", true);
 pref("extensions.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4");
 pref("extensions.pocket.site", "getpocket.com");
 
 pref("signon.schemeUpgrades", true);
 pref("signon.privateBrowsingCapture.enabled", true);
 pref("signon.showAutoCompleteFooter", true);
 pref("signon.management.page.enabled", false);
+#ifdef NIGHTLY_BUILD
+// Bug 1563330 tracks shipping this by default.
 pref("signon.showAutoCompleteOrigins", true);
 pref("signon.includeOtherSubdomainsInLookup", true);
+#endif
 pref("signon.management.page.faqURL", "https://lockwise.firefox.com/faq.html");
 pref("signon.management.page.feedbackURL",
      "https://www.surveygizmo.com/s3/5036102/Lockwise-feedback?ver=%VERSION%");
 
 // Enable the "Simplify Page" feature in Print Preview. This feature
 // is disabled by default in toolkit.
 pref("print.use_simplify_page", true);
 
--- a/browser/components/aboutlogins/content/aboutLogins.html
+++ b/browser/components/aboutlogins/content/aboutLogins.html
@@ -13,31 +13,33 @@
     <script type="module" src="chrome://browser/content/aboutlogins/components/login-filter.js"></script>
     <script type="module" src="chrome://browser/content/aboutlogins/components/login-item.js"></script>
     <script type="module" src="chrome://browser/content/aboutlogins/components/login-list.js"></script>
     <script type="module" src="chrome://browser/content/aboutlogins/components/login-list-item.js"></script>
     <script type="module" src="chrome://browser/content/aboutlogins/components/menu-button.js"></script>
     <script type="module" src="chrome://browser/content/aboutlogins/aboutLogins.js"></script>
     <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
     <link rel="stylesheet" href="chrome://browser/content/aboutlogins/aboutLogins.css">
+    <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
     <link rel="icon" href="chrome://browser/content/aboutlogins/icons/favicon.svg">
   </head>
   <body>
     <header>
       <img id="branding-logo" src="chrome://branding/content/aboutlogins.svg" alt=""/>
       <login-filter></login-filter>
       <button id="create-login-button" data-l10n-id="create-login-button"></button>
       <menu-button></menu-button>
     </header>
     <login-list></login-list>
     <login-item></login-item>
     <confirm-delete-dialog hidden></confirm-delete-dialog>
 
     <template id="confirm-delete-dialog-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
+      <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/confirm-delete-dialog.css">
       <div class="overlay">
         <div class="container" role="dialog" aria-labelledby="title" aria-describedby="message">
           <div class="title-bar">
             <h1 class="title" id="title" data-l10n-id="confirm-delete-dialog-title"></h1>
             <button class="dismiss-button" data-l10n-id="confirm-delete-dialog-dismiss-button"></button>
           </div>
           <div class="content">
@@ -48,16 +50,17 @@
             <button class="confirm-button" data-l10n-id="confirm-delete-dialog-confirm-button"></button>
           </div>
         </div>
       </div>
     </template>
 
     <template id="login-list-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
+      <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/login-list.css">
       <div class="meta">
         <label for="login-sort">
           <span data-l10n-id="login-list-sort-label-text"></span>
           <select id="login-sort">
             <option data-l10n-id="login-list-name-option" value="name"/>
             <option data-l10n-id="login-list-last-used-option" value="last-used"/>
             <option data-l10n-id="login-list-last-changed-option" value="last-changed"/>
@@ -66,16 +69,17 @@
         <span class="count" data-l10n-id="login-list-count" data-l10n-args='{"count": 0}'></span>
       </div>
       <ol role="listbox" tabindex="0" data-l10n-id="login-list">
       </ol>
     </template>
 
     <template id="login-list-item-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
+      <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/login-list-item.css">
       <span class="title"></span>
       <span class="username"></span>
     </template>
 
     <template id="login-item-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
@@ -87,17 +91,17 @@
         </h2>
         <button class="edit-button alternate-button" data-l10n-id="login-item-edit-button"></button>
         <button class="delete-button alternate-button" data-l10n-id="login-item-delete-button"></button>
       </div>
       <form>
         <div class="detail-row">
           <label class="detail-cell">
             <span class="origin-label field-label" data-l10n-id="login-item-origin-label"></span>
-            <input type="url" name="origin" required data-l10n-id="login-item-origin"/>
+            <input type="url" name="origin" class="origin-input" required data-l10n-id="login-item-origin"/>
           </label>
           <button class="open-site-button" data-l10n-id="login-item-open-site-button"></button>
         </div>
         <div class="detail-row">
           <label class="detail-cell">
             <span class="username-label field-label" data-l10n-id="login-item-username-label"></span>
             <input type="text" name="username" data-l10n-id="login-item-username"/>
           </label>
@@ -126,16 +130,17 @@
         <p class="time-used meta-info" data-l10n-id="login-item-time-used" data-l10n-args='{"timeUsed": 0}'></p>
         <button class="save-changes-button" data-l10n-id="login-item-save-changes-button"></button>
         <button class="cancel-button" data-l10n-id="login-item-cancel-button"></button>
       </form>
     </template>
 
     <template id="login-filter-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
+      <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/login-filter.css">
       <input data-l10n-id="login-filter" class="filter" type="text"/>
     </template>
 
     <template id="menu-button-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/menu-button.css">
--- a/browser/components/aboutlogins/content/aboutLogins.js
+++ b/browser/components/aboutlogins/content/aboutLogins.js
@@ -13,24 +13,23 @@ document.addEventListener("DOMContentLoa
   gElements.newLoginButton = document.querySelector("#create-login-button");
 
   let {searchParams} = new URL(document.location);
   if (searchParams.get("filter")) {
     gElements.loginFilter.value = searchParams.get("filter");
   }
 
   gElements.newLoginButton.addEventListener("click", () => {
-    window.dispatchEvent(new CustomEvent("AboutLoginsLoginSelected", {
-      detail: {},
-    }));
-
+    window.dispatchEvent(new CustomEvent("AboutLoginsCreateLogin"));
     recordTelemetryEvent({object: "new_login", method: "new"});
   });
 
   document.dispatchEvent(new CustomEvent("AboutLoginsInit", {bubbles: true}));
+
+  gElements.loginFilter.focus();
 }, {once: true});
 
 window.addEventListener("AboutLoginsChromeToContent", event => {
   switch (event.detail.messageType) {
     case "AllLogins": {
       gElements.loginList.setLogins(event.detail.value);
       break;
     }
--- a/browser/components/aboutlogins/content/components/login-filter.js
+++ b/browser/components/aboutlogins/content/components/login-filter.js
@@ -15,16 +15,20 @@ export default class LoginFilter extends
     document.l10n.connectRoot(shadowRoot);
     shadowRoot.appendChild(loginFilterTemplate.content.cloneNode(true));
 
     this._input = this.shadowRoot.querySelector("input");
 
     this.addEventListener("input", this);
   }
 
+  focus() {
+    this._input.focus();
+  }
+
   handleEvent(event) {
     switch (event.type) {
       case "input": {
         this._dispatchFilterEvent(event.originalTarget.value);
         break;
       }
     }
   }
--- a/browser/components/aboutlogins/content/components/login-item.css
+++ b/browser/components/aboutlogins/content/components/login-item.css
@@ -71,16 +71,30 @@
   padding-inline-start: 30px; /* 8px on each side, and 14px for icon width */
 }
 
 .edit-button {
   background-image: url("chrome://browser/content/aboutlogins/icons/edit.svg");
   padding-inline-start: 32px; /* 8px on each side, and 16px for icon width */
 }
 
+:host(:not([data-editing])) input[type="url"] {
+  color: var(--in-content-link-color) !important;
+  cursor: pointer;
+}
+
+:host(:not([data-editing])) input[type="url"]:hover {
+  color: var(--in-content-link-color-hover) !important;
+  text-decoration: underline;
+}
+
+:host(:not([data-editing])) input[type="url"]:hover:active {
+  color: var(--in-content-link-color-active) !important;
+}
+
 .detail-row,
 .reveal-password-wrapper {
   display: flex;
   align-items: center;
 }
 
 .detail-row {
   margin-bottom: 20px;
@@ -107,16 +121,21 @@
 }
 
 .copy-button[data-copied] {
   color: var(--success-color) !important; /* override common.css */
   background-color: transparent;
   opacity: 1; /* override common.css fading out disabled buttons */
 }
 
+.copy-button[data-copied]:-moz-focusring {
+  outline-width: 0;
+  box-shadow: none;
+}
+
 .meta-info {
   font-size: smaller;
 }
 
 .meta-info:first-of-type {
   padding-top: 1em;
   border-top: 1px solid var(--in-content-box-border-color);
   width: 40px;
--- a/browser/components/aboutlogins/content/components/login-item.js
+++ b/browser/components/aboutlogins/content/components/login-item.js
@@ -24,48 +24,47 @@ export default class LoginItem extends H
       return;
     }
 
     let loginItemTemplate = document.querySelector("#login-item-template");
     let shadowRoot = this.attachShadow({mode: "open"});
     document.l10n.connectRoot(shadowRoot);
     shadowRoot.appendChild(loginItemTemplate.content.cloneNode(true));
 
-    for (let selector of [
-      ".copy-password-button",
-      ".copy-username-button",
-      ".delete-button",
-      ".edit-button",
-      ".open-site-button",
-      ".reveal-password-checkbox",
-      ".save-changes-button",
-      ".cancel-button",
-    ]) {
-      let button = this.shadowRoot.querySelector(selector);
-      button.addEventListener("click", this);
-    }
-
+    this._cancelButton = this.shadowRoot.querySelector(".cancel-button");
     this._confirmDeleteDialog = document.querySelector("confirm-delete-dialog");
     this._copyPasswordButton = this.shadowRoot.querySelector(".copy-password-button");
     this._copyUsernameButton = this.shadowRoot.querySelector(".copy-username-button");
     this._deleteButton = this.shadowRoot.querySelector(".delete-button");
     this._editButton = this.shadowRoot.querySelector(".edit-button");
     this._form = this.shadowRoot.querySelector("form");
+    this._openSiteButton = this.shadowRoot.querySelector(".open-site-button");
     this._originInput = this.shadowRoot.querySelector("input[name='origin']");
     this._usernameInput = this.shadowRoot.querySelector("input[name='username']");
     this._passwordInput = this.shadowRoot.querySelector("input[name='password']");
     this._revealCheckbox = this.shadowRoot.querySelector(".reveal-password-checkbox");
+    this._saveChangesButton = this.shadowRoot.querySelector(".save-changes-button");
     this._title = this.shadowRoot.querySelector(".login-item-title");
     this._timeCreated = this.shadowRoot.querySelector(".time-created");
     this._timeChanged = this.shadowRoot.querySelector(".time-changed");
     this._timeUsed = this.shadowRoot.querySelector(".time-used");
 
     this.render();
 
     this._originInput.addEventListener("blur", this);
+    this._cancelButton.addEventListener("click", this);
+    this._copyPasswordButton.addEventListener("click", this);
+    this._copyUsernameButton.addEventListener("click", this);
+    this._deleteButton.addEventListener("click", this);
+    this._editButton.addEventListener("click", this);
+    this._openSiteButton.addEventListener("click", this);
+    this._originInput.addEventListener("click", this);
+    this._saveChangesButton.addEventListener("click", this);
+    window.addEventListener("AboutLoginsCreateLogin", this);
+    window.addEventListener("AboutLoginsInitialLoginSelected", this);
     window.addEventListener("AboutLoginsLoginSelected", this);
   }
 
   render() {
     document.l10n.setAttributes(this._timeCreated, "login-item-time-created", {timeCreated: this._login.timeCreated || ""});
     document.l10n.setAttributes(this._timeChanged, "login-item-time-changed", {timeChanged: this._login.timePasswordChanged || ""});
     document.l10n.setAttributes(this._timeUsed, "login-item-time-used", {timeUsed: this._login.timeLastUsed || ""});
 
@@ -73,16 +72,24 @@ export default class LoginItem extends H
     this._originInput.defaultValue = this._login.origin || "";
     this._usernameInput.defaultValue = this._login.username || "";
     this._passwordInput.defaultValue = this._login.password || "";
     this._updatePasswordRevealState();
   }
 
   handleEvent(event) {
     switch (event.type) {
+      case "AboutLoginsCreateLogin": {
+        this.setLogin({});
+        break;
+      }
+      case "AboutLoginsInitialLoginSelected": {
+        this.setLogin(event.detail, {skipFocusChange: true});
+        break;
+      }
       case "AboutLoginsLoginSelected": {
         this.setLogin(event.detail);
         break;
       }
       case "blur": {
         // Add https:// prefix if one was not provided.
         let originValue = this._originInput.value.trim();
         if (!originValue) {
@@ -101,27 +108,25 @@ export default class LoginItem extends H
           let method = this._revealCheckbox.checked ? "show" : "hide";
           recordTelemetryEvent({object: "password", method});
           return;
         }
 
         // Prevent form submit behavior on the following buttons.
         event.preventDefault();
         if (classList.contains("cancel-button")) {
-          if (this._login.guid) {
+          let wasExistingLogin = !!this._login.guid;
+          if (wasExistingLogin) {
             this.setLogin(this._login);
           } else {
-            // TODO, should select the first login if it exists
-            // or show the no-logins view otherwise
-            this._toggleEditing();
-            this.render();
+            window.dispatchEvent(new CustomEvent("AboutLoginsClearSelection"));
           }
 
           recordTelemetryEvent({
-            object: this._login.guid ? "existing_login" : "new_login",
+            object: wasExistingLogin ? "existing_login" : "new_login",
             method: "cancel",
           });
           return;
         }
         if (classList.contains("copy-password-button") ||
             classList.contains("copy-username-button")) {
           let copyButton = event.currentTarget;
           copyButton.disabled = true;
@@ -142,17 +147,18 @@ export default class LoginItem extends H
           return;
         }
         if (classList.contains("edit-button")) {
           this._toggleEditing();
 
           recordTelemetryEvent({object: "existing_login", method: "edit"});
           return;
         }
-        if (classList.contains("open-site-button")) {
+        if (classList.contains("open-site-button") ||
+            (classList.contains("origin-input") && !this.dataset.editing)) {
           document.dispatchEvent(new CustomEvent("AboutLoginsOpenSite", {
             bubbles: true,
             detail: this._login,
           }));
 
           recordTelemetryEvent({object: "existing_login", method: "open_site"});
           return;
         }
@@ -196,32 +202,37 @@ export default class LoginItem extends H
       }));
       recordTelemetryEvent({object: "existing_login", method: "delete"});
     }, () => {});
   }
 
   /**
    * @param {login} login The login that should be displayed. The login object is
    *                      a plain JS object representation of nsILoginInfo/nsILoginMetaInfo.
+   * @param {boolean} skipFocusChange Optional, if present and set to true, the Edit button of the
+   *                                  login will not get focus automatically. This is used to prevent
+   *                                  stealing focus from the search filter upon page load.
    */
-  setLogin(login) {
+  setLogin(login, {skipFocusChange} = {}) {
     this._login = login;
 
     this._form.reset();
 
     if (login.guid) {
       delete this.dataset.isNewLogin;
     } else {
       this.dataset.isNewLogin = true;
     }
     this._toggleEditing(!login.guid);
 
     this._revealCheckbox.checked = false;
 
-    this._editButton.focus();
+    if (!skipFocusChange) {
+      this._editButton.focus();
+    }
     this.render();
   }
 
   /**
    * Updates the view if the login argument matches the login currently
    * displayed.
    *
    * @param {login} login The login that was added to storage. The login object is
--- a/browser/components/aboutlogins/content/components/login-list-item.js
+++ b/browser/components/aboutlogins/content/components/login-list-item.js
@@ -50,16 +50,20 @@ export default class LoginListItem exten
     } else {
       document.l10n.setAttributes(this._username, "login-list-item-subtitle-missing-username");
     }
   }
 
   handleEvent(event) {
     switch (event.type) {
       case "click": {
+        if (!this._login.guid) {
+          return;
+        }
+
         this.dispatchEvent(new CustomEvent("AboutLoginsLoginSelected", {
           bubbles: true,
           composed: true,
           detail: this._login,
         }));
 
         recordTelemetryEvent({object: "existing_login", method: "select"});
       }
--- a/browser/components/aboutlogins/content/components/login-list.js
+++ b/browser/components/aboutlogins/content/components/login-list.js
@@ -24,43 +24,53 @@ export default class LoginList extends H
     if (this.shadowRoot) {
       return;
     }
     let loginListTemplate = document.querySelector("#login-list-template");
     let shadowRoot = this.attachShadow({mode: "open"});
     document.l10n.connectRoot(shadowRoot);
     shadowRoot.appendChild(loginListTemplate.content.cloneNode(true));
 
+    this._count = this.shadowRoot.querySelector(".count");
     this._list = this.shadowRoot.querySelector("ol");
-    this._count = this.shadowRoot.querySelector(".count");
+    this._sortSelect = this.shadowRoot.querySelector("#login-sort");
 
     this.render();
 
     this.shadowRoot.getElementById("login-sort")
                    .addEventListener("change", this);
+    window.addEventListener("AboutLoginsClearSelection", this);
+    window.addEventListener("AboutLoginsCreateLogin", this);
+    window.addEventListener("AboutLoginsInitialLoginSelected", this);
     window.addEventListener("AboutLoginsLoginSelected", this);
     window.addEventListener("AboutLoginsFilterLogins", this);
     this.addEventListener("keydown", this);
   }
 
-  render() {
+  /**
+   *
+   * @param {object} options optional
+   *                         createLogin: When set to true will show and select
+   *                                      a blank login-list-item.
+   */
+  render(options = {}) {
     this._list.textContent = "";
 
+    if (options.createLogin) {
+      this._blankLoginListItem.classList.add("selected");
+      this._blankLoginListItem.setAttribute("aria-selected", "true");
+      this._list.setAttribute("aria-activedescendant", this._blankLoginListItem.id);
+      this._list.append(this._blankLoginListItem);
+    }
+
     if (!this._logins.length) {
       document.l10n.setAttributes(this._count, "login-list-count", {count: 0});
       return;
     }
 
-    if (!this._selectedGuid) {
-      this._blankLoginListItem.classList.add("selected");
-      this._blankLoginListItem.setAttribute("aria-selected", "true");
-      this._list.setAttribute("aria-activedescendant", this._blankLoginListItem.id);
-      this._list.append(this._blankLoginListItem);
-    }
-
     for (let login of this._logins) {
       let listItem = new LoginListItem(login);
       if (login.guid == this._selectedGuid) {
         listItem.classList.add("selected");
         listItem.setAttribute("aria-selected", "true");
         this._list.setAttribute("aria-activedescendant", listItem.id);
       }
       this._list.append(listItem);
@@ -68,48 +78,77 @@ export default class LoginList extends H
 
     let visibleLoginCount = this._applyFilter();
     document.l10n.setAttributes(this._count, "login-list-count", {count: visibleLoginCount});
   }
 
   handleEvent(event) {
     switch (event.type) {
       case "change": {
-        const sort = event.target.value;
+        const sort = this._sortSelect.value;
         this._logins = this._logins.sort((a, b) => sortFnOptions[sort](a, b));
         this.render();
         break;
       }
+      case "AboutLoginsClearSelection": {
+        if (!this._logins.length) {
+          return;
+        }
+        window.dispatchEvent(new CustomEvent("AboutLoginsLoginSelected", {
+          detail: this._logins[0],
+        }));
+        break;
+      }
+      case "AboutLoginsCreateLogin": {
+        this._selectedGuid = null;
+        this.render({createLogin: true});
+        break;
+      }
       case "AboutLoginsFilterLogins": {
         this._filter = event.detail.toLocaleLowerCase();
         this.render();
         break;
       }
+      case "AboutLoginsInitialLoginSelected":
       case "AboutLoginsLoginSelected": {
         if (this._selectedGuid == event.detail.guid) {
           return;
         }
 
-        this._selectedGuid = event.detail.guid || null;
+        this._selectedGuid = event.detail.guid;
         this.render();
         break;
       }
       case "keydown": {
         this._handleKeyboardNav(event);
         break;
       }
     }
   }
 
   /**
    * @param {login[]} logins An array of logins used for displaying in the list.
    */
   setLogins(logins) {
     this._logins = logins;
+    const sort = this._sortSelect.value;
+    this._logins = this._logins.sort((a, b) => sortFnOptions[sort](a, b));
+
     this.render();
+
+    if (!this._selectedGuid ||
+        !this._logins.findIndex(login => login.guid == this._selectedGuid) != -1) {
+      // Select the first visible login after any possible filter is applied.
+      let firstVisibleLogin = this._list.querySelector("login-list-item[data-guid]:not([hidden])");
+      if (firstVisibleLogin) {
+        window.dispatchEvent(new CustomEvent("AboutLoginsInitialLoginSelected", {
+          detail: firstVisibleLogin._login,
+        }));
+      }
+    }
   }
 
   /**
    * @param {login} login A login that was added to storage.
    */
   loginAdded(login) {
     this._logins.push(login);
     this.render();
--- a/browser/components/aboutlogins/tests/browser/browser_aaa_eventTelemetry_run_first.js
+++ b/browser/components/aboutlogins/tests/browser/browser_aaa_eventTelemetry_run_first.js
@@ -13,16 +13,20 @@ function waitForTelemetryEventCount(coun
   }, "waiting for telemetry event count of: " + count);
 }
 
 add_task(async function setup() {
   let storageChangedPromised = TestUtils.topicObserved("passwordmgr-storage-changed",
                                                        (_, data) => data == "addLogin");
   TEST_LOGIN1 = Services.logins.addLogin(TEST_LOGIN1);
   await storageChangedPromised;
+  storageChangedPromised = TestUtils.topicObserved("passwordmgr-storage-changed",
+                                                   (_, data) => data == "addLogin");
+  TEST_LOGIN2 = Services.logins.addLogin(TEST_LOGIN2);
+  await storageChangedPromised;
   await BrowserTestUtils.openNewForegroundTab({gBrowser, url: "about:logins"});
   registerCleanupFunction(() => {
     BrowserTestUtils.removeTab(gBrowser.selectedTab);
     Services.logins.removeAllLogins();
   });
 });
 
 add_task(async function test_telemetry_events() {
@@ -30,17 +34,17 @@ add_task(async function test_telemetry_e
     Services.telemetry.clearEvents();
     let events = Services.telemetry.snapshotEvents(
       Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, true).content;
     return !events || !events.length;
   }, "Waiting for telemetry events to get cleared");
 
   await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
     let loginList = content.document.querySelector("login-list");
-    let loginListItem = loginList.shadowRoot.querySelector("login-list-item[data-guid]");
+    let loginListItem = loginList.shadowRoot.querySelector("login-list-item:nth-child(2)");
     loginListItem.click();
   });
   await waitForTelemetryEventCount(1);
 
   await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
     let loginItem = content.document.querySelector("login-item");
     let copyButton = loginItem.shadowRoot.querySelector(".copy-username-button");
     copyButton.click();
--- a/browser/components/aboutlogins/tests/browser/browser_openFiltered.js
+++ b/browser/components/aboutlogins/tests/browser/browser_openFiltered.js
@@ -29,20 +29,27 @@ add_task(async function test_query_param
     LoginHelper.loginToVanillaObject(TEST_LOGIN2),
   ];
   await ContentTask.spawn(browser, vanillaLogins, async (logins) => {
     let loginList = Cu.waiveXrays(content.document.querySelector("login-list"));
     await ContentTaskUtils.waitForCondition(() => {
       return loginList._logins.length == 2;
     }, "Waiting for logins to be cached");
 
-    let loginFilter = Cu.waiveXrays(content.document.querySelector("login-filter"));
-    is(loginFilter.value, logins[0].origin, "The filter should be prepopulated");
+    let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
+    await ContentTaskUtils.waitForCondition(() => loginItem._login.guid == logins[0].guid,
+      "Waiting for TEST_LOGIN1 to be selected for the login-item view");
+
+    let loginFilter = content.document.querySelector("login-filter");
+    let xRayLoginFilter = Cu.waiveXrays(loginFilter);
+    is(xRayLoginFilter.value, logins[0].origin, "The filter should be prepopulated");
+    is(content.document.activeElement, loginFilter, "login-filter should be focused");
+    is(loginFilter.shadowRoot.activeElement, loginFilter.shadowRoot.querySelector(".filter"),
+      "the actual input inside of login-filter should be focused");
 
     let hiddenLoginListItems = loginList.shadowRoot.querySelectorAll("login-list-item[hidden]");
     let visibleLoginListItems = loginList.shadowRoot.querySelectorAll("login-list-item:not([hidden])");
-    is(visibleLoginListItems.length, 2, "The 'new' login and one login should be visible");
-    ok(!visibleLoginListItems[0].dataset.guid, "The 'new' login should be visible");
-    is(visibleLoginListItems[1].dataset.guid, logins[0].guid, "TEST_LOGIN1 should be visible");
+    is(visibleLoginListItems.length, 1, "The one login should be visible");
+    is(visibleLoginListItems[0].dataset.guid, logins[0].guid, "TEST_LOGIN1 should be visible");
     is(hiddenLoginListItems.length, 1, "One login should be hidden");
     is(hiddenLoginListItems[0].dataset.guid, logins[1].guid, "TEST_LOGIN2 should be hidden");
   });
 });
--- a/browser/components/aboutlogins/tests/chrome/test_login_item.html
+++ b/browser/components/aboutlogins/tests/chrome/test_login_item.html
@@ -107,30 +107,26 @@ add_task(async function test_edit_login(
     is(event.detail.password, "newPassword", "event should include new password");
     updateEventDispatched = true;
   }, {once: true});
   gLoginItem.shadowRoot.querySelector(".save-changes-button").click();
   ok(updateEventDispatched, "Clicking the .save-changes-button should dispatch the AboutLoginsUpdateLogin event");
 });
 
 add_task(async function test_edit_login_cancel() {
-  for (let login of [{}, TEST_LOGIN_1]) {
-    let isNewLogin = !login.username;
-    info("Testing with" + (isNewLogin ? "out" : "") + " a login");
-    gLoginItem.setLogin(login);
-    gLoginItem.shadowRoot.querySelector(".edit-button").click();
+  gLoginItem.setLogin(TEST_LOGIN_1);
+  gLoginItem.shadowRoot.querySelector(".edit-button").click();
 
-    ok(gLoginItem.dataset.editing, "loginItem should be in 'edit' mode");
-    is(!!gLoginItem.dataset.isNewLogin, isNewLogin,
-       "loginItem should " + (isNewLogin ? "" : "not ") + "be in 'isNewLogin' mode");
+  ok(gLoginItem.dataset.editing, "loginItem should be in 'edit' mode");
+  is(!!gLoginItem.dataset.isNewLogin, false,
+     "loginItem should not be in 'isNewLogin' mode");
 
-    gLoginItem.shadowRoot.querySelector(".cancel-button").click();
-    ok(!gLoginItem.dataset.editing, "loginItem should not be in 'edit' mode");
-    ok(!gLoginItem.dataset.isNewLogin, "loginItem should not be in 'isNewLogin' mode");
-  }
+  gLoginItem.shadowRoot.querySelector(".cancel-button").click();
+  ok(!gLoginItem.dataset.editing, "loginItem should not be in 'edit' mode");
+  ok(!gLoginItem.dataset.isNewLogin, "loginItem should not be in 'isNewLogin' mode");
 });
 
 add_task(async function test_reveal_password_change_selected_login() {
   gLoginItem.setLogin(TEST_LOGIN_1);
   let revealCheckbox = gLoginItem.shadowRoot.querySelector(".reveal-password-checkbox");
 
   ok(!revealCheckbox.checked, "reveal-checkbox should not be checked by default");
   revealCheckbox.click();
--- a/browser/components/aboutlogins/tests/chrome/test_login_list.html
+++ b/browser/components/aboutlogins/tests/chrome/test_login_list.html
@@ -121,39 +121,36 @@ add_task(async function test_keyboard_na
 add_task(async function test_empty_login_username_in_list() {
   // Clear the selection so the 'new' login will be in the list too.
   window.dispatchEvent(new CustomEvent("AboutLoginsLoginSelected", {
     detail: {},
   }));
 
   gLoginList.setLogins([TEST_LOGIN_3]);
   let loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
-  is(loginListItems.length, 2, "A blank login and the one stored login should be displayed");
-  ok(!loginListItems[0].dataset.guid, "first login-list-item should be the 'new' item");
-  is(loginListItems[1].dataset.guid, TEST_LOGIN_3.guid, "login-list-item should have correct guid attribute");
+  is(loginListItems.length, 1, "The one stored login should be displayed");
+  is(loginListItems[0].dataset.guid, TEST_LOGIN_3.guid, "login-list-item should have correct guid attribute");
 
-  loginListItems[1].render();
-  let loginUsername = loginListItems[1].shadowRoot.querySelector(".username");
+  loginListItems[0].render();
+  let loginUsername = loginListItems[0].shadowRoot.querySelector(".username");
   is(loginUsername.getAttribute("data-l10n-id"), "login-list-item-subtitle-missing-username", "login should show missing username text");
 });
 
 add_task(async function test_populated_list() {
   gLoginList.setLogins([TEST_LOGIN_1, TEST_LOGIN_2]);
   let loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
-  is(loginListItems.length, 3, "A blank login and the two stored logins should be displayed");
-  ok(!loginListItems[0].dataset.guid, "first login-list-item should be the 'new' item");
-  is(loginListItems[1].dataset.guid, TEST_LOGIN_1.guid, "login-list-item should have correct guid attribute");
-  is(loginListItems[1].shadowRoot.querySelector(".title").textContent, TEST_LOGIN_1.title,
+  is(loginListItems.length, 2, "The two stored logins should be displayed");
+  is(loginListItems[0].dataset.guid, TEST_LOGIN_1.guid, "login-list-item should have correct guid attribute");
+  is(loginListItems[0].shadowRoot.querySelector(".title").textContent, TEST_LOGIN_1.title,
      "login-list-item origin should match");
-  is(loginListItems[1].shadowRoot.querySelector(".username").textContent, TEST_LOGIN_1.username,
+  is(loginListItems[0].shadowRoot.querySelector(".username").textContent, TEST_LOGIN_1.username,
      "login-list-item username should match");
   ok(loginListItems[0].classList.contains("selected"), "The first item should be selected by default");
   ok(!loginListItems[1].classList.contains("selected"), "The second item should not be selected by default");
-  ok(!loginListItems[2].classList.contains("selected"), "The third item should not be selected by default");
-  loginListItems[1].click();
+  loginListItems[0].click();
   loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
   is(loginListItems.length, 2, "After selecting one, only the two stored logins should be displayed");
   ok(loginListItems[0].classList.contains("selected"), "The first item should be selected");
   ok(!loginListItems[1].classList.contains("selected"), "The second item should still not be selected");
 });
 
 add_task(async function test_filtered_list() {
   is(gLoginList.shadowRoot.querySelectorAll("login-list-item:not([hidden])").length, 2, "Both logins should be visible");
@@ -269,34 +266,31 @@ add_task(async function test_sorted_list
   // Clear the selection so the 'new' login will be in the list too.
   window.dispatchEvent(new CustomEvent("AboutLoginsLoginSelected", {
     detail: {},
   }));
 
   // sort by last used
   gLoginList.shadowRoot.getElementById("login-sort").selectedIndex = 1;
   let loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
-  is(loginListItems.length, 4, "The list should contain the 'new' login and the three stored logins");
-  ok(!loginListItems[0]._login.guid, "The 'new' login should always be first (last used)");
-  let timeUsed = loginListItems[1]._login.timeLastUsed;
-  let timeUsed2 = loginListItems[2]._login.timeLastUsed;
+  is(loginListItems.length, 3, "The list should contain the three stored logins");
+  let timeUsed = loginListItems[0]._login.timeLastUsed;
+  let timeUsed2 = loginListItems[1]._login.timeLastUsed;
   is(timeUsed2 > timeUsed, true, "Last used login should be displayed at top of list");
 
   // sort by name
   gLoginList.shadowRoot.getElementById("login-sort").selectedIndex = 0;
   loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
-  ok(!loginListItems[0]._login.guid, "The 'new' login should always be first (name)");
-  let title = loginListItems[1]._login.title;
-  let title2 = loginListItems[2]._login.title;
+  let title = loginListItems[0]._login.title;
+  let title2 = loginListItems[1]._login.title;
   is(title.localeCompare(title2), -1, "Logins should be sorted alphabetically by hostname");
 
   // sort by last changed
   gLoginList.shadowRoot.getElementById("login-sort").selectedIndex = 2;
   loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
-  ok(!loginListItems[0]._login.guid, "The 'new' login should always be first (last changed)");
-  let pwChanged = loginListItems[1]._login.timePasswordChanged;
-  let pwChanged2 = loginListItems[2]._login.timePasswordChanged;
+  let pwChanged = loginListItems[0]._login.timePasswordChanged;
+  let pwChanged2 = loginListItems[1]._login.timePasswordChanged;
   is(pwChanged2 > pwChanged, true, "Login with most recently changed password should be displayed at top of list");
 });
 </script>
 
 </body>
 </html>
deleted file mode 100644
--- a/build/unix/build-gcc/PR64905.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- trunk/gcc/lra-eliminations.c	2015/02/04 20:00:48	220415
-+++ trunk/gcc/lra-eliminations.c	2015/02/04 20:02:21	220416
-@@ -182,6 +182,8 @@
-   if (! value
-       && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
-     frame_pointer_needed = 1;
-+  if (!frame_pointer_needed)
-+    REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0;
- }
- 
- /* Map: eliminable "from" register -> its current elimination,
--- a/devtools/docs/getting-started/README.md
+++ b/devtools/docs/getting-started/README.md
@@ -1,5 +1,5 @@
 # Getting started
 
-This section describes [how to create a Bugzilla account](bugzilla.md), [how to build Firefox code locally](build.md), and how to [set up a development profile](development-profile.md), all of which are needed in order to contribute **code** to DevTools.
+This section describes [how to create a Bugzilla account](bugzilla.md), [how to build Firefox code locally](build.md), and how to [set up a development profile](development-profiles.md), all of which are needed in order to contribute **code** to DevTools.
 
 If you want to help, but not necessarily writing code (UX, bugs...), the [contributing](../contributing.html) page can give you helpful pointers.
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -5905,23 +5905,16 @@ nsresult nsDocShell::ForceRefreshURIFrom
 }
 
 NS_IMETHODIMP
 nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
                             int32_t aDelay, bool aMetaRefresh) {
   NS_ENSURE_ARG(aURI);
 
   RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aURI);
-  /* We do need to pass in a referrer, but we don't want it to
-   * be sent to the server.
-   * For most refreshes the current URI is an appropriate
-   * internal referrer
-   */
-  nsCOMPtr<nsIReferrerInfo> referrerInfo =
-      new ReferrerInfo(mCurrentURI, mozilla::net::RP_Unset, false);
   loadState->SetOriginalURI(mCurrentURI);
   loadState->SetResultPrincipalURI(aURI);
   loadState->SetResultPrincipalURIIsSome(true);
   loadState->SetKeepResultPrincipalURIIfSet(true);
 
   // Set the triggering pricipal to aPrincipal if available, or current
   // document's principal otherwise.
   nsCOMPtr<nsIPrincipal> principal = aPrincipal;
@@ -5939,30 +5932,42 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI
 
   loadState->SetPrincipalIsExplicit(true);
 
   /* Check if this META refresh causes a redirection
    * to another site.
    */
   bool equalUri = false;
   nsresult rv = aURI->Equals(mCurrentURI, &equalUri);
+
+  nsCOMPtr<nsIReferrerInfo> referrerInfo;
   if (NS_SUCCEEDED(rv) && (!equalUri) && aMetaRefresh &&
       aDelay <= REFRESH_REDIRECT_TIMER) {
     /* It is a META refresh based redirection within the threshold time
      * we have in mind (15000 ms as defined by REFRESH_REDIRECT_TIMER).
      * Pass a REPLACE flag to LoadURI().
      */
     loadState->SetLoadType(LOAD_NORMAL_REPLACE);
 
-    /* for redirects we mimic HTTP, which passes the
-     *  original referrer
+    /* For redirects we mimic HTTP, which passes the
+     * original referrer.
+     * We will pass in referrer but will not send to server
      */
-    referrerInfo = mReferrerInfo;
+    if (mReferrerInfo) {
+      referrerInfo = static_cast<ReferrerInfo*>(mReferrerInfo.get())
+                         ->CloneWithNewSendReferrer(false);
+    }
   } else {
     loadState->SetLoadType(LOAD_REFRESH);
+    /* We do need to pass in a referrer, but we don't want it to
+     * be sent to the server.
+     * For most refreshes the current URI is an appropriate
+     * internal referrer.
+     */
+    referrerInfo = new ReferrerInfo(mCurrentURI, mozilla::net::RP_Unset, false);
   }
 
   loadState->SetReferrerInfo(referrerInfo);
   loadState->SetLoadFlags(
       nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL);
   loadState->SetFirstParty(true);
 
   /*
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -225,17 +225,17 @@ load 1396466.html
 load 1397795.html
 load 1400701.html
 load 1403377.html
 load 1405771.html
 load 1406109-1.html
 load 1411473.html
 load 1413815.html
 load 1419799.html
-skip-if(!browserIsRemote) pref(dom.disable_open_during_load,false) load 1419902.html # skip on non e10s loads, Bug 1419902
+skip-if(!browserIsRemote) skip-if(geckoview&&webrender) pref(dom.disable_open_during_load,false) load 1419902.html # skip on non e10s loads, Bug 1419902. Bug 1563013 for GV+WR
 load 1422883.html
 load 1428053.html
 load 1441029.html
 load 1445670.html
 load 1449601.html
 load 1458016.html
 load 1459688.html
 load 1460794.html
new file mode 100644
--- /dev/null
+++ b/dom/base/test/iframe_meta_refresh.sjs
@@ -0,0 +1,93 @@
+/*
+* Test server for iframe refresh from meta http-equiv
+*/
+
+const SHARED_KEY="iframe_meta_refresh";
+const DEFAULT_STATE = {'count': 0, 'referrers': []};
+const REFRESH_PAGE =
+"http://example.com/tests/dom/base/test/iframe_meta_refresh.sjs?action=test";
+
+function createContent(refresh) {
+  let metaRefresh = "";
+  let scriptMessage = "";
+
+  if (refresh) {
+    metaRefresh = `<meta http-equiv="refresh" content="0;URL=${REFRESH_PAGE}">`;
+  } else {
+    scriptMessage = `
+      <script>
+          window.addEventListener("load", function() {
+            parent.postMessage("childLoadComplete", "http://mochi.test:8888");
+          }, false);
+      </script>`;
+  }
+
+  return `<!DOCTYPE HTML>
+         <html>
+         <head>
+         <meta charset="utf-8">
+         ${metaRefresh}
+         <title> Test referrer of meta http-equiv refresh</title>
+         </head>
+         <body>
+           ${scriptMessage}
+         </body>
+         </html>`;
+}
+
+function handleRequest(request, response)
+{
+  Components.utils.importGlobalProperties(["URLSearchParams"]);
+  let query = new URLSearchParams(request.queryString);
+
+  let action = query.get("action");
+
+  var referrerLevel = "none";
+  if (request.hasHeader('Referer')) {
+    let referrer = request.getHeader('Referer');
+    if (referrer.indexOf("test_meta_refresh_referrer") > 0) {
+      referrerLevel = "full";
+    } else if (referrer == "http://mochi.test:8888/") {
+      referrerLevel = "origin";
+    }
+  }
+
+  var state = getSharedState(SHARED_KEY);
+  if (state === '') {
+    state = DEFAULT_STATE;
+  } else {
+    state = JSON.parse(state);
+  }
+
+  response.setStatusLine(request.httpVersion, 200, "OK");
+
+  //avoid confusing cache behaviors
+  response.setHeader("Cache-Control", "no-cache", false);
+
+  if (action === 'results') {
+    response.setHeader("Content-Type", "text/plain", false);
+    response.write(JSON.stringify(state));
+    return;
+  }
+
+  if (action === 'reset') {
+    //reset server state
+    setSharedState(SHARED_KEY, JSON.stringify(DEFAULT_STATE));
+    response.write("");
+    return;
+  }
+
+  if (action === 'test') {
+    let load = query.get("load");
+    state.count++;
+    if (state.referrers.indexOf(referrerLevel) < 0) {
+      state.referrers.push(referrerLevel);
+    }
+
+    // Write frame content
+    response.write(createContent(load));
+  }
+
+  setSharedState(SHARED_KEY, JSON.stringify(state));
+  return;
+}
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -208,16 +208,17 @@ support-files =
   iframe_postMessages.html
   test_anonymousContent_style_csp.html^headers^
   file_explicit_user_agent.sjs
   referrer_change_server.sjs
   file_change_policy_redirect.html
   file_bug1198095.js
   file_bug1250148.sjs
   file_bug1268962.sjs
+  iframe_meta_refresh.sjs
   mozbrowser_api_utils.js
   !/dom/security/test/cors/file_CrossSiteXHR_server.sjs
   !/image/test/mochitest/blue.png
   script_bug1238440.js
   intersectionobserver_iframe.html
   intersectionobserver_cross_domain_iframe.html
   intersectionobserver_window.html
   object_bug353334.html
@@ -702,16 +703,17 @@ skip-if = (verify && debug && (os == 'li
 skip-if = (verify && (os == 'win' || os == 'mac'))
 [test_integer_attr_with_leading_zero.html]
 [test_intersectionobservers.html]
 [test_link_prefetch.html]
 skip-if = !e10s # Track Bug 1281415
 [test_link_preload.html]
 [test_link_stylesheet.html]
 [test_messagemanager_targetchain.html]
+[test_meta_refresh_referrer.html]
 [test_meta_viewport0.html]
 [test_meta_viewport1.html]
 [test_meta_viewport2.html]
 [test_meta_viewport3.html]
 [test_meta_viewport4.html]
 [test_meta_viewport5.html]
 [test_meta_viewport6.html]
 [test_meta_viewport7.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_meta_refresh_referrer.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name='referrer' content='origin'>
+  <title>Test for referrer of meta refresh request</title>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+var advance = function() { tests.next(); };
+
+/**
+ * Listen for notifications from the child.
+ */
+window.addEventListener("message", function(event) {
+    if (event.data == "childLoadComplete") {
+      advance();
+    }
+});
+
+var tests = (function*() {
+  var iframe = document.getElementById("testframe");
+
+  // reset counter to make the test pass --repeat test
+  yield reset();
+
+  // load the test frame
+  yield iframe.src =
+    '/tests/dom/base/test/iframe_meta_refresh.sjs?action=test&load=refresh';
+
+  // check the test result
+  yield checkResults(referrerHeaderChecker);
+
+  // complete.
+  SimpleTest.finish();
+})();
+
+function referrerHeaderChecker(results) {
+  var expected = {'count': 2, 'referrers': ['origin', 'none']};
+  is(results.count, expected.count, "Correct number of referrer header");
+  is(results.referrers[0], expected.referrers[0], "Correct load referrer header");
+  is(results.referrers[1], expected.referrers[1], "Correct refresh referrer header");
+
+  advance();
+}
+
+/**
+ * helper to perform an XHR.
+ */
+function doXHR(url, onSuccess, onFail) {
+  var xhr = new XMLHttpRequest();
+  xhr.onload = function () {
+    if (xhr.status == 200) {
+      onSuccess(xhr);
+    } else {
+      onFail(xhr);
+    }
+  };
+  xhr.open('GET', url, true);
+  xhr.send(null);
+}
+
+/**
+ * Grabs the results via XHR and passes to checker.
+ */
+function checkResults(checker) {
+  doXHR('/tests/dom/base/test/iframe_meta_refresh.sjs?action=results',
+        function(xhr) {
+          checker(JSON.parse(xhr.responseText));
+        },
+        function(xhr) {
+          ok(false, "Can't get results from server.");
+        });
+}
+
+/**
+ * Reset the counter.
+ */
+function reset() {
+  doXHR('/tests/dom/base/test/iframe_meta_refresh.sjs?action=reset',
+    advance,
+    function(xhr) {
+      ok(false, "error in reset state");
+      SimpleTest.finish();
+    });
+}
+
+</script>
+</head>
+
+<body onload="tests.next();">
+  <iframe id="testframe"></iframe>
+
+</body>
+</html></html>
--- a/dom/canvas/crashtests/crashtests.list
+++ b/dom/canvas/crashtests/crashtests.list
@@ -42,16 +42,16 @@ load 1286458-1.html
 load 1296410-1.html
 load 1298576-1.html
 load 1299062-1.html
 load 1305085-1.html
 load 1305312-1.html
 load 1305850.html
 load 1334366-1.html
 load 1334647-1.html
-load 1349067.html
+skip-if(geckoview&&webrender) load 1349067.html # Bug 1563214 for GV+WR
 pref(gfx.offscreencanvas.enabled,true) load 1348976-1.html
 load 1357092.html
 load 1441613.html
 pref(gfx.offscreencanvas.enabled,true) load 1443671.html
 pref(gfx.offscreencanvas.enabled,true) load 1546390.html
 load 1549853.html
 load 1551745.html
--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini
+++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini
@@ -5241,17 +5241,17 @@ subsuite = webgl2-core
 [generated/test_2_conformance2__query__occlusion-query.html]
 subsuite = webgl2-core
 skip-if = (os == 'win')
 [generated/test_2_conformance2__query__query.html]
 subsuite = webgl2-core
 skip-if = (os == 'win')
 [generated/test_2_conformance2__reading__format-r11f-g11f-b10f.html]
 subsuite = webgl2-core
-fail-if = (os == 'mac') || (os == "win" && processor == "aarch64") #aarch64 due to bug 1536182
+fail-if = (os == "win" && processor == "aarch64") #aarch64 due to bug 1536182
 [generated/test_2_conformance2__reading__read-pixels-from-fbo-test.html]
 subsuite = webgl2-core
 skip-if = (os == 'mac') || (os == 'win')
 [generated/test_2_conformance2__reading__read-pixels-from-rgb8-into-pbo-bug.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__reading__read-pixels-into-pixel-pack-buffer.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__reading__read-pixels-pack-parameters.html]
@@ -6849,46 +6849,42 @@ subsuite = webgl2-core
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__copy-texture-cube-map-bug.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__copy-texture-image-luma-format.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__copy-texture-image-same-texture.html]
 subsuite = webgl2-core
 skip-if = (os == 'win')
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__copy-texture-image-webgl-specific.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__copy-texture-image.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__generate-mipmap-with-large-base-level.html]
 subsuite = webgl2-core
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__gl-get-tex-parameter.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__integer-cubemap-specification-order-bug.html]
 subsuite = webgl2-core
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__integer-cubemap-texture-sampling.html]
 subsuite = webgl2-core
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__mipmap-fbo.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__npot-video-sizing.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__origin-clean-conformance-offscreencanvas.html]
 subsuite = webgl2-core
 skip-if = 1
 [generated/test_2_conformance2__textures__misc__tex-3d-mipmap-levels-intel-bug.html]
 subsuite = webgl2-core
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-3d-size-limit.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__tex-base-level-bug.html]
 subsuite = webgl2-core
+fail-if = os == 'mac' && os_version == '10.14' # macosx1014 due to 1563418
 [generated/test_2_conformance2__textures__misc__tex-image-and-sub-image-with-array-buffer-view-sub-source.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__tex-image-with-bad-args-from-dom-elements.html]
 subsuite = webgl2-core
 skip-if = (os == 'win') || (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-image-with-bad-args.html]
 subsuite = webgl2-core
 [generated/test_2_conformance2__textures__misc__tex-image-with-different-data-source.html]
--- a/dom/canvas/test/webgl-conf/mochitest-errata.ini
+++ b/dom/canvas/test/webgl-conf/mochitest-errata.ini
@@ -169,16 +169,18 @@ fail-if = 1
 fail-if = 1
 [generated/test_2_conformance2__textures__svg_image__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html]
 fail-if = 1
 [generated/test_2_conformance2__textures__video__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html]
 fail-if = 1
 [generated/test_2_conformance2__textures__video__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html]
 fail-if = 1
 
+[generated/test_2_conformance2__textures__misc__tex-base-level-bug.html]
+fail-if = os == 'mac' && os_version == '10.14' # macosx1014 due to 1563418
 [generated/test_2_conformance2__textures__misc__tex-unpack-params-with-flip-y-and-premultiply-alpha.html]
 fail-if = 1
 
 ########################################################################
 # Complicated
 
 [generated/test_conformance__context__context-attributes-alpha-depth-stencil-antialias.html]
 # Asserts on linux debug. Crashes on Android.
@@ -268,17 +270,16 @@ skip-if = (os == 'linux') || (os == 'and
 skip-if = (os == 'android')
 [generated/test_2_conformance2__textures__misc__tex-image-with-bad-args-from-dom-elements.html]
 skip-if = (os == 'win') || (os == 'mac')
 [generated/test_2_conformance2__glsl3__tricky-loop-conditions.html]
 fail-if = (os == 'win')
 [generated/test_2_conformance2__rendering__blitframebuffer-outside-readbuffer.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__integer-cubemap-specification-order-bug.html]
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-srgb-mipmap.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-float.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-half_float.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html]
 fail-if = (os == 'mac')
@@ -335,17 +336,16 @@ fail-if = (os == 'mac')
 
 [generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html]
 fail-if = (os == 'mac') || (os == 'win')
 [generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html]
 fail-if = (os == 'mac') || (os == 'win')
 
 [generated/test_2_conformance2__textures__misc__copy-texture-image-same-texture.html]
 skip-if = (os == 'win')
-fail-if = (os == 'mac')
 
 [generated/test_conformance__rendering__rendering-stencil-large-viewport.html]
 fail-if = (os == 'mac') || (verify && debug && (os == 'linux'))
 # 02:52:43     INFO -  GECKO(1000) | JavaScript warning: http://mochi.test:8888/tests/dom/canvas/test/webgl-conf/checkout/conformance/rendering/rendering-stencil-large-viewport.html, line 85: Error: WebGL warning: Requested size 32767x32767 was too large, but resize to 16383x16383 succeeded.
 # 02:52:43     INFO -  GECKO(1000) | JavaScript warning: http://mochi.test:8888/tests/dom/canvas/test/webgl-conf/checkout/conformance/rendering/rendering-stencil-large-viewport.html, line 85: Error: WebGL warning: drawArrays: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once)
 # 02:52:43     INFO -  GECKO(1000) | MEMORY STAT | vsize 945MB | vsizeMaxContiguous 98MB | residentFast 211MB | heapAllocated 42MB
 # 02:52:43     INFO -  GECKO(1000) | ERR: rx::SwapChain11::resetOffscreenColorBuffer(268): Could not create offscreen texture, 0x0505
 # 02:52:43     INFO -  GECKO(1000) | JavaScript warning: , line 0: Error: WebGL warning: screen->Resize failed. Losing context.
@@ -641,32 +641,31 @@ skip-if = (os == 'mac')
 [generated/test_conformance__rendering__multisample-corruption.html]
 # application crashed [@ gldAttachDrawable + 0x9e0]. Also crash on Android.
 skip-if = (os == 'mac') || (os == 'android') || (os == 'win')
 [generated/test_2_conformance__textures__misc__copy-tex-image-2d-formats.html]
 # Assertion: ""GFX: We should have caught all other errors"" in WebGLTextureUpload.cpp
 skip-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__generate-mipmap-with-large-base-level.html]
 # getError expected: NO_ERROR. Was OUT_OF_MEMORY
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-unpack-params-imagedata.html]
 # areArraysEqual(actual, expected) should be true. Was false.
 fail-if = (os == 'mac')
 
 ####################
 # failure on OSX
 [generated/test_2_conformance2__renderbuffers__multisampled-depth-renderbuffer-initialization.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-unpack-params.html]
 skip-if = (os == 'mac' && debug)
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__glsl3__valid-invariant.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__reading__format-r11f-g11f-b10f.html]
-fail-if = (os == 'mac') || (os == "win" && processor == "aarch64") #aarch64 due to bug 1536182
+fail-if = (os == "win" && processor == "aarch64") #aarch64 due to bug 1536182
 [generated/test_2_conformance2__rendering__blitframebuffer-filter-outofbounds.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__rendering__blitframebuffer-filter-srgb.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r11f_g11f_b10f-rgb-float.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r11f_g11f_b10f-rgb-half_float.html]
 fail-if = (os == 'mac')
@@ -800,17 +799,16 @@ fail-if = (os == 'mac')
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__image_data__tex-2d-rg8ui-rg_integer-unsigned_byte.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__image_data__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__image_data__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__integer-cubemap-texture-sampling.html]
-fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-mipmap-levels.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__video__tex-3d-r16f-red-float.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__video__tex-3d-r16f-red-half_float.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__video__tex-3d-r32f-red-float.html]
 fail-if = (os == 'mac')
@@ -889,17 +887,16 @@ fail-if = (os == 'mac')
 [generated/test_2_conformance__textures__webgl_canvas__tex-2d-alpha-alpha-unsigned_byte.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance__textures__webgl_canvas__tex-2d-luminance-luminance-unsigned_byte.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance__textures__webgl_canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html]
 fail-if = (os == 'mac')
 
 [generated/test_2_conformance2__textures__misc__tex-3d-mipmap-levels-intel-bug.html]
-fail-if = (os == 'mac')
 
 [generated/test_2_conformance2__extensions__ext-color-buffer-float.html]
 skip-if = (os == 'mac' && debug)
 [generated/test_2_conformance__limits__gl-line-width.html]
 skip-if = (os == 'mac')
 [generated/test_2_conformance__misc__type-conversion-test.html]
 skip-if = (os == 'mac' && debug)
 
--- a/dom/html/reftests/reftest.list
+++ b/dom/html/reftests/reftest.list
@@ -39,17 +39,17 @@ skip-if(Android) == 649134-2.html 649134
 == image-load-shortcircuit-1.html image-load-shortcircuit-ref.html
 == image-load-shortcircuit-2.html image-load-shortcircuit-ref.html
 
 # Test that image documents taken into account CSS properties like
 # image-orientation when determining the size of the image.
 # (Fuzzy necessary due to pixel-wise comparison of different JPEGs.
 # The vast majority of the fuzziness comes from Linux and WinXP.)
 fuzzy(0-1,0-149) == bug917595-iframe-1.html    bug917595-1-ref.html
-fuzzy(0-3,0-640) fuzzy-if(skiaContent,0-3,0-7544) fuzzy-if(webrender,2-3,3092-7544) == bug917595-exif-rotated.jpg bug917595-pixel-rotated.jpg # bug 1060869
+fuzzy(0-3,0-640) fuzzy-if(skiaContent,0-3,0-7544) fuzzy-if(webrender&&!geckoview,2-3,3092-7544) == bug917595-exif-rotated.jpg bug917595-pixel-rotated.jpg # bug 1060869
 
 # Test support for SVG-as-image in <picture> elements.
 == bug1106522-1.html bug1106522-ref.html
 == bug1106522-2.html bug1106522-ref.html
 
 == href-attr-change-restyles.html href-attr-change-restyles-ref.html
 == figure.html figure-ref.html
 == pre-1.html pre-1-ref.html
--- a/dom/security/ReferrerInfo.cpp
+++ b/dom/security/ReferrerInfo.cpp
@@ -579,16 +579,23 @@ already_AddRefed<nsIReferrerInfo> Referr
 
 already_AddRefed<nsIReferrerInfo> ReferrerInfo::CloneWithNewPolicy(
     uint32_t aPolicy) const {
   RefPtr<ReferrerInfo> copy(new ReferrerInfo(*this));
   copy->mPolicy = aPolicy;
   return copy.forget();
 }
 
+already_AddRefed<nsIReferrerInfo> ReferrerInfo::CloneWithNewSendReferrer(
+    bool aSendReferrer) const {
+  RefPtr<ReferrerInfo> copy(new ReferrerInfo(*this));
+  copy->mSendReferrer = aSendReferrer;
+  return copy.forget();
+}
+
 already_AddRefed<nsIReferrerInfo> ReferrerInfo::CloneWithNewOriginalReferrer(
     nsIURI* aOriginalReferrer) const {
   RefPtr<ReferrerInfo> copy(new ReferrerInfo(*this));
   copy->mOriginalReferrer = aOriginalReferrer;
   return copy.forget();
 }
 
 NS_IMETHODIMP
--- a/dom/security/ReferrerInfo.h
+++ b/dom/security/ReferrerInfo.h
@@ -65,16 +65,20 @@ class ReferrerInfo : public nsIReferrerI
       const Maybe<nsCString>& aComputedReferrer = Maybe<nsCString>());
 
   // create an exact copy of the ReferrerInfo
   already_AddRefed<nsIReferrerInfo> Clone() const;
 
   // create an copy of the ReferrerInfo with new referrer policy
   already_AddRefed<nsIReferrerInfo> CloneWithNewPolicy(uint32_t aPolicy) const;
 
+  // create an copy of the ReferrerInfo with new send referrer
+  already_AddRefed<nsIReferrerInfo> CloneWithNewSendReferrer(
+      bool aSendReferrer) const;
+
   // create an copy of the ReferrerInfo with new original referrer
   already_AddRefed<nsIReferrerInfo> CloneWithNewOriginalReferrer(
       nsIURI* aOriginalReferrer) const;
 
   /*
    * Implements step 3.1 and 3.3 of the Determine request's Referrer algorithm
    * from the Referrer Policy specification.
    *
--- a/gfx/layers/apz/test/reftest/reftest.list
+++ b/gfx/layers/apz/test/reftest/reftest.list
@@ -1,21 +1,21 @@
 # The following tests test the async positioning of the scrollbars.
 # Basic root-frame scrollbar with async scrolling
-fuzzy-if(Android,1-1,1-2) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v.html async-scrollbar-1-v-ref.html
+fuzzy-if(Android,0-1,0-2) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v.html async-scrollbar-1-v-ref.html
 fuzzy-if(Android,0-4,0-5) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h.html async-scrollbar-1-h-ref.html
 fuzzy-if(Android,0-3,0-5) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh.html async-scrollbar-1-vh-ref.html
-fuzzy-if(Android,1-1,1-2) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl-ref.html
+fuzzy-if(Android,0-1,0-2) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl-ref.html
 fuzzy-if(Android,0-4,0-5) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl-ref.html
 fuzzy-if(Android,0-3,0-7) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl-ref.html
 
 # Different async zoom levels. Since the scrollthumb gets async-scaled in the
 # compositor, the border-radius ends of the scrollthumb are going to be a little
 # off, hence the fuzzy-if clauses.
-fuzzy-if(Android,0-54,0-20) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-zoom-1.html async-scrollbar-zoom-1-ref.html
+fuzzy-if(Android,0-54,0-20) skip-if(!Android) pref(apz.allow_zooming,true) fuzzy-if(geckoview&&webrender,0-45,0-214) == async-scrollbar-zoom-1.html async-scrollbar-zoom-1-ref.html
 fuzzy-if(Android,0-45,0-27) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-zoom-2.html async-scrollbar-zoom-2-ref.html
 
 # Test scrollbars working properly with pinch-zooming, i.e. different document resolutions.
 # As above, the end of the scrollthumb won't match perfectly, but the bulk of the scrollbar should be present and identical.
 # On desktop, even more fuzz is needed because thumb scaling is not exactly proportional: making the page twice as long 
 # won't make the thumb exactly twice as short, which is what the test expects. That's fine, as the purpose of the test is
 # to catch more fundamental scrollbar rendering bugs such as the entire track being mispositioned or the thumb being
 # clipped away.
--- a/gfx/tests/reftest/reftest.list
+++ b/gfx/tests/reftest/reftest.list
@@ -14,12 +14,12 @@ fuzzy(0-100,0-30) == 1149923.html 114992
 == 1444904.html 1444904-ref.html
 == 1451168.html 1451168-ref.html
 == 1461313.html 1461313-ref.html
 fuzzy(5-32,21908-26621) fuzzy-if(webrender,0-9,0-100) == 1463802.html 1463802-ref.html
 fuzzy(0-11,0-4) == 1474722.html 1474722-ref.html
 == 1501195.html 1501195-ref.html
 == 1519754.html 1519754-ref.html
 skip-if(!asyncPan) == 1524261.html 1524261-ref.html
-fuzzy-if(webrender,14-14,44-44) == 1524353.html 1524353-ref.html
+fuzzy-if(webrender,14-14,44-81) == 1524353.html 1524353-ref.html
 fuzzy-if(webrender,4-7,25000-36908) == 1523776.html 1523776-ref.html
 == bug1523410-translate-scale-snap.html bug1523410-translate-scale-snap-ref.html
 == 1523080.html 1523080-ref.html
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2606,16 +2606,189 @@ static bool CalculateWrQualifiedPrefValu
   // above to abort early as the pref would have a valid type.
   //  We also don't want those prefs to appear in about:config.
   if (Preferences::HasUserValue(WR_ROLLOUT_PREF_OVERRIDE)) {
     return Preferences::GetBool(WR_ROLLOUT_PREF_OVERRIDE);
   }
   return Preferences::GetBool(WR_ROLLOUT_PREF, WR_ROLLOUT_PREF_DEFAULTVALUE);
 }
 
+static void HardwareTooOldForWR(FeatureState& aFeature) {
+  aFeature.Disable(
+      FeatureStatus::BlockedDeviceTooOld, "Device too old",
+      NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
+}
+
+static void UpdateWRQualificationForNvidia(FeatureState& aFeature,
+    int32_t aDeviceId) {
+  // 0x6c0 is the lowest Fermi device id. Unfortunately some Tesla
+  // devices that don't support D3D 10.1 have higher deviceIDs. They
+  // will be included, but blocked by ANGLE.
+  bool supported = aDeviceId >= 0x6c0;
+
+  if (!supported) {
+    HardwareTooOldForWR(aFeature);
+    return;
+  }
+
+  // Any additional Nvidia checks go here
+}
+
+static void UpdateWRQualificationForAMD(FeatureState& aFeature,
+    int32_t aDeviceId) {
+  // AMD deviceIDs are not very well ordered. This
+  // condition is based off the information in gpu-db
+  bool supported =
+      (aDeviceId >= 0x6600 && aDeviceId < 0x66b0) ||
+      (aDeviceId >= 0x6700 && aDeviceId < 0x6720) ||
+      (aDeviceId >= 0x6780 && aDeviceId < 0x6840) ||
+      (aDeviceId >= 0x6860 && aDeviceId < 0x6880) ||
+      (aDeviceId >= 0x6900 && aDeviceId < 0x6a00) ||
+      (aDeviceId == 0x7300) ||
+      (aDeviceId >= 0x9830 && aDeviceId < 0x9870) ||
+      (aDeviceId >= 0x9900 && aDeviceId < 0x9a00);
+
+  if (!supported) {
+    HardwareTooOldForWR(aFeature);
+    return;
+  }
+
+  // we have a desktop CAYMAN, SI, CIK, VI, or GFX9 device
+  // so treat the device as qualified unless it is not Windows
+  // and not nightly.
+#if !defined(XP_WIN) && !defined(NIGHTLY_BUILD)
+  aFeature.Disable(
+      FeatureStatus::BlockedReleaseChannelAMD,
+      "Release channel and AMD",
+      NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_AMD"));
+#endif  // !XPWIN && !NIGHTLY_BUILD
+}
+
+static void UpdateWRQualificationForIntel(FeatureState& aFeature,
+    int32_t aDeviceId, int32_t aScreenPixels) {
+  const uint16_t supportedDevices[] = {
+      // skylake gt2+
+      0x1912,
+      0x1913,
+      0x1915,
+      0x1916,
+      0x1917,
+      0x191a,
+      0x191b,
+      0x191d,
+      0x191e,
+      0x1921,
+      0x1923,
+      0x1926,
+      0x1927,
+      0x192b,
+      0x1932,
+      0x193b,
+      0x193d,
+
+      // kabylake gt2+
+      0x5912,
+      0x5916,
+      0x5917,
+      0x591a,
+      0x591b,
+      0x591c,
+      0x591d,
+      0x591e,
+      0x5921,
+      0x5926,
+      0x5923,
+      0x5927,
+      0x593b,
+
+      // coffeelake gt2+
+      0x3e91,
+      0x3e92,
+      0x3e96,
+      0x3e98,
+      0x3e9a,
+      0x3e9b,
+      0x3e94,
+      0x3ea0,
+      0x3ea9,
+      0x3ea2,
+      0x3ea6,
+      0x3ea7,
+      0x3ea8,
+      0x3ea5,
+
+      // broadwell gt2+
+      0x1612,
+      0x1616,
+      0x161a,
+      0x161b,
+      0x161d,
+      0x161e,
+      0x1622,
+      0x1626,
+      0x162a,
+      0x162b,
+      0x162d,
+      0x162e,
+      0x1632,
+      0x1636,
+      0x163a,
+      0x163b,
+      0x163d,
+      0x163e,
+
+      // HD Graphics 4600
+      0x0412,
+      0x0416,
+      0x041a,
+      0x041b,
+      0x041e,
+      0x0a12,
+      0x0a16,
+      0x0a1a,
+      0x0a1b,
+      0x0a1e,
+  };
+  bool supported = false;
+  for (uint16_t id : supportedDevices) {
+    if (aDeviceId == id) {
+      supported = true;
+      break;
+    }
+  }
+  if (!supported) {
+    HardwareTooOldForWR(aFeature);
+    return;
+  }
+
+#ifdef MOZ_WIDGET_GTK
+  // Performance is not great on 4k screens with WebRender + Linux.
+  // Disable it for now if it is too large.
+  const int32_t kMaxPixelsLinux = 3440 * 1440;  // UWQHD
+  if (aScreenPixels > kMaxPixelsLinux) {
+    aFeature.Disable(
+        FeatureStatus::BlockedScreenTooLarge, "Screen size too large",
+        NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_TOO_LARGE"));
+  } else if (aScreenPixels <= 0) {
+    aFeature.Disable(
+        FeatureStatus::BlockedScreenUnknown, "Screen size unknown",
+        NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_UNKNOWN"));
+  } else {
+#endif  // MOZ_WIDGET_GTK
+#ifndef NIGHTLY_BUILD
+    aFeature.Disable(
+        FeatureStatus::BlockedReleaseChannelIntel,
+        "Release channel and Intel",
+        NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_INTEL"));
+#endif  // !NIGHTLY_BUILD
+#ifdef MOZ_WIDGET_GTK
+  }
+#endif  // MOZ_WIDGET_GTK
+}
+
 static FeatureState& WebRenderHardwareQualificationStatus(
     const IntSize& aScreenSize, bool aHasBattery, nsCString& aOutFailureId) {
   FeatureState& featureWebRenderQualified =
       gfxConfig::GetFeature(Feature::WEBRENDER_QUALIFIED);
   featureWebRenderQualified.EnableByDefault();
 
   if (Preferences::HasUserValue(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
     if (!Preferences::GetBool(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
@@ -2623,224 +2796,85 @@ static FeatureState& WebRenderHardwareQu
           FeatureStatus::BlockedOverride, "HW qualification pref override",
           NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_QUALIFICATION_OVERRIDE"));
     }
     return featureWebRenderQualified;
   }
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
   int32_t status;
-  if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBRENDER,
-                                             aOutFailureId, &status))) {
-    if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
-      featureWebRenderQualified.Disable(FeatureStatus::Blacklisted,
-                                        "No qualified hardware", aOutFailureId);
-    } else {
-      nsAutoString adapterVendorID;
-      gfxInfo->GetAdapterVendorID(adapterVendorID);
-
-      nsAutoString adapterDeviceID;
-      gfxInfo->GetAdapterDeviceID(adapterDeviceID);
-      nsresult valid;
-      int32_t deviceID = adapterDeviceID.ToInteger(&valid, 16);
-      if (valid != NS_OK) {
-        featureWebRenderQualified.Disable(
-            FeatureStatus::BlockedDeviceUnknown, "Bad device id",
-            NS_LITERAL_CSTRING("FEATURE_FAILURE_BAD_DEVICE_ID"));
-      } else {
-        const int32_t screenPixels = aScreenSize.width * aScreenSize.height;
-
-        if (adapterVendorID == u"0x10de") {
-          if (deviceID < 0x6c0) {
-            // 0x6c0 is the lowest Fermi device id. Unfortunately some Tesla
-            // devices that don't support D3D 10.1 have higher deviceIDs. They
-            // will be included, but blocked by ANGLE.
-            featureWebRenderQualified.Disable(
-                FeatureStatus::BlockedDeviceTooOld, "Device too old",
-                NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
-          }
-        } else if (adapterVendorID == u"0x1002") {  // AMD
-          // AMD deviceIDs are not very well ordered. This
-          // condition is based off the information in gpu-db
-          if ((deviceID >= 0x6600 && deviceID < 0x66b0) ||
-              (deviceID >= 0x6700 && deviceID < 0x6720) ||
-              (deviceID >= 0x6780 && deviceID < 0x6840) ||
-              (deviceID >= 0x6860 && deviceID < 0x6880) ||
-              (deviceID >= 0x6900 && deviceID < 0x6a00) ||
-              (deviceID == 0x7300) ||
-              (deviceID >= 0x9830 && deviceID < 0x9870) ||
-              (deviceID >= 0x9900 && deviceID < 0x9a00)) {
-            // we have a desktop CAYMAN, SI, CIK, VI, or GFX9 device
-            // so treat the device as qualified unless it is not Windows
-            // and not nightly.
-#if !defined(XP_WIN) && !defined(NIGHTLY_BUILD)
-            featureWebRenderQualified.Disable(
-                FeatureStatus::BlockedReleaseChannelAMD,
-                "Release channel and AMD",
-                NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_AMD"));
-#endif  // !XPWIN && !NIGHTLY_BUILD
-          } else {
-            featureWebRenderQualified.Disable(
-                FeatureStatus::BlockedDeviceTooOld, "Device too old",
-                NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
-          }
-        } else if (adapterVendorID == u"0x8086") {  // Intel
-          const uint16_t supportedDevices[] = {
-              // skylake gt2+
-              0x1912,
-              0x1913,
-              0x1915,
-              0x1916,
-              0x1917,
-              0x191a,
-              0x191b,
-              0x191d,
-              0x191e,
-              0x1921,
-              0x1923,
-              0x1926,
-              0x1927,
-              0x192b,
-              0x1932,
-              0x193b,
-              0x193d,
-
-              // kabylake gt2+
-              0x5912,
-              0x5916,
-              0x5917,
-              0x591a,
-              0x591b,
-              0x591c,
-              0x591d,
-              0x591e,
-              0x5921,
-              0x5926,
-              0x5923,
-              0x5927,
-              0x593b,
-
-              // coffeelake gt2+
-              0x3e91,
-              0x3e92,
-              0x3e96,
-              0x3e98,
-              0x3e9a,
-              0x3e9b,
-              0x3e94,
-              0x3ea0,
-              0x3ea9,
-              0x3ea2,
-              0x3ea6,
-              0x3ea7,
-              0x3ea8,
-              0x3ea5,
-
-              // broadwell gt2+
-              0x1612,
-              0x1616,
-              0x161a,
-              0x161b,
-              0x161d,
-              0x161e,
-              0x1622,
-              0x1626,
-              0x162a,
-              0x162b,
-              0x162d,
-              0x162e,
-              0x1632,
-              0x1636,
-              0x163a,
-              0x163b,
-              0x163d,
-              0x163e,
-
-              // HD Graphics 4600
-              0x0412,
-              0x0416,
-              0x041a,
-              0x041b,
-              0x041e,
-              0x0a12,
-              0x0a16,
-              0x0a1a,
-              0x0a1b,
-              0x0a1e,
-          };
-          bool supported = false;
-          for (uint16_t id : supportedDevices) {
-            if (deviceID == id) {
-              supported = true;
-              break;
-            }
-          }
-          if (supported) {
-#ifdef MOZ_WIDGET_GTK
-            // Performance is not great on 4k screens with WebRender + Linux.
-            // Disable it for now if it is too large.
-            const int32_t kMaxPixelsLinux = 3440 * 1440;  // UWQHD
-            if (screenPixels > kMaxPixelsLinux) {
-              featureWebRenderQualified.Disable(
-                  FeatureStatus::BlockedScreenTooLarge, "Screen size too large",
-                  NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_TOO_LARGE"));
-            } else if (screenPixels <= 0) {
-              featureWebRenderQualified.Disable(
-                  FeatureStatus::BlockedScreenUnknown, "Screen size unknown",
-                  NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_UNKNOWN"));
-            } else {
-#endif  // MOZ_WIDGET_GTK
-#ifndef NIGHTLY_BUILD
-              featureWebRenderQualified.Disable(
-                  FeatureStatus::BlockedReleaseChannelIntel,
-                  "Release channel and Intel",
-                  NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_INTEL"));
-#endif  // !NIGHTLY_BUILD
-#ifdef MOZ_WIDGET_GTK
-            }
-#endif  // MOZ_WIDGET_GTK
-          } else {
-            featureWebRenderQualified.Disable(
-                FeatureStatus::BlockedDeviceTooOld, "Device too old",
-                NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
-          }
-        } else {
-          featureWebRenderQualified.Disable(
-              FeatureStatus::BlockedVendorUnsupported, "Unsupported vendor",
-              NS_LITERAL_CSTRING("FEATURE_FAILURE_UNSUPPORTED_VENDOR"));
-        }
-
-        // We leave checking the battery for last because we would like to know
-        // which users were denied WebRender only because they have a battery.
-        if (featureWebRenderQualified.IsEnabled() && aHasBattery) {
-          // For AMD/Intel devices, if we have a battery, ignore it if the
-          // screen is small enough. Note that we always check for a battery
-          // with NVIDIA because we do not have a limited/curated set of devices
-          // to support WebRender on.
-          const int32_t kMaxPixelsBattery = 1920 * 1200;  // WUXGA
-          if ((adapterVendorID == u"0x8086" || adapterVendorID == u"0x1002") &&
-              screenPixels > 0 && screenPixels <= kMaxPixelsBattery) {
-#ifndef NIGHTLY_BUILD
-            featureWebRenderQualified.Disable(
-                FeatureStatus::BlockedReleaseChannelBattery,
-                "Release channel and battery",
-                NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_BATTERY"));
-#endif  // !NIGHTLY_BUILD
-          } else {
-            featureWebRenderQualified.Disable(
-                FeatureStatus::BlockedHasBattery, "Has battery",
-                NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_HAS_BATTERY"));
-          }
-        }
-      }
-    }
-  } else {
+  if (NS_FAILED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBRENDER,
+                                          aOutFailureId, &status))) {
     featureWebRenderQualified.Disable(
         FeatureStatus::BlockedNoGfxInfo, "gfxInfo is broken",
         NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_NO_GFX_INFO"));
+    return featureWebRenderQualified;
+  }
+
+  if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
+    featureWebRenderQualified.Disable(FeatureStatus::Blacklisted,
+                                      "No qualified hardware", aOutFailureId);
+    return featureWebRenderQualified;
+  }
+
+  nsAutoString adapterVendorID;
+  gfxInfo->GetAdapterVendorID(adapterVendorID);
+
+  nsAutoString adapterDeviceID;
+  gfxInfo->GetAdapterDeviceID(adapterDeviceID);
+  nsresult valid;
+  int32_t deviceID = adapterDeviceID.ToInteger(&valid, 16);
+  if (valid != NS_OK) {
+    featureWebRenderQualified.Disable(
+        FeatureStatus::BlockedDeviceUnknown, "Bad device id",
+        NS_LITERAL_CSTRING("FEATURE_FAILURE_BAD_DEVICE_ID"));
+    return featureWebRenderQualified;
+  }
+
+  const int32_t screenPixels = aScreenSize.width * aScreenSize.height;
+
+  if (adapterVendorID == u"0x10de") { // Nvidia
+    UpdateWRQualificationForNvidia(featureWebRenderQualified, deviceID);
+  } else if (adapterVendorID == u"0x1002") {  // AMD
+    UpdateWRQualificationForAMD(featureWebRenderQualified, deviceID);
+  } else if (adapterVendorID == u"0x8086") {  // Intel
+    UpdateWRQualificationForIntel(featureWebRenderQualified, deviceID,
+                                  screenPixels);
+  } else {
+    featureWebRenderQualified.Disable(
+        FeatureStatus::BlockedVendorUnsupported, "Unsupported vendor",
+        NS_LITERAL_CSTRING("FEATURE_FAILURE_UNSUPPORTED_VENDOR"));
+  }
+
+  if (!featureWebRenderQualified.IsEnabled()) {
+    // One of the checks above failed, early exit
+    return featureWebRenderQualified;
+  }
+
+  // We leave checking the battery for last because we would like to know
+  // which users were denied WebRender only because they have a battery.
+  if (aHasBattery) {
+    // For AMD/Intel devices, if we have a battery, ignore it if the
+    // screen is small enough. Note that we always check for a battery
+    // with NVIDIA because we do not have a limited/curated set of devices
+    // to support WebRender on.
+    const int32_t kMaxPixelsBattery = 1920 * 1200;  // WUXGA
+    if ((adapterVendorID == u"0x8086" || adapterVendorID == u"0x1002") &&
+        screenPixels > 0 && screenPixels <= kMaxPixelsBattery) {
+#ifndef NIGHTLY_BUILD
+      featureWebRenderQualified.Disable(
+          FeatureStatus::BlockedReleaseChannelBattery,
+          "Release channel and battery",
+          NS_LITERAL_CSTRING("FEATURE_FAILURE_RELEASE_CHANNEL_BATTERY"));
+#endif  // !NIGHTLY_BUILD
+    } else {
+      featureWebRenderQualified.Disable(
+          FeatureStatus::BlockedHasBattery, "Has battery",
+          NS_LITERAL_CSTRING("FEATURE_FAILURE_WR_HAS_BATTERY"));
+    }
   }
   return featureWebRenderQualified;
 }
 
 void gfxPlatform::InitWebRenderConfig() {
   bool prefEnabled = WebRenderPrefEnabled();
   bool envvarEnabled = WebRenderEnvvarEnabled();
 
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -673,17 +673,20 @@ void RenderThread::NotifyNotUsed(uint64_
   }
 
   MutexAutoLock lock(mRenderTextureMapLock);
   if (mHasShutdown) {
     return;
   }
 
   auto it = mRenderTextures.find(aExternalImageId);
+#ifndef MOZ_WIDGET_ANDROID
+  // This assert fails on GeckoView intermittently. Bug 1559958 tracks it.
   MOZ_ASSERT(it != mRenderTextures.end());
+#endif
   if (it == mRenderTextures.end()) {
     return;
   }
 
   RefPtr<RenderTextureHost> texture = it->second;
   texture->NotifyNotUsed();
 }
 
--- a/gfx/wr/webrender/src/renderer.rs
+++ b/gfx/wr/webrender/src/renderer.rs
@@ -4392,31 +4392,34 @@ impl Renderer {
     fn draw_tile_frame(
         &mut self,
         frame: &mut Frame,
         device_size: Option<DeviceIntSize>,
         frame_id: GpuFrameId,
         stats: &mut RendererStats,
         clear_framebuffer: bool,
     ) {
+        // These markers seem to crash a lot on Android, see bug 1559834
+        #[cfg(not(target_os = "android"))]
         let _gm = self.gpu_profile.start_marker("tile frame draw");
 
         if frame.passes.is_empty() {
             frame.has_been_rendered = true;
             return;
         }
 
         self.device.disable_depth_write();
         self.set_blend(false, FramebufferKind::Other);
         self.device.disable_stencil();
 
         self.bind_frame_data(frame);
 
-        for (pass_index, pass) in frame.passes.iter_mut().enumerate() {
-            let _gm = self.gpu_profile.start_marker(&format!("pass {}", pass_index));
+        for (_pass_index, pass) in frame.passes.iter_mut().enumerate() {
+            #[cfg(not(target_os = "android"))]
+            let _gm = self.gpu_profile.start_marker(&format!("pass {}", _pass_index));
 
             self.texture_resolver.bind(
                 &TextureSource::PrevPassAlpha,
                 TextureSampler::PrevPassAlpha,
                 &mut self.device,
             );
             self.texture_resolver.bind(
                 &TextureSource::PrevPassColor,
--- a/image/test/reftest/downscaling/reftest.list
+++ b/image/test/reftest/downscaling/reftest.list
@@ -21,19 +21,19 @@
 # Also note that Mac OS X has its own system-level downscaling algorithm, so
 # tests here may need Mac-specific "fuzzy-if(cocoaWidget,...)" annotations.
 # Similarly, modern versions of Windows have slightly different downscaling
 # behavior than other platforms, and may require "fuzzy-if(winWidget,...)".
 
 
 # RUN TESTS NOT AFFECTED BY DOWNSCALE-DURING-DECODE:
 # ==================================================
-fuzzy-if(skiaContent,0-14,0-416) fuzzy-if(webrender,1-1,2-2) == downscale-svg-1a.html downscale-svg-1-ref.html?80
-fuzzy(0-80,0-468) fuzzy-if(webrender,65-65,468-468) == downscale-svg-1b.html downscale-svg-1-ref.html?72
-fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-62) fuzzy-if(skiaContent,0-8,0-292) fuzzy-if(webrender,1-1,2-2) == downscale-svg-1c.html downscale-svg-1-ref.html?64
+fuzzy-if(skiaContent,0-14,0-416) fuzzy-if(webrender&&!geckoview,1-1,2-2) == downscale-svg-1a.html downscale-svg-1-ref.html?80
+fuzzy(0-80,0-468) fuzzy-if(webrender,65-65,468-480) == downscale-svg-1b.html downscale-svg-1-ref.html?72
+fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-62) fuzzy-if(skiaContent,0-8,0-292) fuzzy-if(webrender&&!geckoview,1-1,2-2) == downscale-svg-1c.html downscale-svg-1-ref.html?64
 fuzzy(0-17,0-208) fuzzy-if(webrender,7-7,208-208) == downscale-svg-1d.html downscale-svg-1-ref.html?53
 fuzzy(0-80,0-216) fuzzy-if(skiaContent,0-110,0-181) fuzzy-if(webrender,54-54,178-178) == downscale-svg-1e.html downscale-svg-1-ref.html?40
 fuzzy(0-51,0-90) fuzzy-if(skiaContent,0-142,0-77) fuzzy-if(webrender,64-64,31-31) == downscale-svg-1f.html downscale-svg-1-ref.html?24
 
 # RUN TESTS WITH DOWNSCALE-DURING-DECODE DISABLED:
 # ================================================
 default-preferences pref(image.downscale-during-decode.enabled,false)
 
--- a/layout/reftests/async-scrolling/reftest.list
+++ b/layout/reftests/async-scrolling/reftest.list
@@ -1,16 +1,16 @@
 skip-if(!asyncPan) == bg-fixed-1.html bg-fixed-1-ref.html
 skip-if(!asyncPan) == bg-fixed-cover-1.html bg-fixed-cover-1-ref.html
 skip-if(!asyncPan) == bg-fixed-cover-2.html bg-fixed-cover-2-ref.html
 skip-if(!asyncPan) == bg-fixed-cover-3.html bg-fixed-cover-3-ref.html
 skip-if(!asyncPan) == bg-fixed-child.html bg-fixed-child-ref.html
 skip-if(!asyncPan) == bg-fixed-child-clip-1.html bg-fixed-child-clip-ref.html
 skip-if(!asyncPan) == bg-fixed-child-clip-2.html bg-fixed-child-clip-ref.html
-fuzzy(0-1,0-246) fuzzy-if(skiaContent,0-2,0-170) fuzzy-if(browserIsRemote&&d2d,0-59,0-187) fuzzy-if(webrender,41-41,166-166) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html
+fuzzy(0-1,0-246) fuzzy-if(skiaContent,0-2,0-170) fuzzy-if(browserIsRemote&&d2d,0-59,0-187) fuzzy-if(webrender,41-41,166-168) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html
 skip-if(!asyncPan) == bg-fixed-in-opacity.html bg-fixed-in-opacity-ref.html
 # Passing the test below without WebRender would require implementing CSS filters in the Gecko compositor.
 fails-if(!webrender) skip-if(!asyncPan) fuzzy-if(webrender&&gtkWidget,0-1,0-87) fuzzy-if(webrender&&!gtkWidget,0-1,0-3951) == bg-fixed-in-css-filter.html bg-fixed-in-css-filter-ref.html # bug 1454794 for webrender fuzziness
 skip-if(!asyncPan) == bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1-ref.html
 skip-if(!asyncPan) == bg-fixed-child-no-culling-2.html bg-fixed-child-no-culling-2-ref.html
 skip-if(!asyncPan) == bg-fixed-child-no-culling-3.html bg-fixed-child-no-culling-3-ref.html
 fuzzy-if(Android,0-2,0-4000) fuzzy-if(browserIsRemote&&cocoaWidget,0-2,0-179524) fuzzy-if(browserIsRemote&&winWidget,0-1,0-74590) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-1,0-3528) fuzzy-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu))&&(/^aarch64-msvc/.test(xulRuntime.XPCOMABI)),0-1,0-75900) skip-if(!asyncPan) fuzzy-if(geckoview,0-1,0-74590) == bg-fixed-transformed-image.html bg-fixed-transformed-image-ref.html
 test-pref(layout.css.contain.enabled,true) skip-if(!asyncPan) == contain-paint-scrollable-frame-1.html contain-paint-scrollable-frame-1-ref.html
@@ -48,17 +48,17 @@ skip-if(!asyncPan) == sticky-inside-fixe
 skip-if(!asyncPan) fails-if(!webrender) == sticky-inside-transform-1.html sticky-inside-transform-1-ref.html
 fuzzy(0-1,0-60000) skip-if(!asyncPan) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
 fuzzy-if(Android,0-1,0-197) fuzzy-if(webrender,0-1,0-1) skip-if(!asyncPan) == position-sticky-transformed.html position-sticky-transformed-ref.html
 skip-if(!asyncPan) == offscreen-prerendered-active-opacity.html offscreen-prerendered-active-opacity-ref.html
 fuzzy-if(Android,0-6,0-4) fuzzy-if(skiaContent&&!Android,0-1,0-34) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html
 fuzzy-if(Android,0-6,0-4) skip-if(!asyncPan) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html
 fuzzy-if(Android,0-6,0-4) skip == offscreen-clipped-blendmode-3.html offscreen-clipped-blendmode-ref.html # bug 1251588 - wrong AGR on mix-blend-mode item
 fuzzy-if(Android,0-6,0-4) skip-if(!asyncPan) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html
-fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) == perspective-scrolling-1.html perspective-scrolling-1-ref.html
+fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) fails-if(geckoview&&webrender) == perspective-scrolling-1.html perspective-scrolling-1-ref.html
 fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) == perspective-scrolling-2.html perspective-scrolling-2-ref.html
 fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) == perspective-scrolling-3.html perspective-scrolling-3-ref.html
 fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html
 skip-if(!asyncPan) == perspective-scrolling-5.html perspective-scrolling-5-ref.html
 pref(apz.disable_for_scroll_linked_effects,true) skip-if(!asyncPan) == disable-apz-for-sle-pages.html disable-apz-for-sle-pages-ref.html
 fuzzy-if(browserIsRemote&&d2d,0-1,0-22) skip-if(!asyncPan) fuzzy-if(geckoview,2-2,242-242) skip-if(geckoview&&debug) == background-blend-mode-1.html background-blend-mode-1-ref.html # bug 1558286 for GV
 skip-if(Android||!asyncPan) != opaque-fractional-displayport-1.html about:blank
 skip-if(Android||!asyncPan) != opaque-fractional-displayport-2.html about:blank
@@ -67,33 +67,33 @@ fuzzy-if(Android,0-6,0-8) skip-if(!async
 fuzzy-if(Android,0-6,0-8) skip-if(!asyncPan) == fixed-pos-scrolled-clip-3.html fixed-pos-scrolled-clip-3-ref.html
 fuzzy-if(Android,0-6,0-8) skip-if(!asyncPan) == fixed-pos-scrolled-clip-4.html fixed-pos-scrolled-clip-4-ref.html
 skip-if(!asyncPan) == fixed-pos-scrolled-clip-5.html fixed-pos-scrolled-clip-5-ref.html
 skip-if(!asyncPan) == position-sticky-bug1434250.html position-sticky-bug1434250-ref.html
 fuzzy-if(Android,0-6,0-4) skip-if(!asyncPan) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html
 fuzzy-if(Android,0-6,0-4) skip == position-sticky-scrolled-clip-2.html position-sticky-scrolled-clip-2-ref.html # bug ?????? - incorrectly applying clip to sticky contents
 fuzzy-if(Android,0-2,0-4) skip-if(!asyncPan) == curtain-effect-1.html curtain-effect-1-ref.html
 fuzzy-if(Android,0-1,0-4) skip-if(!asyncPan) == transformed-1.html transformed-1-ref.html
-fuzzy-if(Android,2-2,4-4) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html
-fuzzy-if(Android,3-3,4-4) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html
-fuzzy-if(Android,3-3,4-4) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html
-fuzzy-if(Android,3-3,4-4) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html
+fuzzy-if(Android&&!webrender,2-2,4-4) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html
+fuzzy-if(Android&&!webrender,3-3,4-4) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html
+fuzzy-if(Android&&!webrender,3-3,4-4) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html
+fuzzy-if(Android&&!webrender,3-3,4-4) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html
 
 # for the following tests, we want to disable the low-precision buffer
 # as it will expand the displayport beyond what the test specifies in
 # its reftest-displayport attributes, and interfere with where we expect
 # checkerboarding to occur
 default-preferences pref(layers.low-precision-buffer,false)
 skip-if(!asyncPan) == checkerboard-1.html checkerboard-1-ref.html
-skip-if(!asyncPan) == checkerboard-2.html checkerboard-2-ref.html
-skip-if(!asyncPan) == checkerboard-3.html checkerboard-3-ref.html
+skip-if(!asyncPan) fails-if(geckoview&&webrender) == checkerboard-2.html checkerboard-2-ref.html
+skip-if(!asyncPan) fails-if(geckoview&&webrender) == checkerboard-3.html checkerboard-3-ref.html
 default-preferences
 
-skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-1.html position-fixed-async-zoom-1-ref.html
+skip-if(!Android) pref(apz.allow_zooming,true) fails-if(geckoview&&webrender) == position-fixed-async-zoom-1.html position-fixed-async-zoom-1-ref.html
 skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-2.html position-fixed-async-zoom-2-ref.html
 skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-3.html position-fixed-async-zoom-3-ref.html
 skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-4.html position-fixed-async-zoom-4-ref.html
-skip-if(!Android) pref(apz.allow_zooming,true) == position-sticky-async-zoom-1.html position-sticky-async-zoom-1-ref.html
+skip-if(!Android) pref(apz.allow_zooming,true) fails-if(geckoview&&webrender) == position-sticky-async-zoom-1.html position-sticky-async-zoom-1-ref.html
 skip-if(!Android) pref(apz.allow_zooming,true) == position-sticky-async-zoom-2.html position-sticky-async-zoom-2-ref.html
 
 # for this test, apz.allow_zooming is needed to ensure we take the containerless scrolling codepath that creates
 # an async zoom container (since we are testing a regression in that codepath)
-skip-if(!Android) pref(apz.allow_zooming,true) test-pref(apz.fixed-margin-override.enabled,true) test-pref(apz.fixed-margin-override.bottom,50) == dynamic-toolbar-fixed-bottom-1.html dynamic-toolbar-fixed-bottom-1-ref.html
+skip-if(!Android) pref(apz.allow_zooming,true) test-pref(apz.fixed-margin-override.enabled,true) test-pref(apz.fixed-margin-override.bottom,50) fails-if(geckoview&&webrender) == dynamic-toolbar-fixed-bottom-1.html dynamic-toolbar-fixed-bottom-1-ref.html
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -164,17 +164,17 @@ fuzzy-if(skiaContent,0-1,0-400) == attac
 fuzzy(0-50,0-500) fuzzy-if(skiaContent,0-51,0-320) == attachment-local-clipping-color-6.html attachment-local-clipping-color-6-ref.html
 
 == attachment-local-clipping-image-1.html attachment-local-clipping-image-1-ref.html
 == attachment-local-clipping-image-2.html attachment-local-clipping-image-1-ref.html  # Same ref as the previous test.
 == attachment-local-clipping-image-3.html attachment-local-clipping-image-3-ref.html
 # The next three tests are fuzzy due to bug 1128229.
 fuzzy(0-16,0-69) fuzzy-if(skiaContent,0-95,0-2206) == attachment-local-clipping-image-4.html attachment-local-clipping-image-4-ref.html
 fuzzy(0-16,0-69) fuzzy-if(skiaContent,0-95,0-2206) == attachment-local-clipping-image-5.html attachment-local-clipping-image-4-ref.html
-fuzzy(0-80,0-500) fuzzy-if(skiaContent,0-109,0-908) == attachment-local-clipping-image-6.html attachment-local-clipping-image-6-ref.html
+fuzzy(0-80,0-500) fuzzy-if(skiaContent,0-109,0-908) fuzzy-if(geckoview&&webrender,64-64,2462-2830) == attachment-local-clipping-image-6.html attachment-local-clipping-image-6-ref.html
 
 fuzzy-if(skiaContent,0-1,0-8) fuzzy-if(webrender,0-1,0-84) == background-multiple-with-border-radius.html background-multiple-with-border-radius-ref.html
 fuzzy-if(webrender,10-93,49600-49600) == background-repeat-large-area.html background-repeat-large-area-ref.html
 
 fuzzy(0-30,0-474) fuzzy-if(skiaContent,0-31,0-474) == background-tiling-zoom-1.html background-tiling-zoom-1-ref.html
 
 skip-if(!cocoaWidget) == background-repeat-resampling.html background-repeat-resampling-ref.html
 
--- a/layout/reftests/border-image/reftest.list
+++ b/layout/reftests/border-image/reftest.list
@@ -6,17 +6,17 @@
 # This is fuzzy temporarily until bug 1044702 makes it possible to use source
 # clipping on Windows. (Any other fix would have a significant perf cost.)
 fuzzy-if(winWidget,0-1,0-1) == multicolor-image-2.html multicolor-image-2-ref.html
 == multicolor-image-3.html multicolor-image-3-ref.html
 == multicolor-image-4.html multicolor-image-4-ref.html
 == multicolor-image-5.html multicolor-image-5-ref.html
 == transparent-image-1.html transparent-image-1-ref.html
 != repeat-image-1.html repeat-image-1-ref.html
-fuzzy-if(webrender,15-15,975-1000) == 470250-1.html 470250-1-ref.html
+fuzzy-if(webrender,15-15,975-1000) fails-if(geckoview&&webrender) == 470250-1.html 470250-1-ref.html
 fuzzy-if(webrender,15-233,975-1080) == 470250-2.html 470250-2-ref.html
 != different-h-v-1.html different-h-v-ref.html
 != different-h-v-2.html different-h-v-ref.html
 != different-h-v-1.html different-h-v-2.html
 == center-scaling-1.html center-scaling-1-ref.html
 fails-if(Android) fails-if(usesRepeatResampling) fuzzy-if(webrender&&cocoaWidget,1-1,3280-3280) == center-scaling-2.html center-scaling-2-ref.html # Android: very different scaling (blurriness) on some sides
 fails-if(Android) fails-if(usesRepeatResampling) fuzzy-if(webrender&&cocoaWidget,1-1,4752-4752) == center-scaling-3.html center-scaling-3-ref.html # Android: very different scaling (blurriness) on some sides
 == center-scaling-4t.html center-scaling-4t-ref.html
@@ -37,49 +37,49 @@ fails-if(Android) fails-if(usesRepeatRes
 == border-image-nofill-1.html border-image-nofill-1-ref.html
 == border-image-outset-resize-1.html border-image-outset-resize-1-ref.html
 fuzzy-if(asyncPan&&!layersGPUAccelerated,0-140,0-514) fuzzy-if(winWidget,0-144,0-448) == border-image-outset-move-1.html border-image-outset-move-1-ref.html
 == border-image-style-none.html border-image-style-none-ref.html
 == border-image-style-none-length.html border-image-style-none-length-ref.html
 == border-image-style-none-auto.html border-image-style-none-auto-ref.html
 
 # border images with gradients
-fuzzy-if(webrender,1-3,1488-1804) == border-image-linear-gradient.html border-image-linear-gradient-ref.html
-fuzzy(0-1,0-98) fuzzy-if(skiaContent,0-1,0-350) fuzzy-if(webrender,1-2,36774-37537) == border-image-linear-gradient-slice-1.html border-image-linear-gradient-slice-1-ref.html
-fuzzy(0-1,0-149) fuzzy-if(OSX,0-1,0-10595) fuzzy-if(webrender,1-3,24999-25136) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html
-fuzzy(0-1,0-433) fuzzy-if(skiaContent,0-1,0-2500) fuzzy-if(webrender,1-3,83975-85584) == border-image-linear-gradient-slice-fill-1.html border-image-linear-gradient-slice-fill-1-ref.html
-fuzzy(0-1,0-177) fuzzy-if(OSX,0-1,0-25771) fuzzy-if(skiaContent&&!Android,0-1,0-400) fuzzy-if(Android,0-1,0-6093) fuzzy-if(webrender,1-3,57249-57480) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html
-fuzzy(0-1,0-48)  fuzzy-if(OSX,0-5,0-1676) fuzzy-if(webrender,1-1,4464-4537) == border-image-linear-gradient-width.html border-image-linear-gradient-width-ref.html
-fuzzy(0-1,0-5000) fuzzy-if(OSX,0-1,0-15000) fuzzy-if(webrender,2-2,58625-58987) == border-image-linear-gradient-slice-width.html border-image-linear-gradient-slice-width-ref.html
-fuzzy(0-1,0-3000) fuzzy-if(OSX,0-1,0-6000) fuzzy-if(webrender,1-3,25940-26413) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html
-fuzzy(0-1,0-12) fuzzy-if(skiaContent,0-1,0-400) fuzzy-if(webrender,1-3,25966-26872) == border-image-linear-gradient-repeat-repeat-1.html border-image-linear-gradient-repeat-repeat-1-ref.html
-fuzzy(0-1,0-13) fuzzy-if(skiaContent,0-1,0-300) fuzzy-if(webrender,1-3,26038-27131) == border-image-linear-gradient-repeat-round-1.html border-image-linear-gradient-repeat-round-1-ref.html
-fuzzy-if(webrender,1-2,61283-67805) == border-image-linear-gradient-repeat-repeat-2.html border-image-linear-gradient-repeat-repeat-2-ref.html
-fuzzy(0-1,0-576) fuzzy-if(skiaContent,0-1,0-2000) fuzzy-if(webrender,1-2,61764-68383) == border-image-linear-gradient-repeat-round-2.html border-image-linear-gradient-repeat-round-2-ref.html
-fuzzy(0-1,0-8533) fuzzy-if(webrender,1-3,64622-85925) == border-image-linear-gradient-repeat-repeat-3.html border-image-linear-gradient-repeat-repeat-3-ref.html
-fuzzy(0-1,0-7161) fuzzy-if(webrender,1-3,85018-86037) == border-image-linear-gradient-repeat-round-3.html border-image-linear-gradient-repeat-round-3-ref.html
+fuzzy-if(webrender&&!geckoview,1-3,1488-1804) == border-image-linear-gradient.html border-image-linear-gradient-ref.html
+fuzzy(0-1,0-98) fuzzy-if(skiaContent,0-1,0-350) fuzzy-if(webrender&&!geckoview,1-2,36774-37537) == border-image-linear-gradient-slice-1.html border-image-linear-gradient-slice-1-ref.html
+fuzzy(0-1,0-149) fuzzy-if(OSX,0-1,0-10595) fuzzy-if(webrender&&!geckoview,1-3,24999-25136) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html
+fuzzy(0-1,0-433) fuzzy-if(skiaContent,0-1,0-2500) fuzzy-if(webrender&&!geckoview,1-3,83975-85584) == border-image-linear-gradient-slice-fill-1.html border-image-linear-gradient-slice-fill-1-ref.html
+fuzzy(0-1,0-177) fuzzy-if(OSX,0-1,0-25771) fuzzy-if(skiaContent&&!Android,0-1,0-400) fuzzy-if(Android,0-1,0-6093) fuzzy-if(webrender&&!geckoview,1-3,57249-57480) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html
+fuzzy(0-1,0-48)  fuzzy-if(OSX,0-5,0-1676) fuzzy-if(webrender&&!geckoview,1-1,4464-4537) == border-image-linear-gradient-width.html border-image-linear-gradient-width-ref.html
+fuzzy(0-1,0-5000) fuzzy-if(OSX,0-1,0-15000) fuzzy-if(webrender&&!geckoview,2-2,58625-58987) == border-image-linear-gradient-slice-width.html border-image-linear-gradient-slice-width-ref.html
+fuzzy(0-1,0-3000) fuzzy-if(OSX,0-1,0-6000) fuzzy-if(webrender&&!geckoview,1-3,25940-26413) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html
+fuzzy(0-1,0-12) fuzzy-if(skiaContent,0-1,0-400) fuzzy-if(webrender&&!geckoview,1-3,25966-26872) == border-image-linear-gradient-repeat-repeat-1.html border-image-linear-gradient-repeat-repeat-1-ref.html
+fuzzy(0-1,0-13) fuzzy-if(skiaContent,0-1,0-300) fuzzy-if(webrender&&!geckoview,1-3,26038-27131) == border-image-linear-gradient-repeat-round-1.html border-image-linear-gradient-repeat-round-1-ref.html
+fuzzy-if(webrender&&!geckoview,1-2,61283-67805) == border-image-linear-gradient-repeat-repeat-2.html border-image-linear-gradient-repeat-repeat-2-ref.html
+fuzzy(0-1,0-576) fuzzy-if(skiaContent,0-1,0-2000) fuzzy-if(webrender&&!geckoview,1-2,61764-68383) == border-image-linear-gradient-repeat-round-2.html border-image-linear-gradient-repeat-round-2-ref.html
+fuzzy(0-1,0-8533) fuzzy-if(webrender&&!geckoview,1-3,64622-85925) == border-image-linear-gradient-repeat-repeat-3.html border-image-linear-gradient-repeat-repeat-3-ref.html
+fuzzy(0-1,0-7161) fuzzy-if(webrender&&!geckoview,1-3,85018-86037) == border-image-linear-gradient-repeat-round-3.html border-image-linear-gradient-repeat-round-3-ref.html
 
 fuzzy-if(webrender,0-1,0-2096) == border-image-radial-gradient.html border-image-radial-gradient-ref.html
 fuzzy(0-1,0-42) fuzzy-if(skiaContent,0-2,0-20) fuzzy-if(webrender,0-1,0-37818) == border-image-radial-gradient-slice-1.html border-image-radial-gradient-slice-1-ref.html
 fuzzy(0-1,0-46) fuzzy-if(OSX,0-2,0-4472) fuzzy-if(webrender,0-1,0-26363) == border-image-radial-gradient-slice-2.html border-image-radial-gradient-slice-2-ref.html
 fuzzy(0-1,0-105) fuzzy-if(webrender,0-1,0-90873) == border-image-radial-gradient-slice-fill-1.html border-image-radial-gradient-slice-fill-1-ref.html
 fuzzy(0-1,0-139) fuzzy-if(OSX,0-2,0-4478) fuzzy-if(skiaContent,0-2,0-120) fuzzy-if(webrender,0-1,0-61729) == border-image-radial-gradient-slice-fill-2.html border-image-radial-gradient-slice-fill-2-ref.html
 fuzzy-if(skiaContent,0-1,0-2) fuzzy-if(webrender,0-1,0-4894) == border-image-radial-gradient-width.html border-image-radial-gradient-width-ref.html
 fuzzy(0-1,0-9000) fuzzy-if(webrender,0-3,0-66698) == border-image-radial-gradient-slice-width.html border-image-radial-gradient-slice-width-ref.html
 
 # OS X failures tracked in bug 957025
-fuzzy-if(webrender,1-5,1766-1824) == border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html
+fuzzy-if(webrender&&!geckoview,1-5,1766-1824) == border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html
 fuzzy(0-1,0-5608) fails-if(OSX) fuzzy-if(skiaContent,0-1,0-6093) fuzzy-if(webrender,0-3,0-95449) == border-image-repeating-linear-gradient-slice-fill-2.html border-image-repeating-linear-gradient-slice-fill-2-ref.html
-fuzzy(0-1,0-19200) fails-if(OSX) fuzzy-if(skiaContent,0-3,0-20000) fuzzy-if(webrender,1-4,67400-70767) == border-image-repeating-linear-gradient-repeat-round-2.html border-image-repeating-linear-gradient-repeat-round-2-ref.html
+fuzzy(0-1,0-19200) fails-if(OSX) fuzzy-if(skiaContent,0-3,0-20000) fuzzy-if(webrender&&!geckoview,1-4,67400-70767) == border-image-repeating-linear-gradient-repeat-round-2.html border-image-repeating-linear-gradient-repeat-round-2-ref.html
 
 fuzzy(0-1,0-657) fuzzy-if(webrender,0-3,0-3008) == border-image-repeating-radial-gradient.html border-image-repeating-radial-gradient-ref.html
 fuzzy(0-1,0-510) fuzzy-if(skiaContent,0-3,0-362) fuzzy-if(webrender,0-3,0-62078) == border-image-repeating-radial-gradient-slice-1.html border-image-repeating-radial-gradient-slice-1-ref.html
 fuzzy(0-1,0-438) fuzzy-if(skiaContent,0-3,0-437) fuzzy-if(webrender,0-3,0-40536) == border-image-repeating-radial-gradient-slice-2.html border-image-repeating-radial-gradient-slice-2-ref.html
-fuzzy(0-1,0-1357) fuzzy-if(skiaContent,0-3,0-964) fuzzy-if(webrender,1-4,85720-85915) == border-image-repeating-radial-gradient-slice-fill-1.html border-image-repeating-radial-gradient-slice-fill-1-ref.html
-fuzzy(0-1,0-1058) fails-if(OSX) fuzzy-if(skiaContent,0-3,0-887) fuzzy-if(webrender,1-4,57067-57318) == border-image-repeating-radial-gradient-slice-fill-2.html border-image-repeating-radial-gradient-slice-fill-2-ref.html
+fuzzy(0-1,0-1357) fuzzy-if(skiaContent,0-3,0-964) fuzzy-if(webrender&&!geckoview,1-4,85720-85915) == border-image-repeating-radial-gradient-slice-fill-1.html border-image-repeating-radial-gradient-slice-fill-1-ref.html
+fuzzy(0-1,0-1058) fails-if(OSX) fuzzy-if(skiaContent,0-3,0-887) fuzzy-if(webrender&&!geckoview,1-4,57067-57318) == border-image-repeating-radial-gradient-slice-fill-2.html border-image-repeating-radial-gradient-slice-fill-2-ref.html
 fuzzy(0-1,0-602) fuzzy-if(webrender,0-3,0-7441) == border-image-repeating-radial-gradient-width.html border-image-repeating-radial-gradient-width-ref.html
 fuzzy(0-3,0-18000) fails-if(OSX) fuzzy-if(skiaContent,0-4,0-16462) fuzzy-if(webrender,0-5,0-99728) == border-image-repeating-radial-gradient-slice-width.html border-image-repeating-radial-gradient-slice-width-ref.html
 fuzzy-if(webrender,0-3,0-117768) == border-image-repeating-radial-gradient-repeat-repeat-2.html border-image-repeating-radial-gradient-repeat-repeat-2-ref.html
 fuzzy(0-1,0-1054) fails-if(OSX) fuzzy-if(skiaContent,0-2,0-952) fuzzy-if(webrender,0-3,0-116185) == border-image-repeating-radial-gradient-repeat-round-2.html border-image-repeating-radial-gradient-repeat-round-2-ref.html
 
 # border-image-source (-moz-)element
 fuzzy(0-125,0-5808) == border-image-element.html border-image-element-ref.html
 
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -19,32 +19,32 @@
 
 # percent units
 == percent-1.html percent-1-ref.html
 fuzzy-if(skiaContent,0-1,0-342) == percent-2.html percent-2-ref.html
 fuzzy-if(skiaContent,0-1,0-343) == percent-3.html percent-3-ref.html
 
 # more serious tests, using SVG reference
 fuzzy-if(skiaContent,0-17,0-58) fuzzy-if(webrender,30-30,70-70) == border-circle-2.html border-circle-2-ref.xhtml
-fuzzy-if(gtkWidget,0-14,0-280) fuzzy-if(cocoaWidget,0-4,0-582) fuzzy-if(Android,0-36,0-264) fuzzy-if(d2d,0-51,0-323) fuzzy-if(winWidget&&!d2d,0-16,0-377) fuzzy-if(skiaContent,0-63,0-507) fuzzy-if(webrender,62-62,931-931) == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
+fuzzy-if(gtkWidget,0-14,0-280) fuzzy-if(cocoaWidget,0-4,0-582) fuzzy-if(Android,0-36,0-264) fuzzy-if(d2d,0-51,0-323) fuzzy-if(winWidget&&!d2d,0-16,0-377) fuzzy-if(skiaContent,0-63,0-507) fuzzy-if(webrender,62-62,930-1013) == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
 
 # Corners
 fuzzy-if(skiaContent,0-17,0-47) fuzzy-if(webrender,30-30,58-58) == corner-1.html corner-1-ref.svg # bottom corners different radius than top corners
 fuzzy-if(gtkWidget,0-23,0-5) fuzzy-if(winWidget&&!d2d,0-23,0-5) fuzzy-if(d2d,0-32,0-8) fuzzy-if(Android,0-10,0-8) fuzzy-if(skiaContent,0-18,0-49) fuzzy-if(webrender,30-30,57-57) == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804
 fuzzy-if(gtkWidget,0-3,0-10) fuzzy-if(winWidget&&!d2d,0-3,0-10) fuzzy-if(d2d,0-15,0-32) fuzzy-if(Android,0-3,0-15) fuzzy-if(skiaContent,0-18,0-90) fuzzy-if(webrender,23-23,105-105) == corner-3.html corner-3-ref.svg
-fuzzy-if(skiaContent,0-13,0-83) fuzzy-if(webrender,13-13,104-104) == corner-4.html corner-4-ref.svg
+fuzzy-if(skiaContent,0-13,0-83) fuzzy-if(webrender,13-13,104-108) == corner-4.html corner-4-ref.svg
 
 # Test that radii too long are reduced
 == border-reduce-height.html border-reduce-height-ref.html
 
 # Tests for border clipping
 fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572
 != clipping-2.html about:blank # background color clipped to inner/outer border, can't get
 # great tests for this due to antialiasing problems described in bug 466572
-fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-1) fuzzy-if(skiaContent,0-17,0-62) fuzzy-if(webrender,30-30,70-70) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
+fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-1) fuzzy-if(skiaContent,0-17,0-62) fuzzy-if(webrender,30-30,70-111) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
 
 # Tests for clipping the contents of replaced elements and overflow!=visible
 != clipping-4-ref.html clipping-4-notref.html
 fuzzy-if(true,0-1,0-20) fuzzy-if(d2d,0-72,0-196) fuzzy-if(cocoaWidget,0-1,0-180) fuzzy-if(Android,0-140,0-237) fuzzy-if(webrender,0-8,0-20) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
 fuzzy-if(Android,0-5,0-54) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-37,0-157) fuzzy-if(skiaContent,0-1,0-172) == clipping-4-image.html clipping-4-ref.html
 fuzzy-if(skiaContent,0-1,0-77) == clipping-4-overflow-hidden.html clipping-4-ref.html
 == clipping-5-canvas.html clipping-5-refc.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-5) == clipping-5-image.html clipping-5-refi.html
@@ -86,9 +86,9 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(
 
 == iframe-1.html iframe-1-ref.html
 
 # Test for antialiasing gaps between background and border
 fuzzy-if(gtkWidget,0-1,0-9) fuzzy-if(winWidget&&!d2d,0-1,0-9) fuzzy-if(d2d,0-5,0-40) fuzzy-if(Android||skiaContent,0-1,0-9) == curved-border-background-nogap.html curved-border-background-nogap-ref.html
 
 fuzzy-if(webrender,0-1,0-4) == color-layer-1a.html color-layer-1-ref.html
 
-fuzzy-if(webrender,1-1,104-162) == corner-split.html corner-split-ref.svg
+fuzzy-if(webrender&&!geckoview,1-1,104-162) == corner-split.html corner-split-ref.svg
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1181,17 +1181,17 @@ fails-if(usesRepeatResampling) fails-if(
 fails-if(Android) fails-if(usesRepeatResampling) fails-if(webrender&&!winWidget) == 446100-1b.html about:blank
 fails-if(Android) fails-if(usesRepeatResampling) fails-if(webrender&&!winWidget) == 446100-1c.html about:blank
 fails-if(usesRepeatResampling) fails-if(webrender&&!winWidget) == 446100-1d.html about:blank
 fails-if(usesRepeatResampling) fails-if(webrender&&!winWidget) == 446100-1e.html about:blank
 == 446100-1f.html about:blank
 fails-if(usesRepeatResampling) fails-if(Android) fails-if(webrender&&!winWidget) == 446100-1g.html about:blank
 == 446100-1h.html about:blank
 == 447749-1.html 447749-1-ref.html
-fuzzy(0-127,0-2) == 448193.html 448193-ref.html
+fuzzy(0-127,0-2) fuzzy-if(geckoview&&webrender,43-43,4-4) == 448193.html 448193-ref.html
 != 449149-1a.html about:blank
 != 449149-1b.html about:blank
 == 449149-2.html 449149-2-ref.html
 == 449171-1.html 449171-ref.html
 == 449362-1.html 449362-1-ref.html
 fuzzy-if(webrender,0-4,0-361) == 449519-1.html 449519-1-ref.html
 == 450670-1.html 450670-1-ref.html
 == 451168-1.html 451168-1-ref.html
@@ -1201,19 +1201,19 @@ fuzzy-if(webrender,0-4,0-361) == 449519-
 == 452964-1.html 452964-1-ref.html
 == 454361.html about:blank
 == 455105-1.html 455105-ref.html
 == 455105-2.html 455105-ref.html
 == 455171-5.html 455171-5-ref.html
 == 455280-1.xhtml 455280-1-ref.xhtml
 == 455826-1.html 455826-1-ref.html
 fails-if(Android||cocoaWidget||winWidget) == 456147.xul 456147-ref.html # bug 458047
-fuzzy-if(Android,0-11,0-41) fuzzy-if(winWidget||gtkWidget,0-4,0-6) fuzzy-if(d2d,0-16,0-95) fuzzy-if(skiaContent,0-42,0-154) fuzzy-if(webrender,56-60,449-497) == 456219-1a.html 456219-1-ref.html # bug 1128229
-fuzzy-if(Android,0-11,0-41) fuzzy-if(winWidget||gtkWidget,0-4,0-6) fuzzy-if(d2d,0-16,0-99) fuzzy-if(skiaContent,0-42,0-154) fuzzy-if(webrender,56-60,449-497) == 456219-1b.html 456219-1-ref.html # bug 1128229
-fuzzy-if(Android,0-11,0-41) fuzzy-if(winWidget||gtkWidget,0-4,0-6) fuzzy-if(d2d,0-16,0-99) fuzzy-if(skiaContent,0-42,0-154) fuzzy-if(webrender,56-60,449-497) == 456219-1c.html 456219-1-ref.html # bug 1128229
+fuzzy-if(Android,0-11,0-41) fuzzy-if(winWidget||gtkWidget,0-4,0-6) fuzzy-if(d2d,0-16,0-95) fuzzy-if(skiaContent,0-42,0-154) fuzzy-if(webrender,56-60,449-518) == 456219-1a.html 456219-1-ref.html # bug 1128229
+fuzzy-if(Android,0-11,0-41) fuzzy-if(winWidget||gtkWidget,0-4,0-6) fuzzy-if(d2d,0-16,0-99) fuzzy-if(skiaContent,0-42,0-154) fuzzy-if(webrender,56-60,449-518) == 456219-1b.html 456219-1-ref.html # bug 1128229
+fuzzy-if(Android,0-11,0-41) fuzzy-if(winWidget||gtkWidget,0-4,0-6) fuzzy-if(d2d,0-16,0-99) fuzzy-if(skiaContent,0-42,0-154) fuzzy-if(webrender,56-60,449-497) fuzzy-if(geckoview&&webrender,60-60,1014-4041) == 456219-1c.html 456219-1-ref.html # bug 1128229
 fuzzy-if(skiaContent,0-1,0-45) fuzzy-if(webrender,9-9,8-8) == 456219-2.html 456219-2-ref.html
 == 456330-1.gif 456330-1-ref.png
 == 456484-1.html 456484-1-ref.html
 == 457398-1.html 457398-1-ref.html
 == 457398-2.html 457398-2-ref.html
 == 458296-1a.html 458296-1a-ref.html
 == 458296-1b.html 458296-1-ref.html
 == 458296-1c.html 458296-1-ref.html
@@ -1232,23 +1232,23 @@ fuzzy-if(skiaContent,0-1,0-45) fuzzy-if(
 == 458487-4b.html 458487-4-ref.html
 == 458487-4c.html 458487-4-ref.html
 == 458487-5a.html 458487-5-ref.html
 == 458487-5b.html 458487-5-ref.html
 fuzzy-if(skiaContent,0-1,0-5) == 459443-1.html 459443-1-ref.html
 == 459613-1.html 459613-1-ref.html
 == 460012-1.html 460012-1-ref.html
 == 461266-1.html 461266-1-ref.html
-fuzzy-if(skiaContent||webrender,0-1,0-31200) == 461512-1.html 461512-1-ref.html
+fuzzy-if(skiaContent||webrender,0-1,0-31200) fails-if(geckoview&&webrender) == 461512-1.html 461512-1-ref.html
 == 462844-1.html 462844-ref.html
 == 462844-2.html 462844-ref.html
 == 462844-3.html 462844-ref.html
 == 462844-4.html 462844-ref.html
 == 463204-1.html 463204-1-ref.html
-fuzzy-if(webrender,16-16,3392-3483) == 463217-1.xul 463217-1-ref.xul
+fuzzy-if(webrender,16-16,3392-4020) == 463217-1.xul 463217-1-ref.xul
 == 463952-1.html 463952-1-ref.html
 == 464811-1.html 464811-1-ref.html
 == 465574-1.html 465574-1-ref.html # bug 421436
 == 466258-1.html 466258-1-ref.html
 == 466395-1.html 466395-1-ref.html
 == 466395-2.html 466395-2-ref.html
 == 467084-1.html 467084-1-ref.html
 == 467084-2.html 467084-2-ref.html
@@ -1620,17 +1620,17 @@ random-if(/^Windows\x20NT\x206\.1/.test(
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 600974-2.html 600974-1-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 600974-3.html 600974-1-ref.html # Bug 1392106
 == 602200-1.html 602200-1-ref.html
 == 602200-2.html 602200-2-ref.html
 fuzzy-if(Android,0-8,0-20) == 602200-3.html 602200-3-ref.html
 == 602200-4.html 602200-4-ref.html
 == 603423-1.html 603423-1-ref.html
 == 604737.html 604737-ref.html
-== 605138-1.html 605138-1-ref.html
+fuzzy-if(geckoview&&webrender,11-11,637-637) == 605138-1.html 605138-1-ref.html
 == 605157-1.xhtml 605157-1-ref.xhtml
 == 607267-1.html 607267-1-ref.html
 == 608636-1.html 608636-1-ref.html
 == 608756-1a.html 608756-1-ref.html
 == 608756-1b.html 608756-1-ref.html
 == 608756-2.html 608756-2-ref.html
 fuzzy-if(Android,0-4,0-196) == 609272-1.html 609272-1-ref.html
 needs-focus == 613433-1.html 613433-1-ref.html
@@ -1661,19 +1661,19 @@ fuzzy-if(Android,0-8,0-300) fuzzy-if(ski
 fuzzy-if(skiaContent,0-1,0-500) == 630835-1.html about:blank
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 631352-1.html 631352-1-ref.html # bug 1392106
 skip-if(!haveTestPlugin) fails-if(Android) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&webrender&&isDebugBuild) fuzzy-if(winWidget&&!layersGPUAccelerated,0-102,0-535) fuzzy-if(skiaContent&&!Android,0-102,0-11000) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) HTTP == 632423-1.html 632423-1-ref.html # Bug 1392106
 skip-if(Android) random-if(winWidget||OSX==1010) == 632781-verybig.html 632781-ref.html
 == 632781-normalsize.html 632781-ref.html
 fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),0-1,0-559) fuzzy-if(!isDebugBuild&&gtkWidget&&/^Linux\x20i686/.test(http.oscpu),0-102,0-140) == 633344-1.html 633344-1-ref.html # bug 1103623, Linux32 from GCC update
 fuzzy-if(skiaContent,0-1,0-500) == 634232-1.html 634232-1-ref.html
 fuzzy-if(skiaContent,0-3,0-120000) == 635302-1.html 635302-1-ref.html
-fuzzy(0-1,0-68) fuzzy-if(gtkWidget,0-1,0-70) fails-if(Android) fuzzy-if(skiaContent&&!Android,0-2,0-300) == 635373-1.html 635373-1-ref.html
-random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,0-20,0-118) fuzzy-if(skiaContent&&!Android,0-2,0-550) == 635373-2.html 635373-2-ref.html
-random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,0-20,0-116) fuzzy-if(skiaContent&&!Android,0-2,0-650) == 635373-3.html 635373-3-ref.html
+fuzzy(0-1,0-68) fuzzy-if(gtkWidget,0-1,0-70) fails-if(Android&&!webrender) fuzzy-if(skiaContent&&!Android,0-2,0-300) == 635373-1.html 635373-1-ref.html
+random-if(d2d) fails-if(Android&&!webrender) fuzzy-if(winWidget&&!d2d,0-20,0-118) fuzzy-if(skiaContent&&!Android,0-2,0-550) == 635373-2.html 635373-2-ref.html
+random-if(d2d) fails-if(Android&&!webrender) fuzzy-if(winWidget&&!d2d,0-20,0-116) fuzzy-if(skiaContent&&!Android,0-2,0-650) == 635373-3.html 635373-3-ref.html
 == 635639-1.html 635639-1-ref.html
 == 635639-2.html 635639-2-ref.html
 random == 637597-1.html 637597-1-ref.html # bug 637597 was never really fixed!
 fuzzy-if(Android,0-8,0-500) fuzzy-if(webrender,0-1,0-19) == 637852-1.html 637852-1-ref.html
 fuzzy-if(Android,0-8,0-500) fuzzy-if(skiaContent,0-3,0-1) fuzzy-if(webrender,0-3,0-19) == 637852-2.html 637852-2-ref.html
 fuzzy-if(Android,0-8,0-500) == 637852-3.html 637852-3-ref.html
 == 641770-1.html 641770-1-ref.html
 == 641856-1.html 641856-1-ref.html
@@ -1741,17 +1741,17 @@ fuzzy-if(cocoaWidget,0-1,0-300000) fuzzy
 == 748692-1b.html 748692-1-ref.html
 == 748803-1.html 748803-1-ref.html
 == 750551-1.html 750551-1-ref.html
 fuzzy-if(skiaContent,0-1,0-1) == 751012-1a.html 751012-1-ref.html
 fuzzy-if(skiaContent,0-1,0-1) == 751012-1b.html 751012-1-ref.html
 random-if(Android) == 753329-1.html about:blank
 == 758561-1.html 758561-1-ref.html
 fuzzy-if(true,0-1,0-90) fuzzy-if(skiaContent,0-1,0-320) == 759036-1.html 759036-1-ref.html
-fuzzy-if(true,0-17,0-5886) fuzzy-if(skiaContent,0-9,0-5894) == 759036-2.html 759036-2-ref.html
+fuzzy-if(true,0-17,0-5886) fuzzy-if(skiaContent,0-9,0-5894) fuzzy-if(geckoview&&webrender,3-3,5897-5897) == 759036-2.html 759036-2-ref.html
 == 776265-1a.html 776265-1-ref.html
 == 776265-1b.html 776265-1-ref.html
 == 776265-1c.html 776265-1-ref.html
 == 776265-1d.html 776265-1-ref.html
 == 776265-2a.html 776265-2-ref.html
 == 776265-2b.html 776265-2-ref.html
 == 776265-2c.html 776265-2-ref.html
 == 776265-2d.html 776265-2-ref.html
@@ -2070,17 +2070,17 @@ needs-focus != 1377447-1.html 1377447-2.
 == 1401317.html 1401317-ref.html
 == 1401992.html 1401992-ref.html
 == 1405878-1.xml 1405878-1-ref.xml
 == 1404057.html 1404057-ref.html
 != 1404057.html 1404057-noref.html
 fuzzy-if(webrender,0-129,0-48) == 1406179.html 1406179-ref.html
 == 1406183-1.html 1406183-1-ref.html
 == 1410028.html 1410028-ref.html
-fuzzy-if(!(webrender&&gtkWidget),1-2,17500-17500) == 1412375.html 1412375-ref.html
+fuzzy-if(!(webrender&&(gtkWidget||geckoview)),1-2,17500-17500) == 1412375.html 1412375-ref.html
 test-pref(font.size.systemFontScale,200) == 1412743.html 1412743-ref.html
 == 1419820-1.html 1419820-1-ref.html
 == 1420946-1.html 1420946-1-ref.html
 == 1422393.html 1422393-ref.html
 == 1424177.html 1424177-ref.html
 == 1424680.html 1424680-ref.html
 == 1424798-1.html 1424798-ref.html
 fuzzy-if(!webrender,0-74,0-2234) == 1425243-1.html 1425243-1-ref.html
@@ -2097,18 +2097,18 @@ fuzzy(0-1,0-625) == 1466638-1.html 14666
 == 1483649-1.xul 1483649-1-ref.xul
 test-pref(layout.css.contain.enabled,true) == 1483946.html 1483946-ref.html
 test-pref(layout.css.visited_links_enabled,false) == 1488155.html 1488155-ref.html
 == 1492660-1.html 1492660-1-ref.html
 pref(layout.css.supports-selector.enabled,true) == 1499386.html 1499386-ref.html
 pref(layout.css.supports-selector.enabled,false) != 1499386.html 1499386-ref.html
 == 1509425-1.html 1509425-1-ref.html
 == 1511570.html 1511570-ref.html
-fuzzy-if(!webrender,1-5,66-547) fuzzy-if(geckoview,1-2,64-141) == 1529992-1.html 1529992-1-ref.html
-fuzzy-if(!webrender,0-6,0-34) fails-if(webrender) fuzzy-if(geckoview,9-9,44-44) == 1529992-2.html 1529992-2-ref.html
+fuzzy-if(!webrender,1-5,66-547) fuzzy-if(geckoview&&!webrender,1-2,64-141) == 1529992-1.html 1529992-1-ref.html
+fuzzy-if(!webrender,0-6,0-34) fuzzy-if(geckoview,9-9,44-44) fails-if(webrender) == 1529992-2.html 1529992-2-ref.html
 == 1535040-1.html 1535040-1-ref.html
 == 1545360-1.xhtml 1545360-1-ref.xhtml
 skip-if(!asyncPan) == 1544895.html 1544895-ref.html
 == 1548809.html 1548809-ref.html
 != 1552789-1.html 1552789-ref-1.html
 == 1558937-1.html 1558937-1-ref.html
 fuzzy-if(!webrender||!winWidget,254-255,464-1613) == 1562733-rotated-nastaliq-1.html 1562733-rotated-nastaliq-1-ref.html
 == 1562733-rotated-nastaliq-2.html 1562733-rotated-nastaliq-2-ref.html
--- a/layout/reftests/css-blending/reftest.list
+++ b/layout/reftests/css-blending/reftest.list
@@ -1,17 +1,17 @@
 == blend-canvas.html blend-canvas-ref.html
 == blend-constant-background-color.html blend-constant-background-color-ref.html
 == blend-gradient-background-color.html blend-gradient-background-color-ref.html
 == blend-image.html blend-image-ref.html
-== blend-difference-stacking.html blend-difference-stacking-ref.html
+fuzzy-if(geckoview&&webrender,3-3,5-5) == blend-difference-stacking.html blend-difference-stacking-ref.html
 
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-10000) fuzzy-if(skiaContent,0-1,0-30000) == background-blending-alpha.html background-blending-alpha-ref.html
 == background-blending-gradient-color.html background-blending-gradient-color-ref.html
-fuzzy-if(azureSkiaGL,0-3,0-7597) fuzzy-if(cocoaWidget,0-3,0-7597) fuzzy-if(d2d,0-1,0-3800) fuzzy-if(d3d11,0-1,0-4200) fuzzy-if(skiaContent,0-2,0-9450) fuzzy-if(webrender,1-1,2400-6200) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
+fuzzy-if(azureSkiaGL,0-3,0-7597) fuzzy-if(cocoaWidget,0-3,0-7597) fuzzy-if(d2d,0-1,0-3800) fuzzy-if(d3d11,0-1,0-4200) fuzzy-if(skiaContent,0-2,0-9450) fuzzy-if(webrender&&!geckoview,1-1,2400-6200) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
 fuzzy-if(azureSkiaGL,0-2,0-7174) == background-blending-gradient-image.html background-blending-gradient-color-ref.html
 fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-10000) == background-blending-image-color-jpg.html background-blending-image-color-ref.html
 == background-blending-image-color-png.html background-blending-image-color-ref.html
 == background-blending-image-color-svg.html background-blending-image-color-ref.html
 fuzzy-if(azureSkiaGL,0-2,0-7174) == background-blending-image-gradient.html background-blending-gradient-color-ref.html
 == background-blending-image-image.html background-blending-image-color-ref.html
 == background-blending-isolation.html background-blending-isolation-ref.html
 == background-blending-list-repeat.html background-blending-list-repeat-ref.html
@@ -20,40 +20,40 @@ fuzzy-if(azureSkiaGL,0-2,0-7174) == back
 == background-blending-color-burn.html background-blending-color-burn-ref.svg
 == background-blending-color-dodge.html background-blending-color-dodge-ref.svg
 # need to investigate why these tests are fuzzy - first suspect is a possible color space conversion on some platforms; same for mix-blend-mode tests
 fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) fuzzy-if(d2d,0-1,0-8000) == background-blending-color.html background-blending-color-ref.svg
 == background-blending-darken.html background-blending-darken-ref.svg
 == background-blending-difference.html background-blending-difference-ref.svg
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||skiaContent,0-1,0-1600) == background-blending-exclusion.html background-blending-exclusion-ref.svg
 fuzzy-if(cocoaWidget||d2d,0-1,0-1600) == background-blending-hard-light.html background-blending-hard-light-ref.svg
-fuzzy-if(d2d,0-1,0-9600) fuzzy-if(azureSkia||gtkWidget,0-1,0-11200) fuzzy-if(webrender,1-1,9600-11200) == background-blending-hue.html background-blending-hue-ref.svg
+fuzzy-if(d2d,0-1,0-9600) fuzzy-if(azureSkia||gtkWidget,0-1,0-11200) fuzzy-if(webrender&&!geckoview,1-1,9600-11240) == background-blending-hue.html background-blending-hue-ref.svg
 == background-blending-lighten.html background-blending-lighten-ref.svg
 fuzzy-if(d2d,0-1,0-8000) fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) == background-blending-luminosity.html background-blending-luminosity-ref.svg
 fuzzy-if(skiaContent,0-1,0-1600) == background-blending-multiply.html background-blending-multiply-ref.svg
 == background-blending-normal.html background-blending-normal-ref.svg
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||azureSkia||gtkWidget,0-1,0-1600) == background-blending-overlay.html background-blending-overlay-ref.svg
 fuzzy-if(d2d,0-1,0-3200) fuzzy-if(azureSkia||gtkWidget,0-2,0-12800) == background-blending-saturation.html background-blending-saturation-ref.svg
 fuzzy-if(d2d||azureSkia||gtkWidget,0-1,0-1600) == background-blending-screen.html background-blending-screen-ref.svg
 fuzzy-if(d2d||azureSkia||gtkWidget,0-10,0-4800) == background-blending-soft-light.html background-blending-soft-light-ref.svg
 
 fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-40000) == background-blending-image-color-959674.html background-blending-image-color-959674-ref.html
 
 #fuzzy due to inconsistencies in rounded rect cliping between parent and child; may be related to antialiasing. Between platforms, the max difference is the same, and the number of different pixels is either 36 or 37. (Win, Mac and Lin)
-fuzzy(0-65,0-53) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html
+fuzzy(0-65,0-53) fuzzy-if(geckoview&&webrender,64-64,163-163) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html
 
 fuzzy-if(d3d11,0-49,0-200) == mix-blend-mode-and-filter.html mix-blend-mode-and-filter-ref.html
 fuzzy-if(d3d11,0-1,0-5) == mix-blend-mode-and-filter.svg mix-blend-mode-and-filter-ref.svg
 
-fuzzy(0-2,0-14400) == mix-blend-mode-child-of-blended-has-opacity.html mix-blend-mode-child-of-blended-has-opacity-ref.html
+fuzzy(0-2,0-14400) fuzzy-if(geckoview&&webrender,3-3,700-700) == mix-blend-mode-child-of-blended-has-opacity.html mix-blend-mode-child-of-blended-has-opacity-ref.html
 
 == mix-blend-mode-nested-976533.html mix-blend-mode-nested-976533-ref.html
 == mix-blend-mode-culling-1207041.html mix-blend-mode-culling-1207041-ref.html
 == mix-blend-mode-dest-alpha-1135271.html mix-blend-mode-dest-alpha-1135271-ref.html
-== clipped-mixblendmode-containing-unclipped-stuff.html clipped-mixblendmode-containing-unclipped-stuff-ref.html
+fuzzy-if(geckoview&&webrender,3-3,849-849) == clipped-mixblendmode-containing-unclipped-stuff.html clipped-mixblendmode-containing-unclipped-stuff-ref.html
 fuzzy(0-1,0-6800) == clipped-opacity-containing-unclipped-mixblendmode.html clipped-opacity-containing-unclipped-mixblendmode-ref.html
 
 # Test plan 5.3.1 Blending between the background layers and the background color for an element with background-blend-mode
 # Test 9
 == background-blending-image-color-svg-as-data-uri.html background-blending-image-color-ref.html
 # Test 10
 test-pref(image.animation_mode,"none") == background-blending-image-color-gif.html background-blending-image-color-gif-ref.html
 == background-blending-image-color-transform3d.html background-blending-image-color-ref.html
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -42,17 +42,17 @@ fuzzy-if(cocoaWidget,0-4,0-22317) fuzzy-
 fuzzy(0-1,0-238) fuzzy-if(cocoaWidget,0-4,0-22608) fuzzy-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\./.test(http.oscpu))&&d2d,0-1,0-336) fuzzy-if(Android,0-8,0-787) fuzzy-if(skiaContent,0-2,0-300) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.test(http.oscpu),0-1,0-5) fuzzy-if(Android,0-17,0-3880) == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.test(http.oscpu),0-1,0-5) fuzzy-if(Android,0-17,0-3880) == radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html
 fuzzy-if(Android,0-8,0-771) == radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html
 fails-if(gtkWidget&&/x86_64-/.test(xulRuntime.XPCOMABI)) fuzzy(0-1,0-1622) fuzzy-if(cocoaWidget,0-2,0-41281) fuzzy-if(Android,0-8,0-1091) fuzzy-if(skiaContent,0-2,0-500) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html
 fuzzy-if(Android,0-17,0-13320) == radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html
 fuzzy-if(Android,0-17,0-13320) == radial-shape-farthest-side-1b.html radial-shape-farthest-side-1-ref.html
 fuzzy-if(webrender,0-2,0-12) == radial-size-1a.html radial-size-1-ref.html
-fuzzy(1-2,1048-1446) == radial-size-1b.html radial-size-1-ref.html
+fuzzy-if(!(geckoview&&webrender),1-2,1048-1446) == radial-size-1b.html radial-size-1-ref.html
 fuzzy-if(Android,0-4,0-248) == radial-zero-length-1a.html radial-zero-length-1-ref.html
 fuzzy-if(Android,0-4,0-248) == radial-zero-length-1b.html radial-zero-length-1-ref.html
 fuzzy-if(Android,0-4,0-248) == radial-zero-length-1c.html radial-zero-length-1-ref.html
 fuzzy-if(Android,0-4,0-248) == radial-zero-length-1d.html radial-zero-length-1-ref.html
 fuzzy-if(Android,0-4,0-248) == radial-zero-length-1e.html radial-zero-length-1-ref.html
 fuzzy-if(Android,0-4,0-248) == radial-zero-length-1f.html radial-zero-length-1-ref.html
 == radial-premul.html radial-premul-ref.html
 == repeated-final-stop-1.html repeated-final-stop-1-ref.html
--- a/layout/reftests/font-matching/reftest.list
+++ b/layout/reftests/font-matching/reftest.list
@@ -130,19 +130,19 @@ random-if(/^Windows\x20NT\x206\.1/.test(
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-6.html italic-oblique-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-7.html italic-oblique-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-8.html italic-oblique-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-9.html italic-oblique-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) != italic-oblique-kinnari.html italic-oblique-kinnari-ref.html # Bug 1392106
 
 # GTK and Windows 7 don't have full emoji and symbol font, so emoji-fallback-2
 # don't work well.
-fails-if(geckoview) == emoji-fallback-1.html emoji-fallback-1-ref.html # Bug 1558513 for GV
+fails-if(geckoview&&!webrender) == emoji-fallback-1.html emoji-fallback-1-ref.html # Bug 1558513 for GV
 skip-if(gtkWidget||/^Windows\x20NT\x206\.1/.test(http.oscpu)) == emoji-fallback-2.html emoji-fallback-2-ref.html
-fails-if(geckoview) == emoji-fallback-3.html emoji-fallback-3-ref.html # Bug 1558513 for GV
+fails-if(geckoview&&!webrender) == emoji-fallback-3.html emoji-fallback-3-ref.html # Bug 1558513 for GV
 
 # system font generic per-language tests, only works under OSX currently
 # Bug 1212731 - initial implementation caused startup regression and
 # regression with full-width digits display in UI elements. Disable
 # tests until these problems are corrected.
 # random-if(!OSX) == system-generic-fallback-1.html system-generic-fallback-1-ref.html
 # random-if(!OSX) == system-generic-fallback-2.html system-generic-fallback-2-ref.html
 # random-if(!OSX) == system-generic-fallback-3.html system-generic-fallback-3-ref.html
--- a/layout/reftests/forms/input/checkbox/reftest.list
+++ b/layout/reftests/forms/input/checkbox/reftest.list
@@ -9,11 +9,11 @@
 == indeterminate-checked-notref.html about:blank
 == indeterminate-unchecked.html about:blank
 != indeterminate-native-checked.html indeterminate-native-checked-notref.html
 != indeterminate-native-unchecked.html indeterminate-native-unchecked-notref.html
 == indeterminate-selector.html indeterminate-selector-ref.html
 skip-if(!gtkWidget) == gtk-theme-width-height.html gtk-theme-width-height-ref.html
 == checkbox-baseline.html checkbox-baseline-ref.html
 == checkbox-radio-color.html checkbox-radio-color-ref.html
-skip-if(gtkWidget) == checkbox-clamp-01.html checkbox-clamp-01-ref.html
-skip-if(OSX||winWidget) == checkbox-clamp-02.html checkbox-clamp-02-ref.html
+skip-if(gtkWidget) fails-if(geckoview&&webrender) == checkbox-clamp-01.html checkbox-clamp-01-ref.html
+skip-if(OSX||winWidget) fails-if(geckoview&&webrender) == checkbox-clamp-02.html checkbox-clamp-02-ref.html
 fails-if(OSX) == checkbox-minimum-size.html checkbox-minimum-size-ref.html
--- a/layout/reftests/forms/input/file/reftest.list
+++ b/layout/reftests/forms/input/file/reftest.list
@@ -1,11 +1,11 @@
 fuzzy-if(gtkWidget||webrender,0-1,0-34) fails-if(Android) == simple.html simple-ref.xul
 fuzzy-if(gtkWidget||webrender,0-1,0-17) fails-if(Android) == rtl.html rtl-ref.xul
 fuzzy-if(gtkWidget||webrender,0-1,0-34) fails-if(Android) == size.html simple-ref.xul
 fuzzy-if(gtkWidget||webrender,0-1,0-10) fails-if(Android) == background.html background-ref.xul
 fuzzy-if(gtkWidget,0-1,0-10) fails-if(Android) == style.html style-ref.xul
 != width-clip.html width-clip-ref.html
 fails-if(Android) == color-inherit.html color-inherit-ref.html
-fuzzy-if(Android,0-2,0-2) fuzzy-if(OSX,0-34,0-134) fails-if(webrender&&!cocoaWidget) == dynamic-max-width.html dynamic-max-width-ref.html # bug 1496542 for webrender.
+fuzzy-if(Android,0-2,0-2) fuzzy-if(OSX,0-34,0-134) fails-if(webrender&&!(cocoaWidget||geckoview)) == dynamic-max-width.html dynamic-max-width-ref.html # bug 1496542 for webrender.
 == label-min-inline-size.html label-min-inline-size-ref.html
 == css-overflow.html css-overflow-ref.html
 == css-display.html css-display-ref.html
--- a/layout/reftests/forms/input/radio/reftest.list
+++ b/layout/reftests/forms/input/radio/reftest.list
@@ -1,10 +1,10 @@
 == label-dynamic.html label-dynamic-ref.html
 != checked-native.html checked-native-notref.html
 == checked-appearance-none.html about:blank
 == unchecked-appearance-none.html about:blank
 != checked-native.html about:blank
 != checked-native-notref.html about:blank
 skip-if(!gtkWidget) == gtk-theme-width-height.html gtk-theme-width-height-ref.html
-skip-if(gtkWidget) == radio-clamp-01.html radio-clamp-01-ref.html
+skip-if(gtkWidget) fails-if(geckoview&&webrender) == radio-clamp-01.html radio-clamp-01-ref.html
 skip-if(OSX||winWidget) == radio-clamp-02.html radio-clamp-02-ref.html
 fails-if(OSX) == radio-minimum-size.html radio-minimum-size-ref.html
--- a/layout/reftests/image-element/reftest.list
+++ b/layout/reftests/image-element/reftest.list
@@ -12,22 +12,22 @@ fuzzy-if(webrender&&winWidget,117-129,47
 == element-paint-recursion.html element-paint-recursion-ref.html
 == element-paint-continuation.html element-paint-continuation-ref.html
 == element-paint-transform-01.html element-paint-transform-01-ref.html
 random-if(d2d) == element-paint-transform-02.html element-paint-transform-02-ref.html # bug 587133
 fuzzy-if(d2d&&/^Windows\x20NT\x206\.1/.test(http.oscpu),0-16,0-90) == element-paint-background-size-01.html element-paint-background-size-01-ref.html
 == element-paint-background-size-02.html element-paint-background-size-02-ref.html
 fuzzy-if(skiaContent,0-255,0-4) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html # Bug 1475907
 fuzzy-if(d2d,0-255,0-24) == element-paint-transform-03.html element-paint-transform-03-ref.html
-fuzzy-if(asyncPan,0-2,0-140) fuzzy-if(skiaContent,0-3,0-106) fuzzy-if(webrender&&winWidget,134-222,1197-1588) == element-paint-native-widget.html element-paint-native-widget-ref.html   # in -ref the scrollframe is active and layerized differently with APZ
+fuzzy-if(asyncPan,0-2,0-140) fuzzy-if(skiaContent,0-3,0-106) fuzzy-if(webrender&&winWidget,134-222,1197-1588) fuzzy-if(geckoview&&webrender,7-7,23-787) == element-paint-native-widget.html element-paint-native-widget-ref.html   # in -ref the scrollframe is active and layerized differently with APZ
 fails-if(usesRepeatResampling&&!(webrender&&winWidget)) == element-paint-subimage-sampling-restriction.html about:blank
 == element-paint-clippath.html element-paint-clippath-ref.html
-fuzzy-if(webrender,36-36,712-715) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html
+fuzzy-if(webrender,36-36,712-738) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html
 fuzzy-if(skiaContent,0-1,0-326) == element-paint-sharpness-01b.html element-paint-sharpness-01c.html
-fuzzy-if(webrender,36-36,712-715) == element-paint-sharpness-01c.html element-paint-sharpness-01d.html
+fuzzy-if(webrender,36-36,712-738) == element-paint-sharpness-01c.html element-paint-sharpness-01d.html
 == element-paint-sharpness-02a.html element-paint-sharpness-02b.html
 == element-paint-sharpness-02b.html element-paint-sharpness-02c.html
 == element-paint-paintserversize-rounding-01.html element-paint-paintserversize-rounding-01-ref.html
 fuzzy-if(skiaContent,0-187,0-1191) == element-paint-paintserversize-rounding-02.html element-paint-paintserversize-rounding-02-ref.html # Linux32 from GCC update
 fuzzy-if(webrender,0-1,0-625) == element-paint-multiple-backgrounds-01a.html element-paint-multiple-backgrounds-01-ref.html
 fuzzy-if(webrender,0-1,0-625) == element-paint-multiple-backgrounds-01b.html element-paint-multiple-backgrounds-01-ref.html
 fuzzy-if(webrender,0-1,0-625) == element-paint-multiple-backgrounds-01c.html element-paint-multiple-backgrounds-01-ref.html
 == gradient-html-01.html gradient-html-01-ref.svg
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -140,17 +140,17 @@ fails-if(skiaContent&&OSX>=1010) == scal
 == mspace-1.html mspace-1-ref.html
 == mpadded-1.html mpadded-1-ref.html
 == mpadded-2.html mpadded-2-ref.html
 == mpadded-3.html mpadded-3-ref.html
 == mpadded-4.html mpadded-4-ref.html
 == mpadded-5.html mpadded-5-ref.html
 == mpadded-1-2.html mpadded-1-2-ref.html
 == mpadded-6.html mpadded-6-ref.html
-random-if(gtkWidget) == mpadded-7.html mpadded-7-ref.html # bug 1309430
+random-if(gtkWidget) fails-if(geckoview&&webrender) == mpadded-7.html mpadded-7-ref.html # bug 1309430
 random-if(gtkWidget) == mpadded-8.html mpadded-8-ref.html # bug 1309430
 random-if(gtkWidget) == mpadded-9.html mpadded-9-ref.html # bug 1309430
 == math-display.html math-display-ref.html
 == scriptlevel-1.html scriptlevel-1-ref.html
 == scriptlevel-movablelimits-1.html scriptlevel-movablelimits-1-ref.html
 == munderover-align-accent-false.html munderover-align-accent-false-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == munderover-align-accent-true.html munderover-align-accent-true-ref.html # Bug 1392106
 == munder-mover-align-accent-true.html munder-mover-align-accent-true-ref.html
@@ -280,21 +280,21 @@ fuzzy-if(d2d,0-7,0-1) == menclose-6-down
 fuzzy-if(skiaContent,0-2,0-3) == menclose-6-roundedbox.html menclose-6-ref.html
 == menclose-6-top.html menclose-6-ref.html
 == menclose-6-updiagonalarrow.html menclose-6-ref.html
 fuzzy-if(d2d,0-7,0-1) == menclose-6-updiagonalstrike.html menclose-6-ref.html
 == menclose-6-verticalstrike.html menclose-6-ref.html
 == menclose-6-phasorangle.html menclose-6-ref.html
 == mmultiscript-align.html mmultiscript-align-ref.html
 fails-if(winWidget) == subscript-italic-correction.html subscript-italic-correction-ref.html # bug 961482
-fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mathvariant-1a.html mathvariant-1a-ref.html # Bug 1010679, Bug 1392106
-fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mathvariant-1b.html mathvariant-1b-ref.html # Bug 1010679, Bug 1392106
-fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mathvariant-1c.html mathvariant-1c-ref.html # Bug 1010679, Bug 1392106
+fails-if(Android&&!webrender) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mathvariant-1a.html mathvariant-1a-ref.html # Bug 1010679, Bug 1392106
+fails-if(Android&&!webrender) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mathvariant-1b.html mathvariant-1b-ref.html # Bug 1010679, Bug 1392106
+fails-if(Android&&!webrender) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mathvariant-1c.html mathvariant-1c-ref.html # Bug 1010679, Bug 1392106
 == mathvariant-1d.html mathvariant-1d-ref.html
-fails-if(Android||OSX) == mathvariant-2.html mathvariant-2-ref.html # Bugs 1010678, 1010679
+fails-if(Android&&!webrender) fails-if(OSX) == mathvariant-2.html mathvariant-2-ref.html # Bugs 1010678, 1010679
 == mathvariant-3.html mathvariant-3-ref.html
 == mathvariant-4.html mathvariant-4-ref.html
 == mathvariant-5.html mathvariant-5-ref.html
 == dtls-1.html dtls-1-ref.html
 == dtls-2.html dtls-2-ref.html
 == dtls-3.html dtls-3-ref.html
 == ssty-1.html ssty-1-ref.html
 == ssty-2.html ssty-2-ref.html
@@ -349,31 +349,31 @@ random-if(gtkWidget) == rowlines-3-2.htm
 == mfrac-A-4.html mfrac-A-4-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mfrac-A-5.html mfrac-A-5-ref.html # bug 1309426
 == mfrac-A-6.html mfrac-A-6-ref.html
 == mfrac-A-7.html mfrac-A-7-ref.html
 == mfrac-A-8.html mfrac-A-8-ref.html
 == mfrac-B-1.html mfrac-B-1-ref.html
 == mfrac-B-2.html mfrac-B-2-3-ref.html
 == mfrac-B-3.html mfrac-B-2-3-ref.html
-== mfrac-B-4.html mfrac-B-4-5-ref.html
+fuzzy-if(geckoview&&webrender,0-198,0-781) == mfrac-B-4.html mfrac-B-4-5-ref.html
 == mfrac-B-5.html mfrac-B-4-5-ref.html
-== mfrac-B-6.html mfrac-B-6-7-ref.html
+fuzzy-if(geckoview&&webrender,0-198,0-781) == mfrac-B-6.html mfrac-B-6-7-ref.html
 == mfrac-B-7.html mfrac-B-6-7-ref.html
 fuzzy-if(OSX,0-1,0-100) fuzzy-if(skiaContent,0-1,0-14) == mfrac-C-1.html mfrac-C-1-ref.html
 == mfrac-C-2.html mfrac-C-2-ref.html
-== mfrac-C-3.html mfrac-C-3-ref.html
-== mfrac-C-4.html mfrac-C-4-ref.html
+fuzzy-if(geckoview&&webrender,0-198,0-776) == mfrac-C-3.html mfrac-C-3-ref.html
+fuzzy-if(geckoview&&webrender,0-198,0-270) == mfrac-C-4.html mfrac-C-4-ref.html
 fuzzy-if(OSX,0-1,0-100) fuzzy-if(skiaContent,0-1,0-14) == mfrac-D-1.html mfrac-D-1-ref.html
 == mfrac-D-2.html mfrac-D-2-ref.html
-== mfrac-D-3.html mfrac-D-3-ref.html
-== mfrac-D-4.html mfrac-D-4-ref.html
+fuzzy-if(geckoview&&webrender,0-198,0-776) == mfrac-D-3.html mfrac-D-3-ref.html
+fuzzy-if(geckoview&&webrender,0-198,0-270) == mfrac-D-4.html mfrac-D-4-ref.html
 == mfrac-E-1.html mfrac-E-1-ref.html
 == shadow-dom-1.html shadow-dom-1-ref.html
-pref(dom.meta-viewport.enabled,true) pref(font.size.inflation.emPerLine,25) fuzzy-if(webrender&&!gtkWidget,0-255,0-260) == font-inflation-1.html font-inflation-1-ref.html
+pref(dom.meta-viewport.enabled,true) pref(font.size.inflation.emPerLine,25) fuzzy-if(webrender&&!gtkWidget,0-255,0-324) == font-inflation-1.html font-inflation-1-ref.html
 test-pref(font.minimum-size.x-math,40) == default-font.html default-font-ref.html
 != radicalbar-1.html about:blank
 != radicalbar-1a.html about:blank
 != radicalbar-1b.html about:blank
 != radicalbar-1c.html about:blank
 != radicalbar-1d.html about:blank
 != radicalbar-2.html about:blank
 != radicalbar-2a.html about:blank
--- a/layout/reftests/meta-viewport/reftest.list
+++ b/layout/reftests/meta-viewport/reftest.list
@@ -7,17 +7,17 @@ default-preferences pref(dom.meta-viewpo
 == no-viewport.html initial-scale-0_5-ref.html
 == viewport-width.html initial-scale-0_5-ref.html
 == initial-scale-1.html no-zoom-ref.html
 == minimum-scale.html no-zoom-ref.html
 == negative-initial-and-maximum-scale.html initial-scale-0_5-ref.html
 == no-scalable-with-minimum-scale.html no-scalable-with-minimum-scale-ref.html
 == clamped-by-default-minimum-scale.html initial-scale-0_25-ref.html
 
-skip-if(!Android) == position-fixed-on-minimum-scale-size.html position-fixed-on-minimum-scale-size-ref.html
+skip-if(!Android) fails-if(geckoview&&webrender) == position-fixed-on-minimum-scale-size.html position-fixed-on-minimum-scale-size-ref.html
 == position-fixed-out-of-view.html about:blank
 
 # Skip below tests on Windows (bug 1516322) on Webrender (bug 1520096)
 skip-if(winWidget||webrender) == overflow-region.html overflow-region-ref.html
 skip-if(winWidget||webrender) == overflow-hidden-region.html overflow-region-ref.html
 skip-if(winWidget||webrender) == overflow-hidden-region-with-negative-left-positioned-element.html overflow-region-ref.html
 skip-if(winWidget||webrender) fails == horizontal-overflow-hidden-region.html horizontal-overflow-hidden-region-ref.html # bug 1508177
 skip-if(winWidget||webrender) == vertical-overflow-hidden-region.html about:blank
--- a/layout/reftests/reftest-sanity/reftest.list
+++ b/layout/reftests/reftest-sanity/reftest.list
@@ -31,18 +31,18 @@ HTTP == about:blank blank.html
 # same for data:
 == default.html data:text/html,<div>Text</div>
 == data:text/html,<div>Text</div> default.html
 HTTP == default.html data:text/html,<div>Text</div>
 HTTP == data:text/html,<div>Text</div> default.html
 != blank.html default.html
 HTTP != blank.html default.html
 
-== filter-1.xhtml filter-1-ref.xhtml
-== filter-2.xhtml filter-2-ref.xhtml
+fails-if(geckoview&&webrender) == filter-1.xhtml filter-1-ref.xhtml
+fails-if(geckoview&&webrender) == filter-2.xhtml filter-2-ref.xhtml
 
 # test that the MozReftestInvalidate event fires
 == invalidation.html about:blank
 == zoom-invalidation.html zoom-invalidation-ref.html # bug 773482
 
 # test that xulRuntime.OS works
 fails-if(xulRuntime.OS!="Linux"&&!Android) == data:text/html,<body>Linux data:text/html,<script>document.write(navigator.platform.substr(0,5))</script>
 fails-if(xulRuntime.OS!="WINNT") == data:text/html,<body>Win data:text/html,<script>document.write(navigator.platform.substr(0,3))</script>
@@ -144,31 +144,31 @@ test-pref(font.size.variable.x-western,2
 test-pref(font.size.variable.x-western,24) != font-default.html font-size-16.html
 fails test-pref(font.size.variable.x-western,false) == font-default.html font-size-16.html
 fails test-pref(font.size.variable.x-western,"foo") == font-default.html font-size-16.html
 ref-pref(font.size.variable.x-western,16) test-pref(font.size.variable.x-western,24) != font-default.html font-default.html
 ref-pref(font.size.variable.x-western,24) test-pref(font.size.variable.x-western,16) != font-default.html font-default.html
 ref-pref(font.size.variable.x-western,24) test-pref(font.size.variable.x-western,24) == font-default.html font-default.html
 
 # reftest syntax: fuzzy(0-maxPixelDifference,0-maxNumberDifferingPixels)
-fuzzy(0-1,0-250000) == fuzzy.html fuzzy-ref.html
-fuzzy(0-1,0-250000) != too-fuzzy.html fuzzy-ref.html
-fuzzy-if(true,0-1,0-250000) == fuzzy.html fuzzy-ref.html
-fuzzy-if(false,0-2,0-1) == fuzzy-ref.html fuzzy-ref.html
+noautofuzz fuzzy(0-1,0-250000) == fuzzy.html fuzzy-ref.html
+noautofuzz fuzzy(0-1,0-250000) != too-fuzzy.html fuzzy-ref.html
+noautofuzz fuzzy-if(true,0-1,0-250000) == fuzzy.html fuzzy-ref.html
+noautofuzz fuzzy-if(false,0-2,0-1) == fuzzy-ref.html fuzzy-ref.html
 # test some ranged fuzzes
-fuzzy(1-10,1-250000) fuzzy-if(false,5-10,0-250000) == fuzzy.html fuzzy-ref.html
-fuzzy(0-0,0-250000) != fuzzy.html fuzzy-ref.html
-fuzzy(0-1,0-2) != fuzzy.html fuzzy-ref.html
+noautofuzz fuzzy(1-10,1-250000) fuzzy-if(false,5-10,0-250000) == fuzzy.html fuzzy-ref.html
+noautofuzz fuzzy(0-0,0-250000) != fuzzy.html fuzzy-ref.html
+noautofuzz fuzzy(0-1,0-2) != fuzzy.html fuzzy-ref.html
 # If enabled, the following two should result in UNEXPECTED-PASS because
 # they are both overfuzzed
-# fuzzy(3-4,0-250000) == fuzzy.html fuzzy-ref.html
-# fuzzy(0-1,250001-250002) == fuzzy.html fuzzy-ref.html
+# noautofuzz fuzzy(3-4,0-250000) == fuzzy.html fuzzy-ref.html
+# noautofuzz fuzzy(0-1,250001-250002) == fuzzy.html fuzzy-ref.html
 #
 # When using 565 fuzzy.html and fuzzy-ref.html will compare as equal
-fails fuzzy-if(false,0-2,0-1) random-if(Android) == fuzzy.html fuzzy-ref.html
+noautofuzz fails fuzzy-if(false,0-2,0-1) random-if(Android) == fuzzy.html fuzzy-ref.html
 
 # Test that reftest-no-paint fails correctly.
 fails-if(layerChecksEnabled) == reftest-no-paint.html reftest-no-paint-ref.html
 
 skip-if(!asyncPan||!browserIsRemote) == async-scroll-1a.html async-scroll-1-ref.html
 
 # Disable low-res painting for this test as it will cause more to
 # be drawn than we want.
--- a/layout/reftests/svg/as-image/reftest.list
+++ b/layout/reftests/svg/as-image/reftest.list
@@ -94,19 +94,19 @@ fuzzy-if(winWidget,0-1,0-10000) test-pre
 fuzzy-if(winWidget,0-1,0-20000) test-pref(svg.context-properties.content.enabled,true) == context-stroke-opacity-02.html context-fill-or-stroke-opacity-02-ref.html # Bug 1377327
 fuzzy-if(winWidget,0-1,0-10000) test-pref(svg.context-properties.content.enabled,true) == context-stroke-opacity-03.html context-fill-or-stroke-opacity-03-ref.html # Bug 1377327
 fuzzy-if(winWidget,0-1,0-10000) test-pref(svg.context-properties.content.enabled,true) == context-stroke-opacity-04.html blue100x100-ref.html # Bug 1377327
 fuzzy-if(winWidget,0-1,0-10000) test-pref(svg.context-properties.content.enabled,true) == context-stroke-opacity-05.html blue100x100-ref.html # Bug 1377327
 
 # Simple <img> tests
 == img-simple-1.html  lime100x100-ref.html
 == img-simple-2.html  lime100x100-ref.html
-fuzzy-if(skiaContent,0-255,0-350) == img-simple-3.html  img-simple-3-ref.html
+fuzzy-if(skiaContent,0-255,0-350) fuzzy-if(geckoview&&webrender,0-255,0-3714) == img-simple-3.html  img-simple-3-ref.html
 == img-simple-4.html  lime100x100-ref.html
-fuzzy-if(skiaContent,0-255,0-90) == img-simple-5.html  img-simple-5-ref.html
+fuzzy-if(skiaContent,0-255,0-90) fuzzy-if(geckoview&&webrender,0-255,0-1266) == img-simple-5.html  img-simple-5-ref.html
 == img-simple-6.html  lime100x100-ref.html
 fuzzy-if(skiaContent,0-255,0-27) == img-simple-7.html  img-simple-7-ref.html
 
 # Test with mix of <html:img> and <svg:image> referring to the same images,
 # with a variety of preserveAspectRatio values in play.
 random == img-and-image-1.html img-and-image-1-ref.svg # bug 645267
 
 # More complex <img> tests
@@ -137,17 +137,17 @@ fuzzy-if(d2d,0-16,0-10) == img-content-o
 
 == img-height-meet-1.html   img-height-meet-1-ref.html
 == img-height-meet-2.html   img-height-meet-2-ref.html
 == img-height-slice-1.html  img-height-slice-1-ref.html
 == img-height-slice-2.html  img-height-slice-2-ref.html
 
 == img-width-meet-1.html   img-width-meet-1-ref.html
 == img-width-meet-2.html   img-width-meet-2-ref.html
-fuzzy-if(webrender,255-255,3-3) == img-width-slice-1.html  img-width-slice-1-ref.html
+fuzzy-if(webrender,255-255,3-3) fuzzy-if(geckoview&&webrender,255-255,14-269) == img-width-slice-1.html  img-width-slice-1-ref.html
 == img-width-slice-2.html  img-width-slice-2-ref.html
 
 # Alternate version of "width & height both non-%-valued" tests, but now
 # with no explicit viewBox, to trigger "synthesize-viewBox" behavior
 == img-novb-widthAndHeight-meet-1-em.html  img-novb-widthAndHeight-all-1-ref.html
 == img-novb-widthAndHeight-meet-1-px.html  img-novb-widthAndHeight-all-1-ref.html
 == img-novb-widthAndHeight-slice-1-em.html img-novb-widthAndHeight-all-1-ref.html
 == img-novb-widthAndHeight-slice-1-px.html img-novb-widthAndHeight-all-1-ref.html
--- a/layout/reftests/svg/filters/css-filter-chains/reftest.list
+++ b/layout/reftests/svg/filters/css-filter-chains/reftest.list
@@ -1,7 +1,7 @@
 # These tests verify that CSS filter chains behave properly.
 # e.g. filter: blur(3px) grayscale(0.5) invert(0.2);
 
 # Some platforms render this complex filter chain a little differently, and that's ok.
 fuzzy(0-5,0-13638) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&layersGPUAccelerated,0-35,0-13638) fuzzy-if(webrender,4-6,12000-19484) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
 == moz-element.html moz-element-ref.html
-fuzzy-if(webrender,13-15,7682-7966) == same-filter.html same-filter-ref.html
+fuzzy-if(webrender,13-15,7676-7966) == same-filter.html same-filter-ref.html
--- a/layout/reftests/svg/filters/css-filters/reftest.list
+++ b/layout/reftests/svg/filters/css-filters/reftest.list
@@ -33,39 +33,39 @@ fuzzy-if(webrender,3-5,5760-8168) == blu
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == grayscale.html grayscale-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == grayscale-one.html grayscale-one-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == grayscale-over-one.html grayscale-over-one-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == grayscale-percent.html grayscale-percent-ref.html
 fuzzy-if(webrender,0-1,0-10000) == grayscale-zero.html grayscale-zero-ref.html
 == hue-rotate.html hue-rotate-ref.html
 == hue-rotate-360.html hue-rotate-360-ref.html
 == hue-rotate-grad.html hue-rotate-grad-ref.html
-fuzzy-if(webrender,2-2,7500-7500) fuzzy-if(d2d,0-2,0-7500) == hue-rotate-multichannel.html hue-rotate-multichannel-ref.html
+fuzzy-if(webrender&&!geckoview,2-2,7500-7500) fuzzy-if(d2d,0-2,0-7500) == hue-rotate-multichannel.html hue-rotate-multichannel-ref.html
 == hue-rotate-negative.html hue-rotate-negative-ref.html
 == hue-rotate-over-360.html hue-rotate-over-360-ref.html
 == hue-rotate-rad.html hue-rotate-rad-ref.html
 == hue-rotate-turn.html hue-rotate-turn-ref.html
 == hue-rotate-zero.html hue-rotate-zero-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == invert.html invert-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||webrender,0-1,0-10000) == invert-half.html invert-half-ref.html
 == invert-one.html invert-one-ref.html
 == invert-over-one.html invert-over-one-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == invert-percent.html invert-percent-ref.html
 == invert-zero.html invert-zero-ref.html
-fuzzy-if(webrender,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == opacity.html opacity-ref.html
+fuzzy-if(webrender&&!geckoview,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == opacity.html opacity-ref.html
 == opacity-one.html opacity-one-ref.html
 == opacity-over-one.html opacity-over-one-ref.html
 fuzzy-if(skiaContent,0-1,0-10000) == opacity-over-one-translucent-source.html opacity-over-one-translucent-source-ref.html
-fuzzy-if(webrender,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == opacity-percent.html opacity-percent-ref.html
+fuzzy-if(webrender&&!geckoview,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == opacity-percent.html opacity-percent-ref.html
 == opacity-zero.html opacity-zero-ref.html
 == saturate.html saturate-ref.html
-fuzzy-if(webrender,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == saturate-desaturate.html saturate-desaturate-ref.html
+fuzzy-if(webrender&&!geckoview,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == saturate-desaturate.html saturate-desaturate-ref.html
 == saturate-extreme.html saturate-extreme-ref.html
 == saturate-one.html saturate-one-ref.html
 == saturate-percent.html saturate-percent-ref.html
-fuzzy-if(webrender,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == saturate-zero.html saturate-zero-ref.html
+fuzzy-if(webrender&&!geckoview,1-1,10000-10000) fuzzy-if(d2d,0-1,0-10000) == saturate-zero.html saturate-zero-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == sepia.html sepia-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == sepia-one.html sepia-one-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == sepia-over-one.html sepia-over-one-ref.html
 fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == sepia-percent.html sepia-percent-ref.html
 == sepia-zero.html sepia-zero-ref.html
 
 fuzzy(0-2,0-125000) == scale-filtered-content-01.html scale-filtered-content-01-ref.html
--- a/layout/reftests/svg/filters/reftest.list
+++ b/layout/reftests/svg/filters/reftest.list
@@ -34,17 +34,17 @@ fuzzy-if(d2d||skiaContent,0-1,0-10000) =
 == feConvolveMatrix-2.svg feConvolveMatrix-2-ref.svg
 
 == feDisplacementMap-1.svg feDisplacementMap-1-ref.svg
 == feDisplacementMap-2.svg feDisplacementMap-2-ref.svg
 
 fuzzy-if(d2d,0-1,0-6400) fuzzy-if(skiaContent,0-1,0-1600)  == feFlood-1.svg feFlood-1-ref.svg
 skip-if(d2d) fuzzy-if(skiaContent,0-1,0-6400) == feFlood-2.svg feFlood-2-ref.svg
 
-fuzzy(0-1,0-6400) fuzzy-if(skiaContent,0-1,0-6404) fuzzy-if(webrender,178-178,3036-3036) == feGaussianBlur-1.svg feGaussianBlur-1-ref.svg
+fuzzy(0-1,0-6400) fuzzy-if(skiaContent,0-1,0-6404) fuzzy-if(webrender,178-178,3036-3042) == feGaussianBlur-1.svg feGaussianBlur-1-ref.svg
 fuzzy-if(webrender,0-2,0-304) == feGaussianBlur-2.svg feGaussianBlur-2-ref.svg
 # != feGaussianBlur-3.svg feGaussianBlur-3-ref.svg
 fuzzy-if(webrender,3-5,5760-8168) == feGaussianBlur-4.svg feGaussianBlur-4-ref.svg
 == feGaussianBlur-5.svg feGaussianBlur-5-ref.svg
 == feGaussianBlur-6.svg feGaussianBlur-6-ref.svg
 skip-if(d2d) == feGaussianBlur-cap-large-directional-radius-on-software.html feGaussianBlur-cap-large-directional-radius-on-software-ref.html
 
 != feImage-1.svg about:blank # (Make sure our image renders at all)
@@ -60,17 +60,17 @@ skip-if(d2d) == feGaussianBlur-cap-large
 == feOffset-1.svg feOffset-1-ref.svg
 == feOffset-2.svg feOffset-2-ref.svg
 
 == feTile-1.svg feTile-1-ref.svg
 == feTile-2.svg feTile-2-ref.svg
 
 # no tests for feTurbulence
 
-== filter-clipped-rect-01.svg pass.svg
+fuzzy-if(geckoview&&webrender,0-8,0-199) == filter-clipped-rect-01.svg pass.svg
 == filter-in-pattern-01.svg pass.svg
 fuzzy(0-5,0-67) != filter-in-pattern-02.svg filter-in-pattern-02-ref.svg
 random-if(winWidget) == filter-in-mask-01.svg pass.svg # bug 1356139
 == filter-in-mask-02.svg pass.svg
 == filter-inner-svg-01.svg pass.svg
 == filter-inner-svg-02.svg pass.svg
 == filter-inner-svg-03.svg pass.svg
 fails == filter-marked-line-01.svg pass.svg # bug 477704
--- a/layout/reftests/svg/filters/svg-filter-chains/reftest.list
+++ b/layout/reftests/svg/filters/svg-filter-chains/reftest.list
@@ -1,16 +1,16 @@
 # These tests verify that SVG filter chains behave properly.
 # e.g. filter: url(#f1) url(#f2) url(#f3)
 
 == clip-input.svg clip-input-ref.svg
 == clip-original-SourceGraphic.svg clip-original-SourceGraphic-ref.svg
 == clip-output.svg clip-output-ref.svg
-fuzzy-if(webrender,3-5,17844-19776) == default-subregion.svg default-subregion-ref.svg
+fuzzy-if(webrender,3-5,17844-20155) == default-subregion.svg default-subregion-ref.svg
 == different-FillPaint-filter-regions.svg different-FillPaint-filter-regions-ref.svg
 == different-StrokePaint-filter-regions.svg different-StrokePaint-filter-regions-ref.svg
 == dont-clip-previous-primitives.svg dont-clip-previous-primitives-ref.svg
 == intersecting-filter-regions.svg intersecting-filter-regions-ref.svg
 fuzzy-if(webrender,9-9,5168-5536) == long-chain.svg simple-chain-ref.svg
 fuzzy-if(webrender,9-9,5168-5536) == multiple-primitives-per-filter.svg simple-chain-ref.svg
-fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-173) fuzzy-if(webrender,9-9,5128-5492) == second-filter-uses-SourceAlpha.svg second-filter-uses-SourceAlpha-ref.svg
+fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-173) fuzzy-if(webrender,9-9,5128-5494) == second-filter-uses-SourceAlpha.svg second-filter-uses-SourceAlpha-ref.svg
 fuzzy-if(webrender,9-9,5168-5536) == second-filter-uses-SourceGraphic.svg simple-chain-ref.svg
 == simple-chain.svg simple-chain-ref.svg
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -31,17 +31,17 @@ include svg-integration/reftest.list
 
 == baseline-middle-01.svg pass.svg
 
 skip-if(Android) == blend-color-burn.svg blend-color-burn-ref.svg
 skip-if(Android) == blend-color-dodge.svg blend-color-dodge-ref.svg
 # == blend-color.svg blend-color-ref.svg
 skip-if(Android) == blend-darken.svg blend-darken-ref.svg
 skip-if(Android) == blend-difference.svg blend-difference-ref.svg
-skip-if(Android) fuzzy-if(skiaContent,0-1,0-1600) == blend-exclusion.svg blend-exclusion-ref.svg
+skip-if(Android) fuzzy-if(skiaContent,0-1,0-1600) fuzzy-if(geckoview&&webrender,0-4,0-254) == blend-exclusion.svg blend-exclusion-ref.svg
 # == blend-hard-light.svg blend-hard-light-ref.svg
 # == blend-hue.svg blend-hue-ref.svg
 skip-if(Android) == blend-layer-blend.svg blend-layer-blend-ref.svg
 skip-if(Android) == blend-layer-filter.svg blend-layer-filter-ref.svg
 skip-if(Android) == blend-layer-mask.svg blend-layer-mask-ref.svg
 skip-if(Android) == blend-layer-opacity.svg blend-layer-opacity-ref.svg
 skip-if(Android) == blend-lighten.svg blend-lighten-ref.svg
 # == blend-luminosity.svg blend-luminosity-ref.svg
@@ -331,32 +331,32 @@ random-if(gtkWidget) == objectBoundingBo
 
 == opacity-and-gradient-01.svg pass.svg
 skip-if(d2d) fuzzy-if(cocoaWidget,0-1,0-99974) fuzzy-if(skiaContent,0-1,0-200000) == opacity-and-gradient-02.svg opacity-and-gradient-02-ref.svg
 == opacity-and-pattern-01.svg pass.svg
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||skiaContent,0-1,0-10000) == opacity-and-transform-01.svg opacity-and-transform-01-ref.svg
 
 fuzzy-if(Android,0-8,0-200) == outer-svg-border-and-padding-01.svg outer-svg-border-and-padding-01-ref.svg
 
-fuzzy(0-16,0-193) fuzzy-if(skiaContent,0-7,0-193) fuzzy-if(webrender,54-54,124-124) == outline.html outline-ref.html # Bug 1392106, Bug 1503525
+fuzzy(0-16,0-193) fuzzy-if(skiaContent,0-7,0-193) fuzzy-if(webrender,54-54,124-435) == outline.html outline-ref.html # Bug 1392106, Bug 1503525
 
 == overflow-on-outer-svg-01.svg overflow-on-outer-svg-01-ref.svg
 == overflow-on-outer-svg-02a.xhtml overflow-on-outer-svg-02-ref.xhtml
 == overflow-on-outer-svg-02b.xhtml overflow-on-outer-svg-02-ref.xhtml
 == overflow-on-outer-svg-02c.xhtml overflow-on-outer-svg-02-ref.xhtml
 == overflow-on-outer-svg-02d.xhtml overflow-on-outer-svg-02-ref.xhtml
 == overflow-on-outer-svg-03a.xhtml overflow-on-outer-svg-03-ref.xhtml
 == overflow-on-outer-svg-03b.xhtml overflow-on-outer-svg-03-ref.xhtml
 
 == paint-on-maskLayer-1a.html paint-on-maskLayer-1-ref.html
 == paint-on-maskLayer-1b.html paint-on-maskLayer-1-ref.html
 == paint-on-maskLayer-1c.html paint-on-maskLayer-1-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-5) == paint-order-01.svg paint-order-01-ref.svg
 == paint-order-02.svg paint-order-02-ref.svg
-fuzzy-if(webrender,72-72,96-143) == paint-order-03.svg paint-order-03-ref.svg
+fuzzy-if(webrender,72-73,96-1804) == paint-order-03.svg paint-order-03-ref.svg
 
 #fuzzy(0-23,0-60) fails-if(d2d) == path-01.svg path-01-ref.svg
 == path-02.svg pass.svg
 == path-04.svg pass.svg
 == path-05.svg pass.svg
 fuzzy-if(skiaContent,0-1,0-400) == path-06.svg path-06-ref.svg
 == path-07.svg path-07-ref.svg
 == path-08.svg pass.svg
@@ -370,32 +370,32 @@ fuzzy(0-1,0-5) skip-if(Android) == patte
 == pattern-invalid-01.svg pattern-invalid-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-5) == pattern-live-01a.svg pattern-live-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-5) == pattern-live-01b.svg pattern-live-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-5) == pattern-live-01c.svg pattern-live-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-5) == pattern-scale-01a.svg pattern-scale-01-ref.svg
 == pattern-scale-01b.svg pattern-scale-01-ref.svg
 fuzzy-if(skiaContent,0-3,0-5) == pattern-scale-01c.svg pattern-scale-01-ref.svg
 fuzzy-if(webrender,0-2,0-227) == pattern-transform-presence-01.svg pattern-transform-presence-01-ref.svg
-fuzzy-if(skiaContent||webrender,0-72,0-871) == pattern-transformed-01.svg pattern-transformed-01-ref.svg
+fuzzy-if(skiaContent||webrender,0-72,0-1245) == pattern-transformed-01.svg pattern-transformed-01-ref.svg
 
 == polygon-01.svg polygon-01-ref.svg
 == polygon-marker-01.svg pass.svg
 == polygon-points-negative-01.svg pass.svg
 == polyline-points-invalid-01.svg pass.svg
 
 == pseudo-classes-01.svg pass.svg
 # This test depends on :visited styles (which are asynchronous), so we run
 # it in layout/style/test/test_visited_reftests.html instead of using the
 # reftest harness.
 # == pseudo-classes-02.svg pseudo-classes-02-ref.svg
 
 == radialGradient-basic-01.svg pass.svg
 == radialGradient-basic-02.svg pass.svg
-fuzzy-if(cocoaWidget,0-4,0-15982) fuzzy-if(winWidget,0-4,0-92) fuzzy-if(skiaContent,0-4,0-60) == radialGradient-basic-03.svg radialGradient-basic-03-ref.svg
+fuzzy-if(cocoaWidget,0-4,0-15982) fuzzy-if(winWidget,0-4,0-92) fuzzy-if(skiaContent,0-4,0-60) fuzzy-if(geckoview&&webrender,0-4,0-159) == radialGradient-basic-03.svg radialGradient-basic-03-ref.svg
 == radialGradient-basic-04.svg pass.svg
 == radialGradient-fr-01.svg pass.svg
 fuzzy(0-1,0-3235) fuzzy-if(winWidget,0-1,0-7030) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg
 
 fuzzy-if(skiaContent,0-1,0-3600) == rect-01.svg pass.svg
 == rect-02.svg pass.svg
 == rect-03.svg pass.svg
 == rect-04.svg pass.svg
@@ -569,18 +569,18 @@ pref(layout.css.devPixelsPerPx,"1.0") ==
 == currentColor-override-flood.svg pass.svg
 == currentColor-override-lighting.svg currentColor-override-lighting-ref.svg
 == currentColor-override-stop.svg pass.svg
 
 == mask-invalidation.html mask-invalidation-ref.html
 == overflow-visible-image.html overflow-visible-image-ref.html
 
 # Shadow DOM id tracking.
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-1.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-2.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-3.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-4.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-5.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-6.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-7.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-8.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-9.html fragid-shadow-ref.html # Bug 1392106
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == fragid-shadow-10.html fragid-shadow-ref.html # Bug 1392106
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-1.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-2.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-3.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-4.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-5.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-6.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-7.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-8.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-9.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(geckoview&&webrender) == fragid-shadow-10.html fragid-shadow-ref.html # Bug 1392106, bug 1560367 for GV+WR
--- a/layout/reftests/svg/svg-integration/clip-path/reftest.list
+++ b/layout/reftests/svg/svg-integration/clip-path/reftest.list
@@ -15,32 +15,32 @@
 == clip-path-polygon-011.html clip-path-stripes-001-ref.html
 == clip-path-polygon-012.html clip-path-stripes-001-ref.html
 fuzzy-if(skiaContent,0-1,0-20) fuzzy-if(webrender&&gtkWidget,8-8,20-20) fails-if(webrender&&!gtkWidget) == clip-path-polygon-013.html clip-path-stripes-003-ref.html
 
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-001.html clip-path-circle-001-ref.html
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-002.html clip-path-circle-001-ref.html
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-003.html clip-path-circle-001-ref.html
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-004.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-005.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,699-710) == clip-path-circle-005.html clip-path-circle-002-ref.html
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-006.html clip-path-circle-001-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-007.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-008.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,699-710) == clip-path-circle-007.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,699-710) == clip-path-circle-008.html clip-path-circle-002-ref.html
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-009.html clip-path-circle-003-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-010.html clip-path-circle-004-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-011.html clip-path-circle-005-ref.html
+fuzzy-if(webrender,35-35,699-731) == clip-path-circle-010.html clip-path-circle-004-ref.html
+fuzzy-if(webrender,35-35,699-719) == clip-path-circle-011.html clip-path-circle-005-ref.html
 fuzzy-if(webrender,35-35,699-708) == clip-path-circle-012.html clip-path-circle-006-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-013.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-014.html clip-path-circle-007-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-015.html clip-path-circle-008-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-016.html clip-path-circle-009-ref.html
-fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-9) fuzzy-if(webrender,35-35,699-708) == clip-path-circle-017.html clip-path-circle-007-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-018.html clip-path-circle-010-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-019.html clip-path-circle-002-ref.html
-fuzzy-if(webrender,35-35,699-708) == clip-path-circle-020.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,699-710) == clip-path-circle-013.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,34-35,699-882) == clip-path-circle-014.html clip-path-circle-007-ref.html
+fuzzy-if(webrender,34-35,699-901) == clip-path-circle-015.html clip-path-circle-008-ref.html
+fuzzy-if(webrender,34-35,699-836) == clip-path-circle-016.html clip-path-circle-009-ref.html
+fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-16,0-9) fuzzy-if(webrender,34-35,699-882) == clip-path-circle-017.html clip-path-circle-007-ref.html
+fuzzy-if(webrender,35-35,699-712) == clip-path-circle-018.html clip-path-circle-010-ref.html
+fuzzy-if(webrender,35-35,699-710) == clip-path-circle-019.html clip-path-circle-002-ref.html
+fuzzy-if(webrender,35-35,699-710) == clip-path-circle-020.html clip-path-circle-002-ref.html
 fuzzy-if(webrender&&(winWidget||cocoaWidget),0-1,0-5) == clip-path-circle-021.html clip-path-circle-021-ref.html
 
 fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-001.html clip-path-ellipse-001-ref.html
 fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-002.html clip-path-ellipse-001-ref.html
 fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-003.html clip-path-ellipse-001-ref.html
 fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-004.html clip-path-ellipse-001-ref.html
 fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-005.html clip-path-ellipse-001-ref.html
 fuzzy-if(webrender,36-36,1099-1100) == clip-path-ellipse-006.html clip-path-ellipse-001-ref.html
--- a/layout/reftests/svg/text/reftest.list
+++ b/layout/reftests/svg/text/reftest.list
@@ -1,16 +1,16 @@
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender&&winWidget,122-127,221-254) == simple.svg simple-ref.html # Bug 1392106
 == simple-2.svg simple.svg
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender&&winWidget,122-127,221-254) == simple-underline.svg simple-underline-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-underline-scaled.svg simple-underline-scaled-ref.svg # Bug 1392106
 fuzzy-if(webrender&&winWidget,119-166,255-318) fuzzy-if(webrender&&OSX,1-1,1-1) == simple-anchor-end-bidi.svg simple-anchor-end-bidi-ref.html
 fuzzy-if(webrender&&winWidget,117-138,182-204) == simple-anchor-end-rtl.svg simple-anchor-end-rtl-ref.html
 fuzzy-if(webrender&&winWidget,119-137,220-250) == simple-anchor-end.svg simple-anchor-end-ref.html
-fuzzy-if(skiaContent&&dwrite,0-104,0-131) fuzzy-if(cocoaWidget,0-143,0-124) fuzzy-if(webrender&&!gtkWidget,79-200,109-319) == simple-anchor-middle-bidi.svg simple-anchor-middle-bidi-ref.html
+fuzzy-if(skiaContent&&dwrite,0-104,0-131) fuzzy-if(cocoaWidget,0-143,0-124) fuzzy-if(webrender&&!(gtkWidget||geckoview),79-200,109-319) == simple-anchor-middle-bidi.svg simple-anchor-middle-bidi-ref.html
 fuzzy-if(webrender&&winWidget,132-138,188-207) == simple-anchor-middle-rtl.svg simple-anchor-middle-rtl-ref.html
 fuzzy-if(skiaContent,0-111,0-81) fuzzy-if(webrender&&winWidget,122-181,221-257) == simple-anchor-middle.svg simple-anchor-middle-ref.html
 fuzzy-if(webrender&&winWidget,132-138,261-319) == simple-bidi.svg simple-bidi-ref.html
 == simple-bidi-2.svg simple-bidi.svg
 
 == simple-dx.svg simple.svg
 == simple-dx-2.svg simple-dx-2-ref.svg
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-dx-anchor-end-bidi.svg simple-dx-anchor-end-bidi-ref.svg # Bug 1392106
@@ -178,28 +178,28 @@ fuzzy-if(skiaContent&&winWidget,0-105,0-
 fuzzy-if(skiaContent&&winWidget,0-53,0-112) == mask-content-2.svg mask-content-2-ref.svg
 
 # text and clipPaths
 == clipPath-applied.svg clipPath-applied-ref.svg
 fuzzy-if(skiaContent&&winWidget,0-105,0-56) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == clipPath-content.svg clipPath-content-ref.svg # Bug 1392106
 fuzzy-if(skiaContent&&winWidget,0-53,0-112) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == clipPath-content-2.svg clipPath-content-2-ref.svg # Bug 1392106
 
 # text and patterns
-fuzzy-if(cocoaWidget,0-1,0-6) fuzzy-if(skiaContent,0-74,0-385) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == pattern-content.svg pattern-content-ref.svg # Bug 1392106
+fuzzy-if(cocoaWidget,0-1,0-6) fuzzy-if(skiaContent,0-74,0-385) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(geckoview&&webrender,0-49,0-1793) == pattern-content.svg pattern-content-ref.svg # Bug 1392106
 
 # text and filters
 fuzzy-if(skiaContent&&winWidget,0-126,0-336) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == filter-applied.svg filter-applied-ref.svg # Bug 1392106
 
 # vertical text
 fuzzy-if(skiaContent,0-1,0-80) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-vertical-dx.svg textpath-vertical-dx-ref.svg # Bug 1392106
 
 # selection
 needs-focus == deselectAll.svg deselectAll-ref.svg
 fuzzy-if(skiaContent,0-1,0-250) needs-focus == selectSubString.svg selectSubString-ref.svg
 fuzzy-if(skiaContent,0-1,0-600) needs-focus == selectSubString-2.svg selectSubString-2-ref.svg
 fuzzy-if(skiaContent,0-1,0-250) needs-focus == selectSubString-3.svg selectSubString-3-ref.svg
-random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender,1-1,237-237) needs-focus fuzzy-if(webrender&&winWidget,125-148,221-254) fuzzy-if(webrender&&OSX,1-1,35-35) == simple-selection.svg simple-selection-ref.html # Bug 1392106
-fuzzy-if(skiaContent,0-1,0-100) fuzzy-if(webrender,1-1,575-575) needs-focus fuzzy-if(webrender&&winWidget,134-148,261-318) fuzzy-if(webrender&&OSX,1-1,65-65) == simple-bidi-selection.svg simple-bidi-selection-ref.html
-fuzzy-if(skiaContent,0-1,0-50) fuzzy-if(webrender,1-1,237-237) needs-focus fuzzy-if(webrender&&winWidget,127-148,221-254) fuzzy-if(webrender&&OSX,1-46,19-196) == simple-fill-color-selection.svg simple-fill-color-selection-ref.html
-fuzzy-if(skiaContent,0-1,0-150) fuzzy-if(webrender,1-1,222-222) needs-focus fuzzy-if(webrender&&winWidget,125-148,221-254) fuzzy-if(webrender&&OSX,1-1,35-35) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-underline-selection.svg simple-underline-selection-ref.html # Bug 1392106
-fuzzy-if(skiaContent,0-1,0-300) fuzzy-if(webrender,1-1,934-934) needs-focus fuzzy-if(webrender&&winWidget,134-152,432-501) fuzzy-if(webrender&&OSX,1-1,119-123) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == multiple-text-selection.svg multiple-text-selection-ref.html # Bug 1392106
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(webrender&&!geckoview,1-1,35-237) needs-focus fuzzy-if(webrender&&winWidget,125-148,221-254) == simple-selection.svg simple-selection-ref.html # Bug 1392106
+fuzzy-if(skiaContent,0-1,0-100) fuzzy-if(webrender&&!geckoview,1-1,65-575) needs-focus fuzzy-if(webrender&&winWidget,134-148,261-318) == simple-bidi-selection.svg simple-bidi-selection-ref.html
+fuzzy-if(skiaContent,0-1,0-50) fuzzy-if(webrender&&!geckoview,1-1,46-237) needs-focus fuzzy-if(webrender&&winWidget,127-148,221-254) fuzzy-if(webrender&&OSX,1-46,19-196) == simple-fill-color-selection.svg simple-fill-color-selection-ref.html
+fuzzy-if(skiaContent,0-1,0-150) fuzzy-if(webrender&&!geckoview,1-1,35-222) needs-focus fuzzy-if(webrender&&winWidget,125-148,221-254) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == simple-underline-selection.svg simple-underline-selection-ref.html # Bug 1392106
+fuzzy-if(skiaContent,0-1,0-300) fuzzy-if(webrender&&!geckoview,1-1,119-934) needs-focus fuzzy-if(webrender&&winWidget,134-152,432-501) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == multiple-text-selection.svg multiple-text-selection-ref.html # Bug 1392106
 needs-focus == multiple-chunks-selection.svg multiple-chunks-selection-ref.svg
 fuzzy-if(skiaContent,0-1,0-200) needs-focus == textpath-selection.svg textpath-selection-ref.svg
--- a/layout/reftests/table-bordercollapse/reftest.list
+++ b/layout/reftests/table-bordercollapse/reftest.list
@@ -105,16 +105,16 @@ random-if(/^Windows\x20NT\x206\.1/.test(
 == bordercolor-3.html bordercolor-3-ref.html
 == bordercolor-4.html bordercolor-4-ref.html
 == empty-toprow.html empty-toprow-ref.html
 == double_borders.html double_borders_ref.html
 == border-collapse-rtl.html border-collapse-rtl-ref.html
 # Fuzzy because border-collapsed borders are not antialiased, since each segment is painted separately.
 # So get 40 pixels of fuzz, 20 at each beveled corner (because the border width
 # is 20px).
-fuzzy(0-255,0-40) == border-style-outset-becomes-groove.html border-style-outset-becomes-groove-ref.html
+fuzzy(0-255,0-40) fails-if(geckoview&&webrender) == border-style-outset-becomes-groove.html border-style-outset-becomes-groove-ref.html
 # Fuzzy because border-collapsed borders are not antialiased, since each segment is painted separately.
 # So get 40 pixels of fuzz, 20 at each beveled corner (because the border width
 # is 20px).
-fuzzy(0-255,0-40) == border-style-inset-becomes-ridge.html border-style-inset-becomes-ridge-ref.html
+fuzzy(0-255,0-40) fails-if(geckoview&&webrender) == border-style-inset-becomes-ridge.html border-style-inset-becomes-ridge-ref.html
 fuzzy(0-2,0-11000) == 1324524.html 1324524-ref.html
 == 1384602-1a.html 1384602-1-ref.html
 == 1384602-1b.html 1384602-1-ref.html
--- a/layout/reftests/text-stroke/reftest.list
+++ b/layout/reftests/text-stroke/reftest.list
@@ -1,10 +1,10 @@
 # basic tests for webkit-text-stroke
 # fuzzy is needed here for platform dependent backends
 
 # These fail on Linux without webrender due to lack of antialiasing of the HTML text stroke
-fuzzy(0-64,0-47) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-001.html webkit-text-stroke-property-001-ref.html
-fuzzy(0-4,0-24) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-002.html webkit-text-stroke-property-002-ref.html
-fuzzy(0-48,0-28) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-003.html webkit-text-stroke-property-003-ref.html
-fuzzy(0-64,0-33) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-004.html webkit-text-stroke-property-004-ref.html
-fuzzy(0-64,0-47) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-005.html webkit-text-stroke-property-005-ref.html
+fuzzy(0-64,0-47) fails-if(gtkWidget&&!webrender) fuzzy-if(geckoview&&webrender,0-64,0-344) == webkit-text-stroke-property-001.html webkit-text-stroke-property-001-ref.html
+fuzzy(0-4,0-24) fails-if(gtkWidget&&!webrender) fuzzy-if(geckoview&&webrender,0-3,0-1476) == webkit-text-stroke-property-002.html webkit-text-stroke-property-002-ref.html
+fuzzy(0-48,0-28) fails-if(gtkWidget&&!webrender) fuzzy-if(geckoview&&webrender,0-63,0-42) == webkit-text-stroke-property-003.html webkit-text-stroke-property-003-ref.html
+fuzzy(0-64,0-33) fails-if(gtkWidget&&!webrender) fuzzy-if(geckoview&&webrender,0-48,0-342) == webkit-text-stroke-property-004.html webkit-text-stroke-property-004-ref.html
+fuzzy(0-64,0-47) fails-if(gtkWidget&&!webrender) fuzzy-if(geckoview&&webrender,0-64,0-770) == webkit-text-stroke-property-005.html webkit-text-stroke-property-005-ref.html
 fuzzy(0-71,0-10) fails-if(gtkWidget&&!webrender) == webkit-text-stroke-property-006.html webkit-text-stroke-property-006-ref.html
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -188,17 +188,17 @@ fails-if(/^Windows\x20NT\x206\.1/.test(h
 skip-if(!cocoaWidget) != 1349308-1.html 1349308-notref.html # macOS-specific test for -apple-system glyph metrics
 fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) fails-if(Android&&!geckoview) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html # Android, Win10: regional indicators not supported by system emoji font
 fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android
 == 1507661-spurious-hyphenation-after-explicit.html 1507661-spurious-hyphenation-after-explicit-ref.html
 fuzzy-if(!webrender,12-66,288-1660) == 1522857-1.html 1522857-1-ref.html # antialiasing fuzz in non-webrender cases
 
 # ensure emoji chars don't render blank (bug 715798, bug 779042);
 # should at least render hexboxes if there's no font support
-!= emoji-01.html emoji-01-notref.html
+random-if(geckoview&&webrender) != emoji-01.html emoji-01-notref.html
 != emoji-02.html emoji-02-notref.html
 
 # Bug 727276: tests with variation selectors 15 and 16 to control emoji rendering style
 == emoji-03.html emoji-03-ref.html
 # the next two will fail on OS X 10.6 because no color emoji font is present,
 # and also on Android platforms until we have color emoji fonts there.
 # Tests rely on bundled Twemoji Mozilla to pass on Windows <8.1 and Linux.
 fails-if(Android&&!geckoview) != emoji-03.html emoji-03-notref.html
--- a/layout/reftests/usercss/reftest.list
+++ b/layout/reftests/usercss/reftest.list
@@ -1,4 +1,4 @@
 == usercss.html usercss-ref.html
 == usercss-uppercase.html usercss-ref.html
 == usercss-xbl.html usercss-ref.html
-== usercss-moz-document.html usercss-moz-document-ref.html
+fails-if(geckoview&&webrender) == usercss-moz-document.html usercss-moz-document-ref.html
--- a/layout/reftests/w3c-css/submitted/background/reftest.list
+++ b/layout/reftests/w3c-css/submitted/background/reftest.list
@@ -17,17 +17,17 @@
 == background-repeat-round-1d.html background-repeat-round-1-ref.html
 == background-repeat-round-1e.html background-repeat-round-1-ref.html
 == background-repeat-round-2.html background-repeat-round-2-ref.html
 == background-repeat-round-3.html background-repeat-round-3-ref.html
 == background-repeat-round-4.html background-repeat-round-4-ref.html
 
 #border-image test cases
 fuzzy-if(webrender,9-10,556-620) == border-image-repeat-round-1.html border-image-repeat-round-1-ref.html
-fuzzy-if(webrender,7-7,208-232) == border-image-repeat-round-2.html border-image-repeat-round-2-ref.html
+fuzzy-if(webrender,7-7,208-294) == border-image-repeat-round-2.html border-image-repeat-round-2-ref.html
 == border-image-repeat-space-1.html border-image-repeat-space-1-ref.html
 == border-image-repeat-space-2.html border-image-repeat-space-2-ref.html
 == border-image-repeat-space-3.html border-image-repeat-space-3-ref.html
 == border-image-repeat-space-4.html border-image-repeat-space-4-ref-1.html
 == border-image-repeat-space-4-ref-1.html border-image-repeat-space-4-ref-2.html
 == border-image-repeat-space-5.html border-image-repeat-space-5-ref-1.html
 == border-image-repeat-space-5-ref-1.html border-image-repeat-space-5-ref-2.html
 == border-image-repeat-space-6.html border-image-repeat-space-6-ref.html
--- a/layout/reftests/w3c-css/submitted/masking/reftest.list
+++ b/layout/reftests/w3c-css/submitted/masking/reftest.list
@@ -82,33 +82,33 @@ fails == mask-origin-2.html mask-origin-
 == mask-size-length-length.html mask-size-length-length-ref.html
 == mask-size-length-percent.html mask-size-length-percent-ref.html
 == mask-size-percent.html mask-size-percent-percent-ref.html
 == mask-size-percent-auto.html mask-size-percent-percent-ref.html
 == mask-size-percent-length.html mask-size-percent-percent-ref.html
 == mask-size-percent-percent.html mask-size-percent-percent-ref.html
 == mask-size-percent-percent-stretch.html mask-size-percent-percent-stretch-ref.html
 
-fuzzy-if(winWidget,0-1,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-371) == clip-path-contentBox-1a.html clip-path-geometryBox-1-ref.html
+fuzzy-if(winWidget,0-1,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-376) == clip-path-contentBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) == clip-path-contentBox-1b.html clip-path-geometryBox-1-ref.html
-fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,36-36,365-365) == clip-path-contentBox-1c.html clip-path-geometryBox-1-ref.html
-fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-371) == clip-path-paddingBox-1a.html clip-path-geometryBox-1-ref.html
+fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,36-36,365-376) == clip-path-contentBox-1c.html clip-path-geometryBox-1-ref.html
+fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-376) == clip-path-paddingBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) == clip-path-paddingBox-1b.html clip-path-geometryBox-1-ref.html
-fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-371) == clip-path-paddingBox-1c.html clip-path-geometryBox-1-ref.html
-fuzzy(0-64,0-371) == clip-path-borderBox-1a.html clip-path-geometryBox-1-ref.html
+fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(webrender,0-64,0-376) == clip-path-paddingBox-1c.html clip-path-geometryBox-1-ref.html
+fuzzy(0-64,0-376) == clip-path-borderBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) == clip-path-borderBox-1b.html clip-path-geometryBox-1-ref.html
-fuzzy(0-64,0-371) == clip-path-borderBox-1c.html clip-path-geometryBox-1-ref.html
+fuzzy(0-64,0-376) == clip-path-borderBox-1c.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-16,0-27) fuzzy-if(skiaContent,0-1,0-60) == clip-path-marginBox-1a.html clip-path-geometryBox-1-ref.html
-fuzzy(0-64,0-371) == clip-path-fillBox-1a.html clip-path-geometryBox-1-ref.html
-fuzzy(0-64,0-371) == clip-path-strokeBox-1a.html clip-path-geometryBox-1-ref.html
+fuzzy(0-64,0-376) == clip-path-fillBox-1a.html clip-path-geometryBox-1-ref.html
+fuzzy(0-64,0-376) == clip-path-strokeBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy(0-64,0-370) == clip-path-strokeBox-1b.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-1,0-21) fuzzy-if(skiaContent,0-1,0-60) == clip-path-viewBox-1a.html clip-path-geometryBox-1-ref.html
 fuzzy-if(winWidget,0-1,0-21) fuzzy-if(skiaContent,0-1,0-60) == clip-path-viewBox-1b.html clip-path-geometryBox-1-ref.html
-fuzzy(0-64,0-371) == clip-path-viewBox-1c.html clip-path-geometryBox-1-ref.html
-fuzzy-if(winWidget,0-9,0-98) fuzzy-if(webrender,0-64,0-100) == clip-path-geometryBox-2.html clip-path-geometryBox-2-ref.html
+fuzzy(0-64,0-376) == clip-path-viewBox-1c.html clip-path-geometryBox-1-ref.html
+fuzzy-if(winWidget,0-9,0-98) fuzzy-if(webrender,0-65,0-120) == clip-path-geometryBox-2.html clip-path-geometryBox-2-ref.html
 
 == clip-path-localRef-1.html clip-path-localRef-1-ref.html
 
 # mask with opacity test cases
 fuzzy(0-1,0-5000) == mask-opacity-1a.html mask-opacity-1-ref.html
 fuzzy(0-1,0-5000) == mask-opacity-1b.html mask-opacity-1-ref.html
 fuzzy(0-1,0-5000) == mask-opacity-1c.html mask-opacity-1-ref.html
 fuzzy(0-1,0-5000) == mask-opacity-1d.html mask-opacity-1-ref.html
--- a/layout/reftests/writing-mode/reftest.list
+++ b/layout/reftests/writing-mode/reftest.list
@@ -145,17 +145,17 @@ skip-if(winWidget&&/^Windows\x20NT\x206\
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize-ref.html # Bug 1392106
 
 # tests involving sideways-lr mode
 == 1193519-sideways-lr-1.html 1193519-sideways-lr-1-ref.html
 == 1193519-sideways-lr-2.html 1193519-sideways-lr-2-ref.html
 fuzzy-if(winWidget,0-3,0-84) fails-if(webrender&&!gtkWidget) == 1193519-sideways-lr-3.html 1193519-sideways-lr-3-ref.html
 fuzzy-if(winWidget,0-3,0-112) fails-if(webrender||Android) == 1193519-sideways-lr-4.html 1193519-sideways-lr-4-ref.html # see bug 1366692. Rounding error with WR enabled, and on Android.
-fuzzy-if(gtkWidget,0-255,0-6) fuzzy-if(cocoaWidget,0-65,0-69) == 1193519-sideways-lr-decoration-1.html 1193519-sideways-lr-decoration-1-ref.html
+fuzzy-if(gtkWidget,0-255,0-6) fuzzy-if(cocoaWidget,0-65,0-69) fuzzy-if(geckoview&&webrender,0-255,0-4) == 1193519-sideways-lr-decoration-1.html 1193519-sideways-lr-decoration-1-ref.html
 
 == 1196887-1-computed-display-inline-block.html 1196887-1-computed-display-inline-block-ref.html
 == 1205787-legacy-svg-values-1.html 1205787-legacy-svg-values-1-ref.html
 
 == 1216747-1.html 1216747-1-ref.html
 != 1216747-1.html 1216747-1-notref.html
 
 == 1243125-1-floats-overflowing.html 1243125-1-floats-overflowing-ref.html
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -299,11 +299,11 @@ load 1502893.html
 load 1509989.html
 load 1514086.html
 pref(layout.css.moz-binding.content.enabled,false) load 1517319.html
 load 1533783.html
 load 1533891.html
 pref(gfx.omta.background-color,true) load 1533968.html
 load 1541126.html
 load 1545177.html
-load 1546255.html
+skip-if(geckoview&&webrender) load 1546255.html # Bug 1563020 for GV+WR
 pref(layout.css.resizeobserver.enabled,true) load 1552911.html
 load 1562361.html
--- a/layout/tools/reftest/README.txt
+++ b/layout/tools/reftest/README.txt
@@ -174,16 +174,24 @@ 2. A test item
           Loading the test and reference is known to assert between
           minCount and maxCount times, inclusive.
           NOTE: See above regarding canvas caching.
 
       asserts-if(condition,count)
       asserts-if(condition,minCount-maxCount)
           Same as above, but only if condition is true.
 
+      noautofuzz
+          Disables the autofuzzing behaviour hard-coded in the reftest harness
+          for specific platform configurations. The autofuzzing is intended to
+          compensate for inherent nondeterminism that results in intermittently
+          fuzzy results (with small amounts of fuzz) across many/all tests on
+          a given platform. Specifying 'noautofuzz' on the test will disable
+          the autofuzzing for that test and require an exact match.
+
       Conditions are JavaScript expressions *without spaces* in them.
       They are evaluated in a sandbox in which a limited set of
       variables are defined.  See the BuildConditionSandbox function in
       layout/tools/reftest.js for details.
 
       Examples of using conditions:
           fails-if(winWidget) == test reference
           asserts-if(cocoaWidget,2) load crashtest
--- a/layout/tools/reftest/manifest.jsm
+++ b/layout/tools/reftest/manifest.jsm
@@ -117,18 +117,19 @@ function ReadManifest(aURL, aFilter)
         var slow = false;
         var testPrefSettings = defaultTestPrefSettings.concat();
         var refPrefSettings = defaultRefPrefSettings.concat();
         var fuzzy_delta = { min: 0, max: 2 };
         var fuzzy_pixels = { min: 0, max: 1 };
         var chaosMode = false;
         var wrCapture = { test: false, ref: false };
         var nonSkipUsed = false;
+        var noAutoFuzz = false;
 
-        while (items[0].match(/^(fails|needs-focus|random|skip|asserts|slow|require-or|silentfail|pref|test-pref|ref-pref|fuzzy|chaos-mode|wr-capture|wr-capture-ref)/)) {
+        while (items[0].match(/^(fails|needs-focus|random|skip|asserts|slow|require-or|silentfail|pref|test-pref|ref-pref|fuzzy|chaos-mode|wr-capture|wr-capture-ref|noautofuzz)/)) {
             var item = items.shift();
             var stat;
             var cond;
             var m = item.match(/^(fails|random|skip|silentfail)-if(\(.*\))$/);
             if (m) {
                 stat = m[1];
                 // Note: m[2] contains the parentheses, and we want them.
                 cond = Cu.evalInSandbox(m[2], sandbox);
@@ -206,16 +207,19 @@ function ReadManifest(aURL, aFilter)
                 cond = false;
                 chaosMode = true;
             } else if (item == "wr-capture") {
                 cond = false;
                 wrCapture.test = true;
             } else if (item == "wr-capture-ref") {
                 cond = false;
                 wrCapture.ref = true;
+            } else if (item == "noautofuzz") {
+                cond = false;
+                noAutoFuzz = true;
             } else {
                 throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": unexpected item " + item;
             }
 
             if (stat != "skip") {
                 nonSkipUsed = true;
             }
 
@@ -311,17 +315,18 @@ function ReadManifest(aURL, aFilter)
                           fuzzyMaxDelta: fuzzy_delta.max,
                           fuzzyMinPixels: fuzzy_pixels.min,
                           fuzzyMaxPixels: fuzzy_pixels.max,
                           runHttp: runHttp,
                           httpDepth: httpDepth,
                           url1: items[1],
                           url2: null,
                           chaosMode: chaosMode,
-                          wrCapture: wrCapture }, aFilter);
+                          wrCapture: wrCapture,
+                          noAutoFuzz: noAutoFuzz }, aFilter);
         } else if (items[0] == TYPE_REFTEST_EQUAL || items[0] == TYPE_REFTEST_NOTEQUAL || items[0] == TYPE_PRINT) {
             if (items.length != 3)
                 throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": incorrect number of arguments to " + items[0];
 
             if (items[0] == TYPE_REFTEST_NOTEQUAL &&
                 expected_status == EXPECTED_FUZZY &&
                 (fuzzy_delta.min > 0 || fuzzy_pixels.min > 0)) {
                 throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": minimum fuzz must be zero for tests of type " + items[0];
@@ -359,17 +364,18 @@ function ReadManifest(aURL, aFilter)
                           fuzzyMaxDelta: fuzzy_delta.max,
                           fuzzyMinPixels: fuzzy_pixels.min,
                           fuzzyMaxPixels: fuzzy_pixels.max,
                           runHttp: runHttp,
                           httpDepth: httpDepth,
                           url1: items[1],
                           url2: items[2],
                           chaosMode: chaosMode,
-                          wrCapture: wrCapture }, aFilter);
+                          wrCapture: wrCapture,
+                          noAutoFuzz: noAutoFuzz }, aFilter);
         } else {
             throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": unknown test type " + items[0];
         }
     }
 }
 
 // Read all available data from an input stream and return it
 // as a string.
--- a/layout/tools/reftest/reftest.jsm
+++ b/layout/tools/reftest/reftest.jsm
@@ -64,16 +64,25 @@ g.logger = new StructuredLogger('reftest
 var logger = g.logger;
 
 function TestBuffer(str)
 {
   logger.debug(str);
   g.testLog.push(str);
 }
 
+function isWebRenderOnAndroidDevice() {
+  var xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
+  // This is the best we can do for now; maybe in the future we'll have
+  // more correct detection of this case.
+  return xr.OS == "Android" &&
+      g.browserIsRemote &&
+      g.windowUtils.layerManagerType == "WebRender";
+}
+
 function FlushTestBuffer()
 {
   // In debug mode, we've dumped all these messages already.
   if (g.logLevel !== 'debug') {
     for (var i = 0; i < g.testLog.length; ++i) {
       logger.info("Saved log: " + g.testLog[i]);
     }
   }
@@ -1100,26 +1109,43 @@ function RecordResult(testRunTime, error
             var differences;
             // whether the two renderings match:
             var equal;
             var maxDifference = {};
             // whether the allowed fuzziness from the annotations is exceeded
             // by the actual comparison results
             var fuzz_exceeded = false;
 
+            // what is expected on this platform (PASS, FAIL, RANDOM, or FUZZY)
+            var expected = g.urls[0].expected;
+
             differences = g.windowUtils.compareCanvases(g.canvas1, g.canvas2, maxDifference);
+
+            if (g.urls[0].noAutoFuzz) {
+                // Autofuzzing is disabled
+            } else if (isWebRenderOnAndroidDevice() && maxDifference.value <= 2 && differences > 0) {
+                // Autofuzz for WR on Android physical devices: Reduce any
+                // maxDifference of 2 to 0, because we get a lot of off-by-ones
+                // and off-by-twos that are very random and hard to annotate.
+                // In cases where the difference on any pixel component is more
+                // than 2 we require manual annotation. Note that this applies
+                // to both == tests and != tests, so != tests don't
+                // inadvertently pass due to a random off-by-one pixel
+                // difference.
+                logger.info(`REFTEST wr-on-android dropping fuzz of (${maxDifference.value}, ${differences}) to (0, 0)`);
+                maxDifference.value = 0;
+                differences = 0;
+            }
+
             equal = (differences == 0);
 
             if (maxDifference.value > 0 && equal) {
                 throw "Inconsistent result from compareCanvases.";
             }
 
-            // what is expected on this platform (PASS, FAIL, or RANDOM)
-            var expected = g.urls[0].expected;
-
             if (expected == EXPECTED_FUZZY) {
                 logger.info(`REFTEST fuzzy test ` +
                             `(${g.urls[0].fuzzyMinDelta}, ${g.urls[0].fuzzyMinPixels}) <= ` +
                             `(${maxDifference.value}, ${differences}) <= ` +
                             `(${g.urls[0].fuzzyMaxDelta}, ${g.urls[0].fuzzyMaxPixels})`);
                 fuzz_exceeded = maxDifference.value > g.urls[0].fuzzyMaxDelta ||
                                 differences > g.urls[0].fuzzyMaxPixels;
                 equal = !fuzz_exceeded &&
--- a/taskcluster/ci/test/reftest.yml
+++ b/taskcluster/ci/test/reftest.yml
@@ -3,24 +3,26 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 ---
 job-defaults:
     suite:
         category: reftest
     target:
         by-test-platform:
             android-em-7.*: geckoview-androidTest.apk
+            android-hw-.*-qr/.*: geckoview-androidTest.apk
             default: null
     variants:
         by-test-platform:
             linux64/debug: ['fission', 'serviceworker']
             default: ['fission']
     run-on-projects:
         by-test-platform:
             android-em-4.*/.*: ['try', 'mozilla-central']  # bug 1548659
+            android-hw-.*-qr/.*: ['try', 'mozilla-central']
             windows10-aarch64/opt: ['try', 'mozilla-central']
             default: built-projects
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 android-hw.*: android_hardware_unittest.py
                 default: desktop_unittest.py
@@ -64,16 +66,17 @@ crashtest:
     max-run-time:
         by-test-platform:
             android-em.*: 7200
             default: 3600
     tier:
         by-test-platform:
             windows10-aarch64.*: 2
             android-em-4.*/.*: 2  # bug 1548659
+            android-hw-.*-qr/.*: 2
             default: default
 
 jsreftest:
     description: "JS Reftest run"
     schedules-component: jsreftest
     treeherder-symbol: R(J)
     instance-size: default
     chunks:
@@ -143,16 +146,17 @@ reftest:
             by-test-platform:
                 android-em.*: false
                 macosx.*64/opt: false
                 windows10-64.*/opt: false
                 default: true
     tier:
         by-test-platform:
             windows10-aarch64.*: 2
+            android-hw-.*-qr/.*: 2
             default: default
 
 reftest-gpu:
     description: "Reftest GPU run"
     treeherder-symbol: R(Rg)
     chunks:
         by-test-platform:
             windows.*/opt: 2
--- a/taskcluster/ci/test/test-platforms.yml
+++ b/taskcluster/ci/test/test-platforms.yml
@@ -406,16 +406,26 @@ android-hw-p2-8-0-arm7-api-16/opt:
         - android-hw-arm7-raptor-power
         - raptor-fetch-geckoview
 
 android-hw-p2-8-0-arm7-api-16/debug:
     build-platform: android-api-16/debug
     test-sets:
         - android-hw-arm7-debug-unittests
 
+android-hw-p2-8-0-arm7-api-16-qr/opt:
+    build-platform: android-api-16/opt
+    test-sets:
+        - android-hw-arm7-qr
+
+android-hw-p2-8-0-arm7-api-16-qr/debug:
+    build-platform: android-api-16/debug
+    test-sets:
+        - android-hw-arm7-qr
+
 android-hw-p2-8-0-android-aarch64/opt:
     build-platform: android-aarch64/opt
     test-sets:
         - android-hw-aarch64-raptor
         - android-hw-aarch64-raptor-power
 
 android-hw-p2-8-0-android-aarch64/pgo:
     build-platform: android-aarch64-pgo/opt
--- a/taskcluster/ci/test/test-sets.yml
+++ b/taskcluster/ci/test/test-sets.yml
@@ -315,25 +315,25 @@ macosx1014-64-tests:
     - firefox-ui-functional-remote
     # - gtest
     - jittest
     - jsreftest
     - marionette
     - mochitest
     - mochitest-a11y
     # - mochitest-browser-chrome
-    # - mochitest-chrome
+    - mochitest-chrome
     - mochitest-devtools-chrome
     - mochitest-devtools-webreplay
     - mochitest-gpu
     - mochitest-media
     - mochitest-remote
     - mochitest-webgl1-core
     - mochitest-webgl1-ext
-    # - mochitest-webgl2-core
+    - mochitest-webgl2-core
     # - mochitest-webgl2-ext test  # timeouts
     - reftest
     - telemetry-tests-client
     - test-verify
     - test-verify-gpu
     - test-verify-wpt
     - web-platform-tests
     - web-platform-tests-reftests
@@ -341,21 +341,18 @@ macosx1014-64-tests:
     - xpcshell
 
 macosx1014-64-qr-tests:
     - crashtest
     - reftest
 
 macosx64-tests:
     - gtest
-    - mochitest
     - mochitest-browser-chrome
-    - mochitest-chrome
     - mochitest-media
-    - mochitest-webgl2-core
     # - mochitest-webgl2-ext test timeouts
 
 macosx64-talos:
     - talos-bcv
     - talos-chrome
     - talos-damp
     - talos-dromaeojs
     - talos-g1
@@ -436,16 +433,20 @@ android-hw-arm7-pgo-unittests:
     - jsreftest
     - mochitest-media
 
 android-hw-arm7-debug-unittests:
     - jittest
     - jsreftest
     - mochitest-media
 
+android-hw-arm7-qr:
+    - crashtest
+    - reftest
+
 android-hw-arm7-raptor:
     - raptor-speedometer-geckoview
     - raptor-speedometer-refbrow
     - raptor-youtube-playback-fenix
     - raptor-youtube-playback-geckoview
     - raptor-tp6m-1-geckoview
     - raptor-tp6m-2-geckoview
     - raptor-tp6m-3-geckoview
deleted file mode 100755
--- a/taskcluster/scripts/misc/build-gcc-4.9-linux.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-set -e
-
-# This script is for building GCC 4.9 for Linux.
-
-WORKSPACE=$HOME/workspace
-HOME_DIR=$WORKSPACE/build
-UPLOAD_DIR=$HOME/artifacts
-
-root_dir=$HOME_DIR
-data_dir=$HOME_DIR/src/build/unix/build-gcc
-
-. $data_dir/build-gcc.sh
-
-gcc_version=4.9.4
-gcc_ext=bz2
-binutils_version=2.25.1
-binutils_ext=bz2
-
-pushd $root_dir/gcc-$gcc_version
-ln -sf ../cloog-0.18.1 cloog
-ln -sf ../gmp-5.1.3 gmp
-ln -sf ../mpc-0.8.2 mpc
-ln -sf ../isl-0.12.2 isl
-ln -sf ../mpfr-3.1.5 mpfr
-popd
-
-apply_patch $data_dir/PR64905.patch
-build_binutils
-build_gcc
-
-# Put a tarball in the artifacts dir
-mkdir -p $UPLOAD_DIR
-cp $HOME_DIR/gcc.tar.* $UPLOAD_DIR
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -115,16 +115,17 @@ PER_PROJECT_PARAMETERS = {
     'default': {
         'target_tasks_method': 'default',
     }
 }
 
 try_task_config_schema = Schema({
     Required('tasks'): [basestring],
     Optional('templates'): {basestring: object},
+    Optional('disable-pgo'): bool,
 })
 
 
 try_task_config_schema_v2 = Schema({
     Optional('parameters'): {basestring: object},
 })
 
 
@@ -259,17 +260,17 @@ def get_decision_parameters(config, opti
     parameters['release_partners'] = []
     parameters['release_partner_config'] = {}
     parameters['release_partner_build_number'] = 1
     parameters['release_enable_emefree'] = False
     parameters['release_product'] = None
     parameters['required_signoffs'] = []
     parameters['signoff_urls'] = {}
     parameters['try_mode'] = None
-    parameters['try_task_config'] = None
+    parameters['try_task_config'] = {}
     parameters['try_options'] = None
 
     # owner must be an email, but sometimes (e.g., for ffxbld) it is not, in which
     # case, fake it
     if '@' not in parameters['owner']:
         parameters['owner'] += '@noreply.mozilla.org'
 
     # use the pushdate as build_date if given, else use current time
--- a/taskcluster/taskgraph/parameters.py
+++ b/taskcluster/taskgraph/parameters.py
@@ -157,17 +157,17 @@ class Parameters(ReadOnlyDict):
             'release_product': None,
             'release_type': 'nightly',
             'required_signoffs': [],
             'signoff_urls': {},
             'target_tasks_method': 'default',
             'tasks_for': 'hg-push',
             'try_mode': None,
             'try_options': None,
-            'try_task_config': None,
+            'try_task_config': {},
             'version': get_version(),
         }
 
         if set(COMM_PARAMETERS) & set(kwargs):
             defaults.update({
                 'comm_base_repository': 'https://hg.mozilla.org/comm-central',
                 'comm_head_repository': 'https://hg.mozilla.org/comm-central',
             })
--- a/taskcluster/taskgraph/test/test_decision.py
+++ b/taskcluster/taskgraph/test/test_decision.py
@@ -72,17 +72,17 @@ class TestGetDecisionParameters(unittest
         with MockedOpen({self.ttc_file: None}):
             params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
         self.assertEqual(params['pushlog_id'], '143')
         self.assertEqual(params['build_date'], 1503691511)
         self.assertEqual(params['hg_branch'], 'default')
         self.assertEqual(params['moz_build_date'], '20170825200511')
         self.assertEqual(params['try_mode'], None)
         self.assertEqual(params['try_options'], None)
-        self.assertEqual(params['try_task_config'], None)
+        self.assertEqual(params['try_task_config'], {})
 
     @patch('taskgraph.decision.get_hg_revision_branch')
     def test_no_email_owner(self, mock_get_hg_revision_branch):
         mock_get_hg_revision_branch.return_value = 'default'
         self.options['owner'] = 'ffxbld'
         with MockedOpen({self.ttc_file: None}):
             params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
         self.assertEqual(params['owner'], 'ffxbld@noreply.mozilla.org')
@@ -93,17 +93,17 @@ class TestGetDecisionParameters(unittest
         mock_get_hg_commit_message.return_value = 'try: -b do -t all'
         mock_get_hg_revision_branch.return_value = 'default'
         self.options['project'] = 'try'
         with MockedOpen({self.ttc_file: None}):
             params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
         self.assertEqual(params['try_mode'], 'try_option_syntax')
         self.assertEqual(params['try_options']['build_types'], 'do')
         self.assertEqual(params['try_options']['unittests'], 'all')
-        self.assertEqual(params['try_task_config'], None)
+        self.assertEqual(params['try_task_config'], {})
 
     @patch('taskgraph.decision.get_hg_revision_branch')
     @patch('taskgraph.decision.get_hg_commit_message')
     def test_try_task_config(self, mock_get_hg_commit_message, mock_get_hg_revision_branch):
         mock_get_hg_commit_message.return_value = 'Fuzzy query=foo'
         mock_get_hg_revision_branch.return_value = 'default'
         ttc = {'tasks': ['a', 'b'], 'templates': {}}
         self.options['project'] = 'try'
--- a/taskcluster/taskgraph/transforms/build.py
+++ b/taskcluster/taskgraph/transforms/build.py
@@ -99,17 +99,18 @@ def mozconfig(config, jobs):
             job['run'].setdefault('extra-config', {})['mozconfig_variant'] = mozconfig_variant
         yield job
 
 
 @transforms.add
 def use_profile_data(config, jobs):
     for job in jobs:
         use_pgo = job.pop('use-pgo', False)
-        if not use_pgo:
+        disable_pgo = config.params['try_task_config'].get('disable-pgo', False)
+        if not use_pgo or disable_pgo:
             yield job
             continue
 
         # If use_pgo is True, the task uses the generate-profile task of the
         # same name. Otherwise a task can specify a specific generate-profile
         # task to use in the use_pgo field.
         if use_pgo is True:
             name = job['name']
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/manifestexpected.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/manifestexpected.py
@@ -37,16 +37,27 @@ def bool_prop(name, node):
 def int_prop(name, node):
     """Boolean property"""
     try:
         return int(node.get(name))
     except KeyError:
         return None
 
 
+def list_prop(name, node):
+    """List property"""
+    try:
+        list_prop = node.get(name)
+        if isinstance(list_prop, basestring):
+            return [list_prop]
+        return list(list_prop)
+    except KeyError:
+        return []
+
+
 def tags(node):
     """Set of tags that have been applied to the test"""
     try:
         value = node.get("tags")
         if isinstance(value, (str, unicode)):
             return {value}
         return set(value)
     except KeyError:
@@ -283,16 +294,24 @@ class ExpectedManifest(ManifestItem):
     @property
     def lsan_max_stack_depth(self):
         return int_prop("lsan-max-stack-depth", self)
 
     @property
     def fuzzy(self):
         return fuzzy_prop(self)
 
+    @property
+    def expected(self):
+        return list_prop("expected", self)[0]
+
+    @property
+    def known_intermittent(self):
+        return list_prop("expected", self)[1:]
+
 
 class DirectoryManifest(ManifestItem):
     @property
     def disabled(self):
         return bool_prop("disabled", self)
 
     @property
     def restart_after(self):
@@ -410,16 +429,24 @@ class TestNode(ManifestItem):
     @property
     def lsan_max_stack_depth(self):
         return int_prop("lsan-max-stack-depth", self)
 
     @property
     def fuzzy(self):
         return fuzzy_prop(self)
 
+    @property
+    def expected(self):
+        return list_prop("expected", self)[0]
+
+    @property
+    def known_intermittent(self):
+        return list_prop("expected", self)[1:]
+
     def append(self, node):
         """Add a subtest to the current test
 
         :param node: AST Node associated with the subtest"""
         child = ManifestItem.append(self, node)
         self.subtests[child.name] = child
 
     def get_subtest(self, name):
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/metadata.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/metadata.py
@@ -328,20 +328,22 @@ class ExpectedUpdater(object):
         action_map = self.action_map
         action_map["suite_start"]({"run_info": data["run_info"]})
         for test in data["results"]:
             action_map["test_start"]({"test": test["test"]})
             for subtest in test["subtests"]:
                 action_map["test_status"]({"test": test["test"],
                                            "subtest": subtest["name"],
                                            "status": subtest["status"],
-                                           "expected": subtest.get("expected")})
+                                           "expected": subtest.get("expected"),
+                                           "known_intermittent": subtest.get("known_intermittent")})
             action_map["test_end"]({"test": test["test"],
                                     "status": test["status"],
-                                    "expected": test.get("expected")})
+                                    "expected": test.get("expected"),
+                                    "known_intermittent": test.get("known_intermittent")})
             if "asserts" in test:
                 asserts = test["asserts"]
                 action_map["assertion_count"]({"test": test["test"],
                                                "count": asserts["count"],
                                                "min_expected": asserts["min"],
                                                "max_expected": asserts["max"]})
         for item in data.get("lsan_leaks", []):
             action_map["lsan_leak"](item)
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_wpttest.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_wpttest.py
@@ -37,16 +37,42 @@ test_1 = """\
     if os == 'win': FAIL
 """
 
 test_2 = """\
 [2.html]
   lsan-max-stack-depth: 42
 """
 
+test_3 = """\
+[3.html]
+  [subtest1]
+    expected: [PASS, FAIL]
+
+  [subtest2]
+    disabled: reason
+
+  [subtest3]
+    expected: FAIL
+"""
+
+test_4 = """\
+[4.html]
+  expected: FAIL
+"""
+
+test_5 = """\
+[5.html]
+"""
+
+test_6 = """\
+[6.html]
+  expected: [OK, FAIL]
+"""
+
 test_fuzzy = """\
 [fuzzy.html]
   fuzzy: fuzzy-ref.html:1;200
 """
 
 
 testharness_test = """<script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>"""
@@ -60,103 +86,130 @@ def make_mock_manifest(*items):
     for test_type, dir_path, num_tests in items:
         for i in range(num_tests):
             filename = dir_path + "/%i.html" % i
             tests.append((test_type,
                           filename,
                           {TestharnessTest("/foo.bar", filename, "/", filename)}))
     return rv
 
+def make_test_object(test_name,
+                     test_path,
+                     index,
+                     items,
+                     inherit_metadata=None,
+                     iterate=False,
+                     condition=None):
+    inherit_metadata = inherit_metadata if inherit_metadata is not None else []
+    condition = condition if condition is not None else {}
+    tests = make_mock_manifest(*items) if isinstance(items, list) else make_mock_manifest(items)
+
+    test_metadata = manifestexpected.static.compile(BytesIO(test_name),
+                                                    condition,
+                                                    data_cls_getter=manifestexpected.data_cls_getter,
+                                                    test_path=test_path,
+                                                    url_base="/")
+
+    test = next(iter(tests[index][2])) if iterate else tests[index][2].pop()
+    return wpttest.from_manifest(tests, test, inherit_metadata, test_metadata.get_test(test.id))
+
 
 @pytest.mark.xfail(sys.version[0] == "3",
                    reason="bytes/text confusion in py3")
 def test_metadata_inherit():
-    tests = make_mock_manifest(("test", "a", 10), ("test", "a/b", 10),
-                               ("test", "c", 10))
-
+    items = [("test", "a", 10), ("test", "a/b", 10), ("test", "c", 10)]
     inherit_metadata = [
         manifestexpected.static.compile(
             BytesIO(item),
             {},
             data_cls_getter=lambda x,y: manifestexpected.DirectoryManifest)
         for item in [dir_ini_0, dir_ini_1]]
-    test_metadata = manifestexpected.static.compile(BytesIO(test_0),
-                                                    {},
-                                                    data_cls_getter=manifestexpected.data_cls_getter,
-                                                    test_path="a/0.html",
-                                                    url_base="/")
 
-    test = next(iter(tests[0][2]))
-    test_obj = wpttest.from_manifest(tests, test, inherit_metadata, test_metadata.get_test(test.id))
+    test_obj = make_test_object(test_0, "a/0.html", 0, items, inherit_metadata, True)
+
     assert test_obj.max_assertion_count == 3
     assert test_obj.min_assertion_count == 1
     assert test_obj.prefs == {"b": "c", "c": "d"}
     assert test_obj.tags == {"a", "dir:a"}
 
 
 @pytest.mark.xfail(sys.version[0] == "3",
                    reason="bytes/text confusion in py3")
 def test_conditional():
-    tests = make_mock_manifest(("test", "a", 10), ("test", "a/b", 10),
-                               ("test", "c", 10))
+    items = [("test", "a", 10), ("test", "a/b", 10), ("test", "c", 10)]
 
-    test_metadata = manifestexpected.static.compile(BytesIO(test_1),
-                                                    {"os": "win"},
-                                                    data_cls_getter=manifestexpected.data_cls_getter,
-                                                    test_path="a/1.html",
-                                                    url_base="/")
+    test_obj = make_test_object(test_1, "a/1.html", 1, items, None, True, {"os": "win"})
 
-    test = next(iter(tests[1][2]))
-    test_obj = wpttest.from_manifest(tests, test, [], test_metadata.get_test(test.id))
     assert test_obj.prefs == {"a": "b", "c": "d"}
     assert test_obj.expected() == "FAIL"
 
 
 @pytest.mark.xfail(sys.version[0] == "3",
                    reason="bytes/text confusion in py3")
 def test_metadata_lsan_stack_depth():
-    tests = make_mock_manifest(("test", "a", 10), ("test", "a/b", 10))
+    items = [("test", "a", 10), ("test", "a/b", 10)]
 
-    test_metadata = manifestexpected.static.compile(BytesIO(test_2),
-                                                    {},
-                                                    data_cls_getter=manifestexpected.data_cls_getter,
-                                                    test_path="a/2.html",
-                                                    url_base="/")
-
-    test = next(iter(tests[2][2]))
-    test_obj = wpttest.from_manifest(tests, test, [], test_metadata.get_test(test.id))
+    test_obj = make_test_object(test_2, "a/2.html", 2, items, None, True)
 
     assert test_obj.lsan_max_stack_depth == 42
 
-    test = next(iter(tests[1][2]))
-    test_obj = wpttest.from_manifest(tests, test, [], test_metadata.get_test(test.id))
+    test_obj = make_test_object(test_2, "a/2.html", 1, items, None, True)
 
     assert test_obj.lsan_max_stack_depth is None
 
-    test_metadata = manifestexpected.static.compile(BytesIO(test_0),
-                                                    {},
-                                                    data_cls_getter=manifestexpected.data_cls_getter,
-                                                    test_path="a/0.html",
-                                                    url_base="/")
-
     inherit_metadata = [
         manifestexpected.static.compile(
             BytesIO(dir_ini_2),
             {},
             data_cls_getter=lambda x,y: manifestexpected.DirectoryManifest)
     ]
 
-    test = tests[0][2].pop()
-    test_obj = wpttest.from_manifest(tests, test, inherit_metadata, test_metadata.get_test(test.id))
+    test_obj = make_test_object(test_0, "a/0/html", 0, items, inherit_metadata, False)
 
     assert test_obj.lsan_max_stack_depth == 42
 
 
 @pytest.mark.xfail(sys.version[0] == "3",
                    reason="bytes/text confusion in py3")
+def test_subtests():
+    test_obj = make_test_object(test_3, "a/3.html", 3, ("test", "a", 4), None, False)
+    assert test_obj.expected("subtest1") == "PASS"
+    assert test_obj.known_intermittent("subtest1") == ["FAIL"]
+    assert test_obj.expected("subtest2") == "PASS"
+    assert test_obj.known_intermittent("subtest2") == []
+    assert test_obj.expected("subtest3") == "FAIL"
+    assert test_obj.known_intermittent("subtest3") == []
+
+
+@pytest.mark.xfail(sys.version[0] == "3",
+                   reason="bytes/text confusion in py3")
+def test_expected_fail():
+    test_obj = make_test_object(test_4, "a/4.html", 4, ("test", "a", 5), None, False)
+    assert test_obj.expected() == "FAIL"
+    assert test_obj.known_intermittent() == []
+
+
+@pytest.mark.xfail(sys.version[0] == "3",
+                   reason="bytes/text confusion in py3")
+def test_no_expected():
+    test_obj = make_test_object(test_5, "a/5.html", 5, ("test", "a", 6), None, False)
+    assert test_obj.expected() == "OK"
+    assert test_obj.known_intermittent() == []
+
+
+@pytest.mark.xfail(sys.version[0] == "3",
+                   reason="bytes/text confusion in py3")
+def test_known_intermittent():
+    test_obj = make_test_object(test_6, "a/6.html", 6, ("test", "a", 7), None, False)
+    assert test_obj.expected() == "OK"
+    assert test_obj.known_intermittent() == ["FAIL"]
+
+
+@pytest.mark.xfail(sys.version[0] == "3",
+                   reason="bytes/text confusion in py3")
 def test_metadata_fuzzy():
     manifest_data = {
         "items": {"reftest": {"a/fuzzy.html": [["a/fuzzy.html",
                                                 [["/a/fuzzy-ref.html", "=="]],
                                                 {"fuzzy": [[["/a/fuzzy.html", '/a/fuzzy-ref.html', '=='],
                                                             [[2, 3], [10, 15]]]]}]]}},
         "paths": {"a/fuzzy.html": ["0"*40, "reftest"]},
         "version": 6,
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/wpttest.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/wpttest.py
@@ -5,38 +5,46 @@ from collections import defaultdict
 
 from .wptmanifest.parser import atoms
 
 atom_reset = atoms["Reset"]
 enabled_tests = {"testharness", "reftest", "wdspec"}
 
 
 class Result(object):
-    def __init__(self, status, message, expected=None, extra=None, stack=None):
+    def __init__(self,
+                 status,
+                 message,
+                 expected=None,
+                 extra=None,
+                 stack=None,
+                 known_intermittent=None):
         if status not in self.statuses:
             raise ValueError("Unrecognised status %s" % status)
         self.status = status
         self.message = message
         self.expected = expected
+        self.known_intermittent = known_intermittent if known_intermittent is not None else []
         self.extra = extra if extra is not None else {}
         self.stack = stack
 
     def __repr__(self):
         return "<%s.%s %s>" % (self.__module__, self.__class__.__name__, self.status)
 
 
 class SubtestResult(object):
-    def __init__(self, name, status, message, stack=None, expected=None):
+    def __init__(self, name, status, message, stack=None, expected=None, known_intermittent=None):
         self.name = name
         if status not in self.statuses:
             raise ValueError("Unrecognised status %s" % status)
         self.status = status
         self.message = message
         self.stack = stack
         self.expected = expected
+        self.known_intermittent = known_intermittent if known_intermittent is not None else []
 
     def __repr__(self):
         return "<%s.%s %s %s>" % (self.__module__, self.__class__.__name__, self.name, self.status)
 
 
 class TestharnessResult(Result):
     default_expected = "OK"
     statuses = {"OK", "ERROR", "INTERNAL-ERROR", "TIMEOUT", "EXTERNAL-TIMEOUT", "CRASH"}
@@ -299,20 +307,39 @@ class Test(object):
         else:
             default = self.subtest_result_cls.default_expected
 
         metadata = self._get_metadata(subtest)
         if metadata is None:
             return default
 
         try:
-            return metadata.get("expected")
+            expected = metadata.get("expected")
+            if isinstance(expected, (basestring)):
+                return expected
+            elif isinstance(expected, list):
+                return expected[0]
+            elif expected is None:
+                return default
         except KeyError:
             return default
 
+    def known_intermittent(self, subtest=None):
+        metadata = self._get_metadata(subtest)
+        if metadata is None:
+            return []
+
+        try:
+            expected = metadata.get("expected")
+            if isinstance(expected, list):
+                return expected[1:]
+            return []
+        except KeyError:
+            return []
+
     def __repr__(self):
         return "<%s.%s %s>" % (self.__module__, self.__class__.__name__, self.id)
 
 
 class TestharnessTest(Test):
     result_cls = TestharnessResult
     subtest_result_cls = TestharnessSubtestResult
     test_type = "testharness"
--- a/toolkit/content/tests/chrome/chrome.ini
+++ b/toolkit/content/tests/chrome/chrome.ini
@@ -107,16 +107,17 @@ skip-if = toolkit == "cocoa"
 [test_custom_element_delay_connection.xul]
 [test_deck.xul]
 [test_dialogfocus.xul]
 [test_edit_contextmenu.html]
 [test_editor_for_input_with_autocomplete.html]
 [test_editor_for_textbox_with_autocomplete.xul]
 [test_findbar.xul]
 tags = clipboard
+skip-if = os == 'mac' && os_version == '10.14' # macosx1014 due to 1550078
 [test_findbar_entireword.xul]
 [test_findbar_events.xul]
 [test_focus_anons.xul]
 [test_frames.xul]
 [test_hiddenitems.xul]
 [test_hiddenpaging.xul]
 [test_keys.xul]
 [test_labelcontrol.xul]
@@ -136,16 +137,17 @@ support-files = window_navigate_persist.
 [test_menulist_keynav.xul]
 [test_menulist_null_value.xul]
 [test_menulist_paging.xul]
 [test_menulist_position.xul]
 [test_mousescroll.xul]
 [test_notificationbox.xul]
 skip-if = (os == 'linux' && debug) || (os == 'win') # Bug 1429649
 [test_panel.xul]
+skip-if = os == 'mac' && os_version == '10.14' # macosx1014 due to 1550078
 [test_panel_anchoradjust.xul]
 [test_panelfrommenu.xul]
 [test_popup_anchor.xul]
 [test_popup_anchoratrect.xul]
 skip-if = os == 'linux' # 1167694
 [test_popup_attribute.xul]
 skip-if = os == 'linux' && asan # Bug 1131634
 [test_popup_button.xul]
@@ -178,17 +180,17 @@ support-files = window_preferences_onsyn
 [test_showcaret.xul]
 [test_subframe_origin.xul]
 [test_tabbox.xul]
 [test_tabindex.xul]
 [test_textbox_dictionary.xul]
 [test_textbox_emptytext.xul]
 [test_textbox_search.xul]
 [test_titlebar.xul]
-skip-if = os == "linux"
+skip-if = os == "linux" || (os == 'mac' && os_version == '10.14') # macosx1014 due to 1550078
 [test_tooltip.xul]
 skip-if = (os == 'mac' && os_version == '10.10') || (os == 'win') # Bug 1141245, frequent timeouts on OSX 10.10, Windows
 [test_tooltip_noautohide.xul]
 [test_tree.xul]
 [test_tree_hier.xul]
 [test_tree_single.xul]
 [test_tree_view.xul]
 [test_window_intrinsic_size.xul]
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -531,21 +531,26 @@ async function loadManifestFromWebManife
   addon.softDisabled = addon.blocklistState == nsIBlocklistService.STATE_SOFTBLOCKED;
 
   return addon;
 }
 
 async function readRecommendationStates(aPackage, aAddonID) {
   let recommendationData;
   try {
-    recommendationData = JSON.parse(await aPackage.readString("mozilla-recommendation.json"));
+    recommendationData = await aPackage.readString("mozilla-recommendation.json");
   } catch (e) {
-    if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
-      logger.warn("Failed to parse recommendation", e);
-    }
+    // Ignore I/O errors.
+    return null;
+  }
+
+  try {
+    recommendationData = JSON.parse(recommendationData);
+  } catch (e) {
+    logger.warn("Failed to parse recommendation", e);
   }
 
   if (recommendationData) {
     let {addon_id, states, validity} = recommendationData;
 
     if (addon_id === aAddonID && Array.isArray(states) && validity) {
       let validNotAfter = Date.parse(validity.not_after);
       let validNotBefore = Date.parse(validity.not_before);
@@ -627,17 +632,17 @@ var loadManifest = async function(aPacka
         throw new Error(`Extension is signed with an invalid id (${addon.id})`);
       }
     }
     if (!addon.id && aLocation.isTemporary) {
       addon.id = generateTemporaryInstallID(aPackage.file);
     }
   }
 
-  if (addon.type === "extension" && !addon.location.isBuiltin) {
+  if (addon.type === "extension" && !aLocation.isBuiltin && !aLocation.isTemporary) {
     addon.recommendationState = await readRecommendationStates(aPackage, addon.id);
   }
 
   addon.propagateDisabledState(aOldAddon);
   await addon.updateBlocklistState();
   addon.appDisabled = !XPIDatabase.isUsableAddon(addon);
 
   defineSyncGUID(addon);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_recommendations.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_recommendations.js
@@ -97,16 +97,41 @@ add_task(async function test_temporary()
   });
   let addon = await XPIInstall.installTemporaryAddon(xpi);
 
   ok(!addon.isRecommended, "The add-on is not recommended");
 
   await addon.uninstall();
 });
 
+// Tests that unpacked temporary add-ons are not recommended.
+add_task(async function test_temporary_directory() {
+  const id = "temporary-dir@test.web.extension";
+  let files = ExtensionTestCommon.generateFiles({
+    manifest: {
+      applications: {gecko: {id}},
+    },
+    files: {
+      [RECOMMENDATION_FILE_NAME]: {
+        addon_id: id,
+        states: ["recommended"],
+        validity: {not_before, not_after},
+      },
+    },
+  });
+  let extDir = await AddonTestUtils.promiseWriteFilesToExtension(gTmpD.path, id, files, true);
+
+  let addon = await XPIInstall.installTemporaryAddon(extDir);
+
+  ok(!addon.isRecommended, "The add-on is not recommended");
+
+  await addon.uninstall();
+  extDir.remove(true);
+});
+
 add_task(async function test_builtin() {
   const id = "builtin@test.web.extension";
   let extension = await installBuiltinExtension({
     manifest: {
       applications: {gecko: {id}},
     },
     background: `browser.test.sendMessage("started");`,
     files: {
--- a/toolkit/xre/CmdLineAndEnvUtils.h
+++ b/toolkit/xre/CmdLineAndEnvUtils.h
@@ -16,16 +16,17 @@
 #elif defined(XP_WIN)
 #  include <stdlib.h>
 #endif
 
 #if defined(XP_WIN)
 #  include "mozilla/Move.h"
 #  include "mozilla/UniquePtr.h"
 #  include "mozilla/Vector.h"
+#  include "mozilla/WinHeaderOnlyUtils.h"
 
 #  include <wchar.h>
 #  include <windows.h>
 #endif  // defined(XP_WIN)
 
 #include "mozilla/MemoryChecking.h"
 #include "mozilla/TypedEnumBits.h"
 
@@ -354,49 +355,16 @@ inline UniquePtr<wchar_t[]> MakeCommandL
     }
   }
 
   *c = '\0';
 
   return s;
 }
 
-inline UniquePtr<wchar_t[]> GetFullBinaryPath() {
-  DWORD bufLen = MAX_PATH;
-  mozilla::UniquePtr<wchar_t[]> buf;
-  DWORD retLen;
-
-  while (true) {
-    buf = mozilla::MakeUnique<wchar_t[]>(bufLen);
-    retLen = ::GetModuleFileNameW(nullptr, buf.get(), bufLen);
-    if (!retLen) {
-      return nullptr;
-    }
-
-    if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-      bufLen *= 2;
-      continue;
-    }
-
-    break;
-  }
-
-  // Upon success, retLen *excludes* the null character
-  ++retLen;
-
-  // Since we're likely to have a bunch of unused space in buf, let's reallocate
-  // a string to the actual size of the file name.
-  auto result = mozilla::MakeUnique<wchar_t[]>(retLen);
-  if (wcscpy_s(result.get(), retLen, buf.get())) {
-    return nullptr;
-  }
-
-  return result;
-}
-
 inline bool SetArgv0ToFullBinaryPath(wchar_t* aArgv[]) {
   if (!aArgv) {
     return false;
   }
 
   UniquePtr<wchar_t[]> newArgv_0(GetFullBinaryPath());
   if (!newArgv_0) {
     return false;
--- a/toolkit/xre/LauncherRegistryInfo.h
+++ b/toolkit/xre/LauncherRegistryInfo.h
@@ -2,20 +2,20 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_LauncherRegistryInfo_h
 #define mozilla_LauncherRegistryInfo_h
 
-#include "mozilla/CmdLineAndEnvUtils.h"
 #include "mozilla/LauncherResult.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/WinHeaderOnlyUtils.h"
 #include "nsWindowsHelpers.h"
 
 #include <string>
 
 /**
  * We use std::wstring here because this code must be usable within both the
  * launcher process and Gecko itself.
  */
--- a/tools/tryselect/mach_commands.py
+++ b/tools/tryselect/mach_commands.py
@@ -13,16 +13,17 @@ from mach.decorators import (
     CommandProvider,
     Command,
     SettingsProvider,
     SubCommand,
 )
 from mozboot.util import get_state_dir
 from mozbuild.base import BuildEnvironmentNotFoundException, MachCommandBase
 
+
 CONFIG_ENVIRONMENT_NOT_FOUND = '''
 No config environment detected. This means we are unable to properly
 detect test files in the specified paths or tags. Please run:
 
     $ mach configure
 
 and try again.
 '''.lstrip()
@@ -152,34 +153,35 @@ class TrySelect(MachCommandBase):
                     defaults[k] = v
                 else:
                     nondefaults[k] = v
 
             kwargs = merge(defaults, preset, nondefaults)
 
         return kwargs
 
-    def handle_templates(self, **kwargs):
-        kwargs.setdefault('templates', {})
+    def handle_try_config(self, **kwargs):
+        from tryselect.util.dicttools import merge
+        kwargs.setdefault('try_config', {})
         for cls in self.parser.templates.itervalues():
-            context = cls.context(**kwargs)
-            if context is not None:
-                kwargs['templates'].update(context)
+            try_config = cls.try_config(**kwargs)
+            if try_config is not None:
+                kwargs['try_config'] = merge(kwargs['try_config'], try_config)
 
             for name in cls.dests:
                 del kwargs[name]
 
         return kwargs
 
     def run(self, **kwargs):
         if 'preset' in self.parser.common_groups:
             kwargs = self.handle_presets(**kwargs)
 
         if self.parser.templates:
-            kwargs = self.handle_templates(**kwargs)
+            kwargs = self.handle_try_config(**kwargs)
 
         mod = importlib.import_module('tryselect.selectors.{}'.format(self.subcommand))
         return mod.run(**kwargs)
 
     @Command('try',
              category='ci',
              description='Push selected tasks to the try server',
              parser=generic_parser)
--- a/tools/tryselect/push.py
+++ b/tools/tryselect/push.py
@@ -74,41 +74,44 @@ def check_working_directory(push=True):
     if not push:
         return
 
     if not vcs.working_directory_clean():
         print(UNCOMMITTED_CHANGES)
         sys.exit(1)
 
 
-def push_to_try(method, msg, labels=None, templates=None, try_task_config=None,
+def generate_try_task_config(method, labels, try_config=None):
+    try_task_config = try_config or {}
+
+    templates = try_task_config.setdefault('templates', {})
+    templates.setdefault('env', {}).update({'TRY_SELECTOR': method})
+
+    try_task_config.update({
+        'version': 1,
+        'tasks': sorted(labels),
+    })
+
+    return try_task_config
+
+
+def push_to_try(method, msg, try_task_config=None,
                 push=True, closed_tree=False, files_to_change=None):
     check_working_directory(push)
 
     # Format the commit message
     closed_tree_string = " ON A CLOSED TREE" if closed_tree else ""
     commit_message = ('%s%s\n\nPushed via `mach try %s`' %
                       (msg, closed_tree_string, method))
 
-    if templates is not None:
-        templates.setdefault('env', {}).update({'TRY_SELECTOR': method})
-
-    if labels or labels == []:
-        try_task_config = {
-            'version': 1,
-            'tasks': sorted(labels),
-        }
-        if templates:
-            try_task_config['templates'] = templates
-        if push:
-            write_task_config_history(msg, try_task_config)
-
     config_path = None
     changed_files = []
     if try_task_config:
+        if push and method != 'again':
+            write_task_config_history(msg, try_task_config)
         config_path = write_task_config(try_task_config)
         changed_files.append(config_path)
 
     if files_to_change:
         for path, content in files_to_change.items():
             path = os.path.join(vcs.path, path)
             with open(path, 'w') as fh:
                 fh.write(content)
--- a/tools/tryselect/selectors/chooser/__init__.py
+++ b/tools/tryselect/selectors/chooser/__init__.py
@@ -5,29 +5,29 @@
 from __future__ import absolute_import, print_function, unicode_literals
 
 import os
 import webbrowser
 from threading import Timer
 
 from tryselect.cli import BaseTryParser
 from tryselect.tasks import generate_tasks
-from tryselect.push import check_working_directory, push_to_try
+from tryselect.push import check_working_directory, push_to_try, generate_try_task_config
 
 here = os.path.abspath(os.path.dirname(__file__))
 
 
 class ChooserParser(BaseTryParser):
     name = 'chooser'
     arguments = []
     common_groups = ['push', 'task']
-    templates = ['artifact', 'env', 'rebuild', 'chemspill-prio', 'gecko-profile']
+    templates = ['artifact', 'env', 'rebuild', 'chemspill-prio', 'gecko-profile', 'disable-pgo']
 
 
-def run(update=False, query=None, templates=None, full=False, parameters=None,
+def run(update=False, query=None, try_config=None, full=False, parameters=None,
         save=False, preset=None, mod_presets=False, push=True, message='{msg}',
         closed_tree=False):
     from .app import create_application
     check_working_directory(push)
 
     tg = generate_tasks(parameters, full)
     app = create_application(tg)
 
@@ -43,10 +43,11 @@ def run(update=False, query=None, templa
     app.run()
 
     selected = app.tasks
     if not selected:
         print("no tasks selected")
         return
 
     msg = "Try Chooser Enhanced ({} tasks selected)".format(len(selected))
-    return push_to_try('chooser', message.format(msg=msg), selected, templates, push=push,
-                       closed_tree=closed_tree)
+    return push_to_try('chooser', message.format(msg=msg),
+                       try_task_config=generate_try_task_config('chooser', selected, try_config),
+                       push=push, closed_tree=closed_tree)
--- a/tools/tryselect/selectors/coverage.py
+++ b/tools/tryselect/selectors/coverage.py
@@ -18,17 +18,17 @@ import datetime
 from mozboot.util import get_state_dir
 from mozbuild.base import MozbuildObject
 from mozpack.files import FileFinder
 from moztest.resolve import TestResolver
 from mozversioncontrol import get_repository_object
 
 from ..cli import BaseTryParser
 from ..tasks import generate_tasks, filter_tasks_by_paths, resolve_tests_by_suite
-from ..push import push_to_try
+from ..push import push_to_try, generate_try_task_config
 
 here = os.path.abspath(os.path.dirname(__file__))
 build = MozbuildObject.from_environment(cwd=here)
 vcs = get_repository_object(build.topsrcdir)
 
 root_hash = hashlib.sha256(os.path.abspath(build.topsrcdir)).hexdigest()
 cache_dir = os.path.join(get_state_dir(), 'cache', root_hash, 'chunk_mapping')
 if not os.path.isdir(cache_dir):
@@ -52,17 +52,17 @@ OPT_TASK_PATTERNS = [
     'linux64/opt',
 ]
 
 
 class CoverageParser(BaseTryParser):
     name = 'coverage'
     arguments = []
     common_groups = ['push', 'task']
-    templates = ['artifact', 'env', 'rebuild', 'chemspill-prio']
+    templates = ['artifact', 'env', 'rebuild', 'chemspill-prio', 'disable-pgo']
 
 
 def read_test_manifests():
     '''Uses TestResolver to read all test manifests in the tree.
 
     Returns a (tests, support_files_map) tuple that describes the tests in the tree:
     tests - a set of test file paths
     support_files_map - a dict that maps from each support file to a list with
@@ -338,17 +338,17 @@ def filter_tasks_by_chunks(tasks, chunks
 
 def is_opt_task(task):
     '''True if the task runs on a supported platform and build type combination.
     This is used to remove -ccov/asan/pgo tasks, along with all /debug tasks.
     '''
     return any(platform in task for platform in OPT_TASK_PATTERNS)
 
 
-def run(templates={}, full=False, parameters=None, push=True, message='{msg}', closed_tree=False):
+def run(try_config={}, full=False, parameters=None, push=True, message='{msg}', closed_tree=False):
     download_coverage_mapping(vcs.base_ref)
 
     changed_sources = vcs.get_outgoing_files()
     test_files, test_chunks = find_tests(changed_sources)
     if not test_files and not test_chunks:
         print('ERROR Could not find any tests or chunks to run.')
         return 1
 
@@ -369,14 +369,15 @@ def run(templates={}, full=False, parame
         test_plural='' if len(test_files) == 1 else 's',
         test_singular='s' if len(test_files) == 1 else '',
         task_count=len(tasks),
         task_plural='' if len(tasks) == 1 else 's')
     print('Found ' + test_count_message)
 
     # Set the test paths to be run by setting MOZHARNESS_TEST_PATHS.
     path_env = {'MOZHARNESS_TEST_PATHS': json.dumps(resolve_tests_by_suite(test_files))}
-    templates.setdefault('env', {}).update(path_env)
+    try_config.setdefault('templates', {}).setdefault('env', {}).update(path_env)
 
     # Build commit message.
     msg = 'try coverage - ' + test_count_message
-    return push_to_try('coverage', message.format(msg=msg), tasks, templates, push=push,
-                       closed_tree=closed_tree)
+    return push_to_try('coverage', message.format(msg=msg),
+                       try_task_config=generate_try_task_config('coverage', tasks, try_config),
+                       push=push, closed_tree=closed_tree)
--- a/tools/tryselect/selectors/empty.py
+++ b/tools/tryselect/selectors/empty.py
@@ -1,19 +1,20 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from ..cli import BaseTryParser
-from ..push import push_to_try
+from ..push import push_to_try, generate_try_task_config
 
 
 class EmptyParser(BaseTryParser):
     name = 'empty'
     common_groups = ['push']
 
 
 def run(message='{msg}', push=True, closed_tree=False):
     msg = 'No try selector specified, use "Add New Jobs" to select tasks.'
-    return push_to_try('empty', message.format(msg=msg), [], push=push,
-                       closed_tree=closed_tree)
+    return push_to_try('empty', message.format(msg=msg),
+                       try_task_config=generate_try_task_config('empty', []),
+                       push=push, closed_tree=closed_tree)
--- a/tools/tryselect/selectors/fuzzy.py
+++ b/tools/tryselect/selectors/fuzzy.py
@@ -11,17 +11,17 @@ import subprocess
 import sys
 from distutils.spawn import find_executable
 
 from mozboot.util import get_state_dir
 from mozterm import Terminal
 
 from ..cli import BaseTryParser
 from ..tasks import generate_tasks, filter_tasks_by_paths
-from ..push import check_working_directory, push_to_try
+from ..push import check_working_directory, push_to_try, generate_try_task_config
 
 terminal = Terminal()
 
 here = os.path.abspath(os.path.dirname(__file__))
 
 # Some tasks show up in the target task set, but are either special cases
 # or uncommon enough that they should only be selectable with --full.
 TARGET_TASK_FILTERS = (
@@ -116,17 +116,19 @@ class FuzzyParser(BaseTryParser):
           }],
         [['-u', '--update'],
          {'action': 'store_true',
           'default': False,
           'help': "Update fzf before running.",
           }],
     ]
     common_groups = ['push', 'task', 'preset']
-    templates = ['artifact', 'path', 'env', 'rebuild', 'chemspill-prio', 'gecko-profile']
+    templates = [
+        'artifact', 'path', 'env', 'rebuild', 'chemspill-prio', 'gecko-profile', 'disable-pgo',
+    ]
 
 
 def run_cmd(cmd, cwd=None):
     is_win = platform.system() == 'Windows'
     return subprocess.call(cmd, cwd=cwd, shell=True if is_win else False)
 
 
 def run_fzf_install_script(fzf_path):
@@ -214,17 +216,17 @@ def run_fzf(cmd, tasks):
         selected = out[1:]
     return query, selected
 
 
 def filter_target_task(task):
     return not any(re.search(pattern, task) for pattern in TARGET_TASK_FILTERS)
 
 
-def run(update=False, query=None, intersect_query=None, templates=None, full=False,
+def run(update=False, query=None, intersect_query=None, try_config=None, full=False,
         parameters=None, save_query=False, push=True, message='{msg}',
         test_paths=None, exact=False, closed_tree=False):
     fzf = fzf_bootstrap(update)
 
     if not fzf:
         print(FZF_NOT_FOUND)
         return 1
 
@@ -290,10 +292,11 @@ def run(update=False, query=None, inters
 
     # build commit message
     msg = "Fuzzy"
     args = ["query={}".format(q) for q in queries]
     if test_paths:
         args.append("paths={}".format(':'.join(test_paths)))
     if args:
         msg = "{} {}".format(msg, '&'.join(args))
-    return push_to_try('fuzzy', message.format(msg=msg), selected, templates, push=push,
-                       closed_tree=closed_tree)
+    return push_to_try('fuzzy', message.format(msg=msg),
+                       try_task_config=generate_try_task_config('fuzzy', selected, try_config),
+                       push=push, closed_tree=closed_tree)
--- a/tools/tryselect/selectors/release.py
+++ b/tools/tryselect/selectors/release.py
@@ -53,23 +53,27 @@ class ReleaseParser(BaseTryParser):
         [['--tasks'],
          {'choices': TARGET_TASKS.keys(),
           'default': 'staging',
           'help': "Which tasks to run on-push.",
           }],
 
     ]
     common_groups = ['push']
+    templates = ['disable-pgo']
 
     def __init__(self, *args, **kwargs):
         super(ReleaseParser, self).__init__(*args, **kwargs)
         self.set_defaults(migrations=[])
 
 
-def run(version, migrations, limit_locales, tasks, push=True, message='{msg}', closed_tree=False):
+def run(
+    version, migrations, limit_locales, tasks,
+    try_config=None, push=True, message='{msg}', closed_tree=False
+):
     app_version = attr.evolve(version, beta_number=None, is_esr=False)
 
     files_to_change = {
         'browser/config/version.txt': '{}\n'.format(app_version),
         'browser/config/version_display.txt': '{}\n'.format(version),
         'config/milestone.txt': '{}\n'.format(app_version),
     }
 
@@ -83,16 +87,18 @@ def run(version, migrations, limit_local
     task_config = {
         'version': 2,
         'parameters': {
             'target_tasks_method': TARGET_TASKS[tasks],
             'optimize_target_tasks': True,
             'release_type': release_type,
         },
     }
+    if try_config:
+        task_config['parameters']['try_task_config'] = try_config
 
     for migration in migrations:
         migration_path = os.path.join(
             vcs.path,
             'testing/mozharness/configs/merge_day',
             '{}.py'.format(migration.replace('-', '_')),
         )
         migration_config = {}
--- a/tools/tryselect/selectors/syntax.py
+++ b/tools/tryselect/selectors/syntax.py
@@ -142,17 +142,17 @@ class SyntaxParser(BaseTryParser):
             'help': 'Force artifact builds where possible.',
         },
         '--upload-xdbs': {
             'action': 'store_true',
             'dest': 'upload_xdbs',
             'help': 'Upload XDB compilation db files generated by hazard build',
         },
     }
-    templates = ['chemspill-prio']
+    templates = []
 
     def __init__(self, *args, **kwargs):
         BaseTryParser.__init__(self, *args, **kwargs)
 
         group = self.add_argument_group("pass-through arguments")
         for arg, opts in self.pass_through_arguments.items():
             group.add_argument(arg, **opts)
 
--- a/tools/tryselect/templates.py
+++ b/tools/tryselect/templates.py
@@ -18,32 +18,43 @@ from argparse import Action, SUPPRESS
 import mozpack.path as mozpath
 from mozbuild.base import BuildEnvironmentNotFoundException, MozbuildObject
 from .tasks import resolve_tests_by_suite
 
 here = os.path.abspath(os.path.dirname(__file__))
 build = MozbuildObject.from_environment(cwd=here)
 
 
-class Template(object):
+class TryConfig(object):
     __metaclass__ = ABCMeta
 
     def __init__(self):
         self.dests = set()
 
     def add_arguments(self, parser):
         for cli, kwargs in self.arguments:
             action = parser.add_argument(*cli, **kwargs)
             self.dests.add(action.dest)
 
     @abstractproperty
     def arguments(self):
         pass
 
     @abstractmethod
+    def try_config(self, **kwargs):
+        pass
+
+
+class Template(TryConfig):
+    def try_config(self, **kwargs):
+        context = self.context(**kwargs)
+        if context:
+            return {'templates': context}
+
+    @abstractmethod
     def context(self, **kwargs):
         pass
 
 
 class Artifact(Template):
 
     arguments = [
         [['--artifact'],
@@ -204,16 +215,33 @@ class GeckoProfile(Template):
     ]
 
     def context(self, profile, **kwargs):
         if not profile:
             return
         return {'gecko-profile': profile}
 
 
+class DisablePgo(TryConfig):
+
+    arguments = [
+        [['--disable-pgo'],
+         {'action': 'store_true',
+          'help': 'Don\'t run PGO builds',
+          }],
+    ]
+
+    def try_config(self, disable_pgo, **kwargs):
+        if disable_pgo:
+            return {
+                'disable-pgo': True,
+            }
+
+
 all_templates = {
     'artifact': Artifact,
     'path': Path,
     'env': Environment,
     'rebuild': Rebuild,
     'chemspill-prio': ChemspillPrio,
     'gecko-profile': GeckoProfile,
+    'disable-pgo': DisablePgo,
 }
--- a/tools/tryselect/test/test_again.py
+++ b/tools/tryselect/test/test_again.py
@@ -10,51 +10,64 @@ import mozunit
 import pytest
 
 from tryselect import push
 from tryselect.selectors import again
 
 
 @pytest.fixture(autouse=True)
 def patch_history_path(tmpdir, monkeypatch):
-    monkeypatch.setattr(push, 'history_path', tmpdir.join('history.json').strpath)
+    monkeypatch.setattr(push, "history_path", tmpdir.join("history.json").strpath)
     reload(again)
 
 
 def test_try_again(monkeypatch):
-    push.push_to_try('fuzzy', 'Fuzzy message', ['foo', 'bar'], {'artifact': True})
+    push.push_to_try(
+        "fuzzy",
+        "Fuzzy message",
+        try_task_config=push.generate_try_task_config(
+            "fuzzy", ["foo", "bar"], {"templates": {"artifact": True}},
+        ),
+    )
 
     assert os.path.isfile(push.history_path)
-    with open(push.history_path, 'r') as fh:
+    with open(push.history_path, "r") as fh:
         assert len(fh.readlines()) == 1
 
     def fake_push_to_try(*args, **kwargs):
         return args, kwargs
 
-    monkeypatch.setattr(push, 'push_to_try', fake_push_to_try)
+    monkeypatch.setattr(push, "push_to_try", fake_push_to_try)
     reload(again)
 
     args, kwargs = again.run()
 
-    assert args[0] == 'again'
-    assert args[1] == 'Fuzzy message'
+    assert args[0] == "again"
+    assert args[1] == "Fuzzy message"
 
-    try_task_config = kwargs.pop('try_task_config')
-    assert sorted(try_task_config.get('tasks')) == sorted(['foo', 'bar'])
-    assert try_task_config.get('templates') == {
-        'artifact': True,
-        'env': {'TRY_SELECTOR': 'fuzzy'},
+    try_task_config = kwargs.pop("try_task_config")
+    assert sorted(try_task_config.get("tasks")) == sorted(["foo", "bar"])
+    assert try_task_config.get("templates") == {
+        "artifact": True,
+        "env": {"TRY_SELECTOR": "fuzzy"},
     }
 
-    with open(push.history_path, 'r') as fh:
+    with open(push.history_path, "r") as fh:
         assert len(fh.readlines()) == 1
 
 
 def test_no_push_does_not_generate_history(tmpdir):
     assert not os.path.isfile(push.history_path)
 
-    push.push_to_try('fuzzy', 'Fuzzy', ['foo', 'bar'], {'artifact': True}, push=False)
+    push.push_to_try(
+        "fuzzy",
+        "Fuzzy",
+        try_task_config=push.generate_try_task_config(
+            "fuzzy", ["foo", "bar"], {"templates": {"artifact": True}},
+        ),
+        push=False,
+    )
     assert not os.path.isfile(push.history_path)
     assert again.run() == 1
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     mozunit.main()
--- a/widget/windows/WinHeaderOnlyUtils.h
+++ b/widget/windows/WinHeaderOnlyUtils.h
@@ -7,25 +7,33 @@
 #ifndef mozilla_WinHeaderOnlyUtils_h
 #define mozilla_WinHeaderOnlyUtils_h
 
 #include <windows.h>
 #include <winerror.h>
 #include <winnt.h>
 #include <winternl.h>
 
+#include <stdlib.h>
+
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DynamicallyLinkedFunctionPtr.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/Result.h"
+#include "mozilla/Tuple.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WindowsVersion.h"
 #include "nsWindowsHelpers.h"
 
+#if defined(MOZILLA_INTERNAL_API)
+#  include "nsIFile.h"
+#  include "nsString.h"
+#endif  // defined(MOZILLA_INTERNAL_API)
+
 /**
  * This header is intended for self-contained, header-only, utility code for
  * Win32. It may be used outside of xul.dll, in places such as firefox.exe or
  * mozglue.dll. If your code creates dependencies on Mozilla libraries, you
  * should put it elsewhere.
  */
 
 #if _WIN32_WINNT < _WIN32_WINNT_WIN8
@@ -397,11 +405,133 @@ class MOZ_RAII AutoVirtualProtect final 
  private:
   void* mAddress;
   size_t mLength;
   HANDLE mTargetProcess;
   DWORD mPrevProt;
   WindowsError mError;
 };
 
+inline UniquePtr<wchar_t[]> GetFullModulePath(HMODULE aModule) {
+  DWORD bufLen = MAX_PATH;
+  mozilla::UniquePtr<wchar_t[]> buf;
+  DWORD retLen;
+
+  while (true) {
+    buf = mozilla::MakeUnique<wchar_t[]>(bufLen);
+    retLen = ::GetModuleFileNameW(aModule, buf.get(), bufLen);
+    if (!retLen) {
+      return nullptr;
+    }
+
+    if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+      bufLen *= 2;
+      continue;
+    }
+
+    break;
+  }
+
+  // Upon success, retLen *excludes* the null character
+  ++retLen;
+
+  // Since we're likely to have a bunch of unused space in buf, let's reallocate
+  // a string to the actual size of the file name.
+  auto result = mozilla::MakeUnique<wchar_t[]>(retLen);
+  if (wcscpy_s(result.get(), retLen, buf.get())) {
+    return nullptr;
+  }
+
+  return result;
+}
+
+inline UniquePtr<wchar_t[]> GetFullBinaryPath() {
+  return GetFullModulePath(nullptr);
+}
+
+class ModuleVersion final {
+ public:
+  explicit ModuleVersion(const VS_FIXEDFILEINFO& aFixedInfo)
+      : mVersion((static_cast<uint64_t>(aFixedInfo.dwFileVersionMS) << 32) |
+                 static_cast<uint64_t>(aFixedInfo.dwFileVersionLS)) {}
+
+  explicit ModuleVersion(const uint64_t aVersion) : mVersion(aVersion) {}
+
+  ModuleVersion(const ModuleVersion& aOther) : mVersion(aOther.mVersion) {}
+
+  uint64_t AsInteger() const { return mVersion; }
+
+  operator uint64_t() const { return AsInteger(); }
+
+  Tuple<uint16_t, uint16_t, uint16_t, uint16_t> AsTuple() const {
+    uint16_t major = static_cast<uint16_t>((mVersion >> 48) & 0xFFFFU);
+    uint16_t minor = static_cast<uint16_t>((mVersion >> 32) & 0xFFFFU);
+    uint16_t patch = static_cast<uint16_t>((mVersion >> 16) & 0xFFFFU);
+    uint16_t build = static_cast<uint16_t>(mVersion & 0xFFFFU);
+
+    return MakeTuple(major, minor, patch, build);
+  }
+
+  explicit operator bool() const { return !!mVersion; }
+
+  bool operator<(const ModuleVersion& aOther) const {
+    return mVersion < aOther.mVersion;
+  }
+
+  bool operator<(const uint64_t& aOther) const { return mVersion < aOther; }
+
+ private:
+  const uint64_t mVersion;
+};
+
+inline WindowsErrorResult<ModuleVersion> GetModuleVersion(
+    const wchar_t* aModuleFullPath) {
+  DWORD verInfoLen = ::GetFileVersionInfoSizeW(aModuleFullPath, nullptr);
+  if (!verInfoLen) {
+    return Err(WindowsError::FromLastError());
+  }
+
+  auto verInfoBuf = MakeUnique<BYTE[]>(verInfoLen);
+  if (!::GetFileVersionInfoW(aModuleFullPath, 0, verInfoLen,
+                             verInfoBuf.get())) {
+    return Err(WindowsError::FromLastError());
+  }
+
+  UINT fixedInfoLen;
+  VS_FIXEDFILEINFO* fixedInfo = nullptr;
+  if (!::VerQueryValueW(verInfoBuf.get(), L"\\",
+                        reinterpret_cast<LPVOID*>(&fixedInfo), &fixedInfoLen)) {
+    // VerQueryValue may fail if the resource does not exist. This is not an
+    // error; we'll return 0 in this case.
+    return ModuleVersion(0ULL);
+  }
+
+  return ModuleVersion(*fixedInfo);
+}
+
+inline WindowsErrorResult<ModuleVersion> GetModuleVersion(HMODULE aModule) {
+  UniquePtr<wchar_t[]> fullPath(GetFullModulePath(aModule));
+  if (!fullPath) {
+    return Err(WindowsError::CreateGeneric());
+  }
+
+  return GetModuleVersion(fullPath.get());
+}
+
+#if defined(MOZILLA_INTERNAL_API)
+inline WindowsErrorResult<ModuleVersion> GetModuleVersion(nsIFile* aFile) {
+  if (!aFile) {
+    return Err(WindowsError::FromHResult(E_INVALIDARG));
+  }
+
+  nsAutoString fullPath;
+  nsresult rv = aFile->GetPath(fullPath);
+  if (NS_FAILED(rv)) {
+    return Err(WindowsError::CreateGeneric());
+  }
+
+  return GetModuleVersion(fullPath.get());
+}
+#endif  // defined(MOZILLA_INTERNAL_API)
+
 }  // namespace mozilla
 
 #endif  // mozilla_WinHeaderOnlyUtils_h