Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 27 Jul 2016 16:40:43 +0200
changeset 347112 714cca6d49d0dc89b2b7bf71bc99a94e5ae04dd8
parent 347111 bb19a9b7a3360dc775dd7f1a88eddff14db8ebe1 (current diff)
parent 346871 fef429fba4c64c5b9c0c823a6ab713edbbcd4220 (diff)
child 347113 739a8707a3e290ea0f995ffcb6709d30f9027028
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to fx-team
browser/components/downloads/content/downloads.css
browser/components/downloads/content/downloads.js
build/autoconf/mozcommonheader.m4
build/autoconf/winsdk.m4
mobile/android/geckoview_library/.classpath
mobile/android/geckoview_library/.project
mobile/android/geckoview_library/AndroidManifest.xml.in
mobile/android/geckoview_library/Makefile.in
mobile/android/geckoview_library/build.xml
mobile/android/geckoview_library/geckolibs/AndroidManifest.xml
mobile/android/geckoview_library/geckolibs/classes.jar
mobile/android/geckoview_library/geckoview/AndroidManifest.xml
mobile/android/geckoview_library/local.properties.in
mobile/android/geckoview_library/moz.build
mobile/android/geckoview_library/project.properties.in
python/mozbuild/mozbuild/action/package_geckolibs_aar.py
toolkit/content/widgets/findbar.xml
toolkit/modules/Finder.jsm
--- a/accessible/interfaces/nsIAccessible.idl
+++ b/accessible/interfaces/nsIAccessible.idl
@@ -25,17 +25,17 @@ class Accessible;
  * accessibility APIs like MSAA and ATK. Contains the sum of what's needed
  * to support IAccessible as well as ATK's generic accessibility objects.
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
  * nodes in the DOM tree -- such as documents, focusable elements and text.
  * Mozilla creates the implementations of nsIAccessible on demand.
  * See http://www.mozilla.org/projects/ui/accessibility for more information.
  */
-[scriptable, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
+[scriptable, builtinclass, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
 interface nsIAccessible : nsISupports
 {
   /**
    * Parent node in accessible tree.
    */
   readonly attribute nsIAccessible parent;
 
   /**
--- a/accessible/interfaces/nsIAccessibleApplication.idl
+++ b/accessible/interfaces/nsIAccessibleApplication.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * This interface is implemented by top level accessible object in hierarchy and
  * provides information about application.
  */
-[scriptable, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
+[scriptable, builtinclass, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
 interface nsIAccessibleApplication : nsISupports
 {
   /**
    * Returns the application name.
    */
   readonly attribute DOMString appName;
 
   /**
--- a/accessible/interfaces/nsIAccessibleDocument.idl
+++ b/accessible/interfaces/nsIAccessibleDocument.idl
@@ -14,17 +14,17 @@ interface mozIDOMWindowProxy;
  * that wish to retrieve information about a document.
  * When accessibility is turned on in Gecko,
  * there is an nsIAccessibleDocument for each document
  * whether it is XUL, HTML or whatever.
  * You can QueryInterface to nsIAccessibleDocument from the nsIAccessible for
  * the root node of a document or you can get one from
  * nsIAccessible::GetDocument().
  */
-[scriptable, uuid(5cad5f91-fcce-40e7-913e-4671701d19b4)]
+[scriptable, builtinclass, uuid(5cad5f91-fcce-40e7-913e-4671701d19b4)]
 interface nsIAccessibleDocument : nsISupports
 {
   /**
    * The URL of the document
    */
   readonly attribute AString URL;
 
   /**
--- a/accessible/interfaces/nsIAccessibleEditableText.idl
+++ b/accessible/interfaces/nsIAccessibleEditableText.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(28915cca-3366-4034-ba1d-b7afb9b37639)]
+[scriptable, builtinclass, uuid(28915cca-3366-4034-ba1d-b7afb9b37639)]
 interface nsIAccessibleEditableText : nsISupports
 {
   /**
    * Replaces the text represented by this object by the given text.
    */
   void setTextContents (in AString text);
 
   /**
--- a/accessible/interfaces/nsIAccessibleHyperLink.idl
+++ b/accessible/interfaces/nsIAccessibleHyperLink.idl
@@ -8,17 +8,17 @@
 
 interface nsIURI;
 interface nsIAccessible;
 
 /**
  * A cross-platform interface that supports hyperlink-specific properties and
  * methods.  Anchors, image maps, xul:labels with class="text-link" implement this interface.
  */
-[scriptable, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
+[scriptable, builtinclass, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
 interface nsIAccessibleHyperLink : nsISupports
 {
   /**
    * Returns the offset of the link within the parent accessible.
    */
   readonly attribute long startIndex;
 
   /**
--- a/accessible/interfaces/nsIAccessibleHyperText.idl
+++ b/accessible/interfaces/nsIAccessibleHyperText.idl
@@ -10,17 +10,17 @@
 /**
  * A cross-platform interface that deals with text which contains hyperlinks.
  * Each link is an embedded object representing exactly 1 character within
  * the hypertext.
  *
  * Current implementation assumes every embedded object is a link.
  */
 
-[scriptable, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
+[scriptable, builtinclass, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
 interface nsIAccessibleHyperText : nsISupports
 {
   /**
    * Return the number of links contained within this hypertext object.
    */
   readonly attribute long linkCount;
 
   /**
--- a/accessible/interfaces/nsIAccessibleImage.idl
+++ b/accessible/interfaces/nsIAccessibleImage.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 /* 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/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
+[scriptable, builtinclass, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
 interface nsIAccessibleImage : nsISupports
 {
   /**
    * Returns the coordinates of the image.
    *
    * @param coordType  specifies coordinates origin (for available constants
    *                   refer to nsIAccessibleCoordinateType)
    * @param x          the x coordinate
--- a/accessible/interfaces/nsIAccessibleRelation.idl
+++ b/accessible/interfaces/nsIAccessibleRelation.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 #include "nsIArray.idl"
 
 interface nsIAccessible;
 
 /**
  * This interface gives access to an accessible's set of relations.
  */
-[scriptable, uuid(55b308c4-2ae4-46bc-b4cd-4d4370e0a660)]
+[scriptable, builtinclass, uuid(55b308c4-2ae4-46bc-b4cd-4d4370e0a660)]
 interface nsIAccessibleRelation : nsISupports
 {
   /**
    * This object is labelled by a target object.
    */
   const unsigned long RELATION_LABELLED_BY = 0x00;
 
   /**
--- a/accessible/interfaces/nsIAccessibleRetrieval.idl
+++ b/accessible/interfaces/nsIAccessibleRetrieval.idl
@@ -11,17 +11,17 @@ interface nsIWeakReference;
 interface nsIPresShell;
 interface nsIAccessiblePivot;
 
 /**
  * An interface for in-process accessibility clients wishing to get an
  * nsIAccessible for a given DOM node.  More documentation at:
  *   http://www.mozilla.org/projects/ui/accessibility
  */
-[scriptable, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
+[scriptable, builtinclass, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
 interface nsIAccessibleRetrieval : nsISupports
 {
   /**
    * Return application accessible.
    */
   nsIAccessible getApplicationAccessible();
 
   /**
--- a/accessible/interfaces/nsIAccessibleRole.idl
+++ b/accessible/interfaces/nsIAccessibleRole.idl
@@ -3,17 +3,17 @@
  * 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/. */
 
 #include "nsISupports.idl"
 
 /**
  * Defines cross platform (Gecko) roles.
  */
-[scriptable, uuid(05a9f33f-dcfd-4e7b-b825-138ba784c1f5)]
+[scriptable, builtinclass, uuid(05a9f33f-dcfd-4e7b-b825-138ba784c1f5)]
 interface nsIAccessibleRole : nsISupports
 {
   /**
    * Used when accessible hans't strong defined role.
    */
   const unsigned long ROLE_NOTHING = 0;
 
   /**
--- a/accessible/interfaces/nsIAccessibleSelectable.idl
+++ b/accessible/interfaces/nsIAccessibleSelectable.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 
 interface nsIAccessible;
 interface nsIArray;
 
 /**
  * An accessibility interface for selectable widgets.
  */
-[scriptable, uuid(8efb03d4-1354-4875-94cf-261336057626)]
+[scriptable, builtinclass, uuid(8efb03d4-1354-4875-94cf-261336057626)]
 interface nsIAccessibleSelectable : nsISupports
 {
   /**
    * Return an nsIArray of selected items within the widget.
    */
   readonly attribute nsIArray selectedItems;
 
   /**
--- a/accessible/interfaces/nsIAccessibleTable.idl
+++ b/accessible/interfaces/nsIAccessibleTable.idl
@@ -4,17 +4,17 @@
  * 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/. */
 
 #include "nsISupports.idl"
 
 interface nsIAccessible;
 interface nsIArray;
 
-[scriptable, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
+[scriptable, builtinclass, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
 interface nsIAccessibleTable : nsISupports
 {
   /**
    * Return the caption accessible for the table. For example, html:caption
    * element of html:table element.
    */
   readonly attribute nsIAccessible caption;
 
@@ -216,17 +216,17 @@ interface nsIAccessibleTable : nsISuppor
 
   /**
    * Use heuristics to determine if table is most likely used for layout.
    */
   boolean isProbablyForLayout();
 };
 
 
-[scriptable, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
+[scriptable, builtinclass, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
 interface nsIAccessibleTableCell : nsISupports
 {
   /**
    * Return host table accessible.
    */
   readonly attribute nsIAccessibleTable table;
 
   /**
--- a/accessible/interfaces/nsIAccessibleText.idl
+++ b/accessible/interfaces/nsIAccessibleText.idl
@@ -8,17 +8,17 @@
 
 typedef long AccessibleTextBoundary;
 
 interface nsIAccessible;
 interface nsIArray;
 interface nsIPersistentProperties;
 interface nsIAccessibleTextRange;
 
-[scriptable, uuid(93ad2ca1-f12b-4ab9-a793-95d9fa9d1774)]
+[scriptable, builtinclass, uuid(93ad2ca1-f12b-4ab9-a793-95d9fa9d1774)]
 interface nsIAccessibleText : nsISupports
 {
   // In parameters for character offsets:
   //  -1 will be treated as the equal to the end of the text
   //  -2 will be treated as the caret position
   const int32_t TEXT_OFFSET_END_OF_TEXT = -1;
   const int32_t TEXT_OFFSET_CARET       = -2;
 
--- a/accessible/interfaces/nsIAccessibleTextRange.idl
+++ b/accessible/interfaces/nsIAccessibleTextRange.idl
@@ -8,17 +8,17 @@
 interface nsIAccessible;
 interface nsIAccessibleText;
 interface nsIArray;
 interface nsIVariant;
 
 /**
  * A range representing a piece of text in the document.
  */
-[scriptable, uuid(c4515623-55f9-4543-a3d5-c1e9afa588f4)]
+[scriptable, builtinclass, uuid(c4515623-55f9-4543-a3d5-c1e9afa588f4)]
 interface nsIAccessibleTextRange : nsISupports
 {
   readonly attribute nsIAccessibleText startContainer;
   readonly attribute long startOffset;
   readonly attribute nsIAccessibleText endContainer;
   readonly attribute long endOffset;
 
   /**
--- a/accessible/interfaces/nsIAccessibleTypes.idl
+++ b/accessible/interfaces/nsIAccessibleTypes.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * These constants control the scrolling of an object or substring into a
  * window. Note, keep them synchronized with IA2ScrollType.
  */
-[scriptable, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
+[scriptable, builtinclass, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
 interface nsIAccessibleScrollType : nsISupports
 {
   /**
    * Scroll the top left of the object or substring to the top left of the
    * window (or as close as possible).
    */
   const unsigned long SCROLL_TYPE_TOP_LEFT =0x00;
 
@@ -54,17 +54,17 @@ interface nsIAccessibleScrollType : nsIS
    */
   const unsigned long SCROLL_TYPE_ANYWHERE = 0x06;
 };
 
 
 /**
  * These constants define which coordinate system a point is located in.
  */
-[scriptable, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
+[scriptable, builtinclass, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
 interface nsIAccessibleCoordinateType : nsISupports
 {
   /**
    * The coordinates are relative to the screen.
    */
   const unsigned long COORDTYPE_SCREEN_RELATIVE = 0x00;
 
   /**
--- a/accessible/interfaces/nsIAccessibleValue.idl
+++ b/accessible/interfaces/nsIAccessibleValue.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
+[scriptable, builtinclass, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
 interface nsIAccessibleValue : nsISupports
 {
   readonly attribute double maximumValue;
   readonly attribute double minimumValue;
   attribute double currentValue;
   readonly attribute double minimumIncrement;
 };
 
--- a/accessible/interfaces/nsIXBLAccessible.idl
+++ b/accessible/interfaces/nsIXBLAccessible.idl
@@ -5,16 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * XBL controls can implement this interface to provide own implementation of
  * accessible properties.
  */
-[scriptable, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
+[scriptable, builtinclass, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
 interface nsIXBLAccessible : nsISupports
 {
   /**
    * Return accessible name.
    */
   readonly attribute DOMString accessibleName;
 };
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -11,26 +11,24 @@ builtin(include, build/autoconf/toolchai
 builtin(include, build/autoconf/nspr.m4)dnl
 builtin(include, build/autoconf/nspr-build.m4)dnl
 builtin(include, build/autoconf/nss.m4)dnl
 builtin(include, build/autoconf/pkg.m4)dnl
 builtin(include, build/autoconf/codeset.m4)dnl
 builtin(include, build/autoconf/altoptions.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
-builtin(include, build/autoconf/mozcommonheader.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
 builtin(include, build/autoconf/compiler-opts.m4)dnl
 builtin(include, build/autoconf/expandlibs.m4)dnl
 builtin(include, build/autoconf/arch.m4)dnl
 builtin(include, build/autoconf/android.m4)dnl
 builtin(include, build/autoconf/zlib.m4)dnl
 builtin(include, build/autoconf/linux.m4)dnl
-builtin(include, build/autoconf/winsdk.m4)dnl
 builtin(include, build/autoconf/icu.m4)dnl
 builtin(include, build/autoconf/ffi.m4)dnl
 builtin(include, build/autoconf/clang-plugin.m4)dnl
 builtin(include, build/autoconf/alloc.m4)dnl
 builtin(include, build/autoconf/ios.m4)dnl
 builtin(include, build/autoconf/jemalloc.m4)dnl
 builtin(include, build/autoconf/sanitize.m4)dnl
 
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -15,17 +15,17 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
   <project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="1ec02eda4b375778b3611ebb7fb186faf5f75bb0"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="f1a61fa8f97cc0a1ac4eca160acc222981b21d90"/>
   <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3618678c472320de386f5ddc27897992d0e148a8"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="964d9fa4eabe9eb473ef9101ca2a690880f28547">
     <copyfile dest="Makefile" src="core/root.mk"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -15,17 +15,17 @@
   <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!--
     B2G repositories for all targets
     -->
   <project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="1ec02eda4b375778b3611ebb7fb186faf5f75bb0"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform_system_libpdu" path="system/libpdu" remote="b2g" revision="f1a61fa8f97cc0a1ac4eca160acc222981b21d90"/>
   <project name="platform_system_sensorsd" path="system/sensorsd" remote="b2g" revision="3618678c472320de386f5ddc27897992d0e148a8"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="aee7ff3dba262a037559d360b62af429b62cb876">
     <copyfile dest="Makefile" src="core/root.mk"/>
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -21,38 +21,38 @@ function onUnload(aEvent) {
   // Safe to call even when there isn't a download in progress.
   gAppUpdater.removeDownloadListener();
   gAppUpdater = null;
 }
 
 
 function appUpdater()
 {
+  XPCOMUtils.defineLazyServiceGetter(this, "aus",
+                                     "@mozilla.org/updates/update-service;1",
+                                     "nsIApplicationUpdateService");
+  XPCOMUtils.defineLazyServiceGetter(this, "checker",
+                                     "@mozilla.org/updates/update-checker;1",
+                                     "nsIUpdateChecker");
+  XPCOMUtils.defineLazyServiceGetter(this, "um",
+                                     "@mozilla.org/updates/update-manager;1",
+                                     "nsIUpdateManager");
+
   this.updateDeck = document.getElementById("updateDeck");
 
   // Hide the update deck when the update window is already open and it's not
   // already applied, to avoid syncing issues between them. Applied updates
   // don't have any information to sync between the windows as they both just
   // show the "Restart to continue"-type button.
   if (Services.wm.getMostRecentWindow("Update:Wizard") &&
       !this.isApplied) {
     this.updateDeck.hidden = true;
     return;
   }
 
-  XPCOMUtils.defineLazyServiceGetter(this, "aus",
-                                     "@mozilla.org/updates/update-service;1",
-                                     "nsIApplicationUpdateService");
-  XPCOMUtils.defineLazyServiceGetter(this, "checker",
-                                     "@mozilla.org/updates/update-checker;1",
-                                     "nsIUpdateChecker");
-  XPCOMUtils.defineLazyServiceGetter(this, "um",
-                                     "@mozilla.org/updates/update-manager;1",
-                                     "nsIUpdateManager");
-
   this.bundle = Services.strings.
                 createBundle("chrome://browser/locale/browser.properties");
 
   let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
   let manualLink = document.getElementById("manualLink");
   manualLink.value = manualURL;
   manualLink.href = manualURL;
   document.getElementById("failedLink").href = manualURL;
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -14,20 +14,16 @@ var gEMEHandler = {
   },
   ensureEMEEnabled: function(browser, keySystem) {
     Services.prefs.setBoolPref("media.eme.enabled", true);
     if (keySystem) {
       if (keySystem.startsWith("com.adobe") &&
           Services.prefs.getPrefType("media.gmp-eme-adobe.enabled") &&
           !Services.prefs.getBoolPref("media.gmp-eme-adobe.enabled")) {
         Services.prefs.setBoolPref("media.gmp-eme-adobe.enabled", true);
-      } else if (keySystem == "org.w3.clearkey" &&
-                 Services.prefs.getPrefType("media.eme.clearkey.enabled") &&
-                 !Services.prefs.getBoolPref("media.eme.clearkey.enabled")) {
-        Services.prefs.setBoolPref("media.eme.clearkey.enabled", true);
       } else if (keySystem == "com.widevine.alpha" &&
                  Services.prefs.getPrefType("media.gmp-widevinecdm.enabled") &&
                  !Services.prefs.getBoolPref("media.gmp-widevinecdm.enabled")) {
         Services.prefs.setBoolPref("media.gmp-widevinecdm.enabled", true);
       }
     }
     browser.reload();
   },
--- a/browser/components/downloads/content/downloads.css
+++ b/browser/components/downloads/content/downloads.css
@@ -170,17 +170,16 @@ richlistitem.download button {
   display: none;
 }
 
 /* Make the panel wide enough to show the download list items without improperly
    truncating them. */
 #downloadsPanel-multiView > .panel-viewcontainer,
 #downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack,
 #downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack > .panel-mainview {
-  overflow: visible;
   max-width: unset;
 }
 
 /* Show the "show blocked info" button. */
 #downloadsPanel-mainView .download-state[state="8"] .downloadShowBlockedInfo {
   display: inline;
 }
 
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -74,21 +74,34 @@ var gCookiesWindow = {
   _cookieEquals: function (aCookieA, aCookieB, aStrippedHost) {
     return aCookieA.rawHost == aStrippedHost &&
            aCookieA.name == aCookieB.name &&
            aCookieA.path == aCookieB.path &&
            ChromeUtils.isOriginAttributesEqual(aCookieA.originAttributes,
                                                aCookieB.originAttributes);
   },
 
+  _isPrivateCookie: function (aCookie) {
+      let { userContextId } = aCookie.originAttributes;
+      if (!userContextId) {
+        // Default identity is public.
+        return false;
+      }
+      return !ContextualIdentityService.getIdentityFromId(userContextId).public;
+  },
+
   observe: function (aCookie, aTopic, aData) {
     if (aTopic != "cookie-changed")
       return;
 
     if (aCookie instanceof Components.interfaces.nsICookie) {
+      if (this._isPrivateCookie(aCookie)) {
+        return;
+      }
+
       var strippedHost = this._makeStrippedHost(aCookie.host);
       if (aData == "changed")
         this._handleCookieChanged(aCookie, strippedHost);
       else if (aData == "added")
         this._handleCookieAdded(aCookie, strippedHost);
     }
     else if (aData == "cleared") {
       this._hosts = {};
@@ -485,16 +498,20 @@ var gCookiesWindow = {
   _loadCookies: function () {
     var e = this._cm.enumerator;
     var hostCount = { value: 0 };
     this._hosts = {};
     this._hostOrder = [];
     while (e.hasMoreElements()) {
       var cookie = e.getNext();
       if (cookie && cookie instanceof Components.interfaces.nsICookie) {
+        if (this._isPrivateCookie(cookie)) {
+          continue;
+        }
+
         var strippedHost = this._makeStrippedHost(cookie.host);
         this._addCookie(strippedHost, cookie, hostCount);
       }
       else
         break;
     }
     this._view._rowCount = hostCount.value;
   },
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -392,19 +392,19 @@ PluginContent.prototype = {
       // <embed> element), this call is for a window-global plugin.
       this.onPluginCrashed(event.target, event);
       return;
     }
 
     if (eventType == "HiddenPlugin") {
       let pluginTag = event.tag.QueryInterface(Ci.nsIPluginTag);
       if (event.target.defaultView.top.document != this.content.document) {
-	return;
+        return;
       }
-      this._showClickToPlayNotification(pluginTag, true);
+      this._showClickToPlayNotification(pluginTag, false);
     }
 
     let plugin = event.target;
     let doc = plugin.ownerDocument;
 
     if (!(plugin instanceof Ci.nsIObjectLoadingContent))
       return;
 
--- a/build/autoconf/alloc.m4
+++ b/build/autoconf/alloc.m4
@@ -17,26 +17,26 @@ for file in $MALLOC_HEADERS; do
 done
 
 MOZ_CHECK_HEADERS(alloca.h)
 
 AC_CHECK_FUNCS(strndup posix_memalign memalign)
 
 AC_CHECK_FUNCS(malloc_usable_size)
 MALLOC_USABLE_SIZE_CONST_PTR=const
-MOZ_CHECK_HEADERS([malloc.h], [
+if test -n "$HAVE_MALLOC_H"; then
   AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
   AC_TRY_COMPILE([#include <malloc.h>
                   #include <stddef.h>
                   size_t malloc_usable_size(const void *ptr);],
                   [return malloc_usable_size(0);],
                   AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   MALLOC_USABLE_SIZE_CONST_PTR=)
-])
+fi
 AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
 
 
 dnl In newer bionic headers, valloc is built but not defined,
 dnl so we check more carefully here.
 AC_MSG_CHECKING([for valloc in malloc.h])
 AC_EGREP_HEADER(valloc, malloc.h,
                 AC_DEFINE(HAVE_VALLOC)
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -6,69 +6,19 @@ AC_DEFUN([MOZ_ANDROID_NDK],
 [
 
 MOZ_ARG_WITH_STRING(android-cxx-stl,
 [  --with-android-cxx-stl=VALUE
                           use the specified C++ STL (stlport, libstdc++, libc++)],
     android_cxx_stl=$withval,
     android_cxx_stl=libc++)
 
-define([MIN_ANDROID_VERSION], [9])
-android_version=MIN_ANDROID_VERSION
-
-MOZ_ARG_WITH_STRING(android-version,
-[  --with-android-version=VER
-                          android platform version, default] MIN_ANDROID_VERSION,
-    android_version=$withval)
-
-if test $android_version -lt MIN_ANDROID_VERSION ; then
-    AC_MSG_ERROR([--with-android-version must be at least MIN_ANDROID_VERSION.])
-fi
-
 case "$target" in
 *-android*|*-linuxandroid*)
-    AC_MSG_CHECKING([for android platform directory])
-
-    case "$target_cpu" in
-    arm)
-        target_name=arm
-        ;;
-    i?86)
-        target_name=x86
-        ;;
-    mipsel)
-        target_name=mips
-        ;;
-    esac
-
-    dnl Not all Android releases have their own platform release. We use
-    dnl the next lower platform version in these cases.
-    case $android_version in
-    11|10)
-        android_platform_version=9
-        ;;
-    20)
-        android_platform_version=19
-        ;;
-    22)
-        android_platform_version=21
-        ;;
-    *)
-        android_platform_version=$android_version
-        ;;
-    esac
-
-    android_platform="$android_ndk"/platforms/android-"$android_platform_version"/arch-"$target_name"
-
-    if test -d "$android_platform" ; then
-        AC_MSG_RESULT([$android_platform])
-    else
-        AC_MSG_ERROR([not found. Please check your NDK. With the current configuration, it should be in $android_platform])
-    fi
-
+    dnl $android_platform will be set for us by Python configure.
     CPPFLAGS="-idirafter $android_platform/usr/include $CPPFLAGS"
     CFLAGS="-fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-fno-short-enums -fno-exceptions $CXXFLAGS"
     ASFLAGS="-idirafter $android_platform/usr/include -DANDROID $ASFLAGS"
 
     dnl Add --allow-shlib-undefined, because libGLESv2 links to an
     dnl undefined symbol (present on the hardware, just not in the
     dnl NDK.)
deleted file mode 100644
--- a/build/autoconf/mozcommonheader.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-dnl This Source Code Form is subject to the terms of the Mozilla Public
-dnl License, v. 2.0. If a copy of the MPL was not distributed with this
-dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-AC_DEFUN(MOZ_CHECK_COMMON_HEADERS,
-	MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h sys/bitypes.h \
-        memory.h unistd.h gnu/libc-version.h nl_types.h malloc.h \
-        X11/XKBlib.h io.h cpuid.h)
-)
deleted file mode 100644
--- a/build/autoconf/winsdk.m4
+++ /dev/null
@@ -1,22 +0,0 @@
-dnl This Source Code Form is subject to the terms of the Mozilla Public
-dnl License, v. 2.0. If a copy of the MPL was not distributed with this
-dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-dnl Identify which version of the SDK we're building with
-dnl Windows Server 2008 and newer SDKs have WinSDKVer.h, get the version
-dnl from there
-AC_DEFUN([MOZ_FIND_WINSDK_VERSION], [
-  AC_CACHE_CHECK(for highest Windows version supported by this SDK,
-                 ac_cv_winsdk_maxver,
-                 [cat > conftest.h <<EOF
-#include <winsdkver.h>
-
-WINVER_MAXVER
-EOF
-                      ac_cv_winsdk_maxver=`$CPP conftest.h 2>/dev/null | tail -n1`
-                      rm -f conftest.h
-                     ])
-      dnl WinSDKVer.h returns the version number in 4-digit format while many
-      dnl consumers expect 8. Therefore, pad the result with an extra 4 zeroes.
-      MOZ_WINSDK_MAXVER=${ac_cv_winsdk_maxver}0000
-])
--- a/build/moz.configure/android-ndk.configure
+++ b/build/moz.configure/android-ndk.configure
@@ -9,27 +9,96 @@ js_option('--with-android-ndk', nargs=1,
           help='location where the Android NDK can be found')
 
 js_option('--with-android-toolchain', nargs=1,
           help='location of the Android toolchain')
 
 js_option('--with-android-gnu-compiler-version', nargs=1,
           help='GNU compiler version to use')
 
+@depends('--help')
+def min_android_version(_):
+    return '9'
+
+js_option('--with-android-version',
+          nargs=1,
+          help='android platform version',
+          default=min_android_version)
+
+@depends('--with-android-version', min_android_version)
+@imports(_from='__builtin__', _import='ValueError')
+def android_version(value, min_version):
+    if not value:
+        # Someone has passed --without-android-version.
+        die('--with-android-version cannot be disabled.')
+
+    try:
+        version = int(value[0])
+    except ValueError:
+        die('--with-android-version expects an integer value')
+
+    if version < int(min_version):
+        die('--with-android-version must be at least %s (got %s)',
+            min_version, value[0])
+
+    return version
+
+add_old_configure_assignment('android_version', android_version)
+
 @depends('--with-android-ndk', build_project)
 def ndk(value, build_project):
     if build_project == 'mobile/android' and not value:
         die('You must specify --with-android-ndk=/path/to/ndk when '
             'building mobile/android')
     if value:
         return value[0]
 
 set_config('ANDROID_NDK', ndk)
 add_old_configure_assignment('android_ndk', ndk)
 
+@depends(target, android_version, ndk)
+@checking('for android platform directory')
+def android_platform(target, android_version, ndk):
+    if target.os != 'Android':
+        return
+
+    if 'mips' in target.cpu:
+        target_dir_name = 'mips'
+    else:
+        target_dir_name = target.cpu
+
+    # Not all Android releases have their own platform release. We use
+    # the next lower platform version in these cases.
+    if android_version in (11, 10):
+        platform_version = 9
+    elif android_version in (20, 22):
+        platform_version = android_version - 1
+    else:
+        platform_version = android_version
+
+    platform_dir = os.path.join(ndk,
+                                'platforms',
+                                'android-%s' % platform_version,
+                                'arch-%s' % target_dir_name)
+
+    if not os.path.isdir(platform_dir):
+        die("Android platform directory not found. With the current "
+            "configuration, it should be in %s" % platform_dir)
+
+    return platform_dir
+
+add_old_configure_assignment('android_platform', android_platform)
+
+@depends(android_platform)
+def extra_toolchain_flags(platform_dir):
+    if not platform_dir:
+        return []
+    return ['-idirafter',
+            os.path.join(platform_dir, 'usr', 'include')]
+
 @depends(target, host, ndk, '--with-android-toolchain',
          '--with-android-gnu-compiler-version')
 @checking('for the Android toolchain directory', lambda x: x or 'not found')
 @imports(_from='mozbuild.shellutil', _import='quote')
 def android_toolchain(target, host, ndk, toolchain, gnu_compiler_version):
     if not ndk:
         return
     if toolchain:
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/compilechecks.configure
@@ -0,0 +1,110 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+
+# Generates a test program and attempts to compile it. In case of failure, the
+# resulting check will return None. If the test program succeeds, it will return
+# the output of the test program.
+# - `includes` are the includes (as file names) that will appear at the top of
+#   the generated test program.
+# - `body` is the code that will appear in the main function of the generated
+#   test program. `return 0;` is appended to the function body automatically.
+# - `language` is the language selection, so that the appropriate compiler is
+#   used.
+# - `flags` are the flags to be passed to the compiler, in addition to `-c`.
+# - `check_msg` is the message to be printed to accompany compiling the test
+#   program.
+@template
+@imports('textwrap')
+def try_compile(includes=None, body='', language='C++', flags=None, check_msg=None):
+    includes = includes or []
+    source_lines = ['#include <%s>' % f for f in includes]
+    source = '\n'.join(source_lines) + '\n'
+    source += textwrap.dedent('''\
+        int
+        main(void)
+        {
+        %s
+          ;
+          return 0;
+        }
+    ''' % body)
+
+    if check_msg:
+        def checking_fn(fn):
+            return checking(check_msg, callback=lambda r: r is not None)(fn)
+    else:
+        def checking_fn(fn):
+            return fn
+
+    def get_flags():
+        if flags:
+            return flags[:]
+
+    @depends(cxx_compiler, c_compiler, extra_toolchain_flags)
+    @checking_fn
+    def check(cxx_info, c_info, extra_flags):
+        flags = get_flags() or []
+        flags += extra_flags
+        flags.append('-c')
+
+        info = {
+            'C': c_info,
+            'C++': cxx_info,
+        }[language]
+        return try_invoke_compiler(info.wrapper + [info.compiler] + info.flags,
+                                   language, source, flags,
+                                   onerror=lambda: None)
+    return check
+
+# Checks for the presence of the given header on the target system by compiling
+# a test program including that header. The return value of the template is a
+# check function returning True if the header is present, and None if it is not.
+# The value of this check function is also used to set a variable (with set_define)
+# corresponding to the checked header. For instance, HAVE_MALLOC_H will be set in
+# defines if check_header if called with 'malloc.h' as input and malloc.h is
+# present on the target.
+# - `header` is the header, as a file name, to check for.
+# - `language` is the language selection, so that the appropriate compiler is
+#   used.
+# - `flags` are the flags to be passed to the compiler, in addition to `-c`.
+# - `includes` are additional includes, as file names, to appear before the
+#   header checked for.
+# - `when` is a depends function that if present will make performing the check
+#   conditional on the value of that function.
+@template
+def check_header(header, language='C++', flags=None, includes=None, when=None):
+    when = when or depends('--help')(lambda _: True)
+
+    if includes:
+        includes = includes[:]
+    else:
+        includes = []
+    includes.append(header)
+
+    @depends_when(try_compile(includes=includes, language=language, flags=flags,
+                              check_msg='for %s' % header), when=when)
+    def have_header(value):
+        if value is not None:
+            return True
+    header_var = 'HAVE_%s' % (header.upper()
+                                    .replace('-', '_')
+                                    .replace('/', '_')
+                                    .replace('.', '_'))
+    set_define(header_var, have_header)
+    return have_header
+
+# A convenience wrapper for check_header for checking multiple headers.
+# returns an array of the resulting checks in order corresponding to the
+# provided headers.
+# - `headers` are the headers to be checked.
+# - `kwargs` are keyword arguments passed verbatim to check_header.
+@template
+def check_headers(*headers, **kwargs):
+    checks = []
+    for header in headers:
+        checks.append(check_header(header, **kwargs))
+    return checks
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/headers.configure
@@ -0,0 +1,63 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+# Check for headers defining standard int types.
+check_header('stdint.h')
+have_inttypes = check_header('inttypes.h')
+
+set_config('HAVE_INTTYPES_H', have_inttypes)
+
+# Checks for headers relevant to non-windows systems.
+non_msvc_compiler = depends(c_compiler)(lambda info: info.type != 'msvc')
+
+building_linux = depends(target)(lambda target: target.kernel == 'Linux')
+
+have_malloc = check_header('malloc.h')
+
+add_old_configure_assignment('HAVE_MALLOC_H', have_malloc)
+
+check_headers(
+    'sys/byteorder.h',
+    'getopt.h',
+    'unistd.h',
+    'nl_types.h',
+    'cpuid.h',
+    when=non_msvc_compiler,
+)
+
+# These are all the places some variant of statfs can be hiding.
+check_headers(
+    'sys/statvfs.h',
+    'sys/statfs.h',
+    'sys/vfs.h',
+    'sys/mount.h',
+    when=non_msvc_compiler,
+)
+
+# Quota support
+check_header('sys/quota.h',
+             when=non_msvc_compiler)
+check_header('linux/quota.h',
+             includes=['sys/socket.h'],
+             when=building_linux)
+
+# SCTP support - needs various network include headers
+check_headers(
+    'linux/if_addr.h',
+    'linux/rtnetlink.h',
+    includes=['sys/socket.h'],
+    when=building_linux,
+)
+
+check_header('sys/queue.h',
+             when=non_msvc_compiler)
+
+check_headers(
+    'sys/types.h',
+    'netinet/in.h',
+    'byteswap.h',
+    when=non_msvc_compiler,
+)
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -267,17 +267,16 @@ def old_configure_options(*options):
     '--no-create',
     '--prefix',
     '--with-adjust-sdk-keyfile',
     '--with-android-cxx-stl',
     '--with-android-distribution-directory',
     '--with-android-max-sdk',
     '--with-android-min-sdk',
     '--with-android-sdk',
-    '--with-android-version',
     '--with-app-basename',
     '--with-app-name',
     '--with-arch',
     '--with-bing-api-keyfile',
     '--with-branding',
     '--with-crashreporter-enable-percent',
     '--with-cross-lib',
     '--with-debug-label',
@@ -317,17 +316,16 @@ def old_configure_options(*options):
     '--with-system-nspr',
     '--with-system-nss',
     '--with-system-png',
     '--with-system-zlib',
     '--with-thumb',
     '--with-thumb-interwork',
     '--with-unify-dist',
     '--with-user-appdir',
-    '--with-windows-version',
     '--x-includes',
     '--x-libraries',
 
     # Below are the configure flags used by comm-central.
     '--enable-ldap',
     '--enable-mapi',
     '--enable-calendar',
     '--enable-incomplete-external-linkage',
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -50,27 +50,30 @@ set_config('YASM_ASFLAGS', yasm_asflags)
 def have_yasm(value):
     if value:
         return True
 
 set_config('HAVE_YASM', have_yasm)
 # Until the YASM variable is not necessary in old-configure.
 add_old_configure_assignment('YASM', have_yasm)
 
+@depends('--help')
+def extra_toolchain_flags(_):
+    # This value will be overriden for android builds, where
+    # extra flags are required to do basic checks.
+    return []
 
 # Android NDK
 # ==============================================================
 
 @depends('--disable-compile-environment', build_project, gonkdir, '--help')
-def android_ndk_include(compile_env, build_project, gonkdir, _):
-    if compile_env and (gonkdir or build_project in ('mobile/android', 'js')):
-        return 'android-ndk.configure'
+def compiling_android(compile_env, build_project, gonkdir, _):
+    return compile_env and (gonkdir or build_project in ('mobile/android', 'js'))
 
-include(android_ndk_include)
-
+include_when('android-ndk.configure', when=compiling_android)
 
 # MacOS deployment target version
 # ==============================================================
 # This needs to happen before any compilation test is done.
 
 option('--enable-macos-target', env='MACOSX_DEPLOYMENT_TARGET', nargs=1,
        default='10.7', help='Set the minimum MacOS version needed at runtime')
 
@@ -163,41 +166,18 @@ def toolchain_prefix(value, target, host
         return '%s-' % target.toolchain
 
 set_config('TOOLCHAIN_PREFIX', toolchain_prefix)
 add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
 
 
 # Compilers
 # ==============================================================
-@imports('os')
-@imports('subprocess')
-@imports(_from='mozbuild.configure.util', _import='LineIO')
-@imports(_from='tempfile', _import='mkstemp')
 def try_preprocess(compiler, language, source):
-    suffix = {
-        'C': '.c',
-        'C++': '.cpp',
-    }[language]
-
-    fd, path = mkstemp(prefix='conftest.', suffix=suffix)
-    try:
-        source = source.encode('ascii', 'replace')
-
-        log.debug('Creating `%s` with content:', path)
-        with LineIO(lambda l: log.debug('| %s', l)) as out:
-            out.write(source)
-
-        os.write(fd, source)
-        os.close(fd)
-        cmd = compiler + ['-E', path]
-        return check_cmd_output(*cmd)
-    finally:
-        os.remove(path)
-
+    return try_invoke_compiler(compiler, language, source, ['-E'])
 
 @imports(_from='mozbuild.configure.constants', _import='CompilerType')
 @imports(_from='mozbuild.configure.constants',
          _import='CPU_preprocessor_checks')
 @imports(_from='mozbuild.configure.constants',
          _import='kernel_preprocessor_checks')
 @imports(_from='textwrap', _import='dedent')
 def get_compiler_info(compiler, language):
@@ -395,16 +375,81 @@ def check_compiler(compiler, language, t
         version=info.version,
         target_cpu=info.cpu,
         target_kernel=info.kernel,
         target_endianness=info.endianness,
         flags=flags,
     )
 
 
+@imports(_from='collections', _import='defaultdict')
+@imports(_from='__builtin__', _import='sorted')
+def get_vc_paths(base):
+    vc = defaultdict(lambda: defaultdict(dict))
+    subkey = r'Microsoft\VisualStudio\VC\*\*\*\Compiler'
+    for v, h, t, p in get_registry_values(base + '\\' + subkey):
+        vc[v][h][t] = p
+    if not vc:
+        return
+    version, data = sorted(vc.iteritems(), key=lambda x: Version(x[0]))[-1]
+    return data
+
+
+@depends(host)
+@imports('platform')
+def vc_compiler_path(host):
+    if host.kernel != 'WINNT':
+        return
+    vc_host = {
+        'x86': 'x86',
+        'AMD64': 'x64',
+    }.get(platform.machine())
+    if vc_host is None:
+        return
+    vc_target = {
+        'x86': 'x86',
+        'x86_64': 'x64',
+        'arm': 'arm',
+    }.get(host.cpu)
+    if vc_target is None:
+        return
+
+    base_key = r'HKEY_LOCAL_MACHINE\SOFTWARE'
+    data = get_vc_paths(base_key)
+    if not data:
+        data = get_vc_paths(base_key + r'\Wow6432Node')
+    if not data:
+        return
+
+    path = data.get(vc_host, {}).get(vc_target)
+    if not path and vc_host == 'x64':
+        vc_host = 'x86'
+        path = data.get(vc_host, {}).get(vc_target)
+    if not path:
+        return
+    path = os.path.dirname(path)
+    if vc_host != vc_target:
+        other_path = data.get(vc_host, {}).get(vc_host)
+        if other_path:
+            return (path, os.path.dirname(other_path))
+    return (path,)
+
+
+@depends(vc_compiler_path)
+@imports('os')
+def toolchain_search_path(vc_compiler_path):
+    if vc_compiler_path:
+        result = [os.environ.get('PATH')]
+        result.extend(vc_compiler_path)
+        # We're going to alter PATH for good in windows.configure, but we also
+        # need to do it for the valid_compiler() check below.
+        os.environ['PATH'] = os.pathsep.join(result)
+        return result
+
+
 @template
 def default_c_compilers(host_or_target):
     '''Template defining the set of default C compilers for the host and
     target platforms.
     `host_or_target` is either `host` or `target` (the @depends functions
     from init.configure.
     '''
     assert host_or_target in (host, target)
@@ -536,17 +581,18 @@ def compiler(language, host_or_target, c
                     for k, v in other_compiler.__dict__.iteritems()
                 })
 
     # Normally, we'd use `var` instead of `_var`, but the interaction with
     # old-configure complicates things, and for now, we a) can't take the plain
     # result from check_prog as CC/CXX/HOST_CC/HOST_CXX and b) have to let
     # old-configure AC_SUBST it (because it's autoconf doing it, not us)
     compiler = check_prog('_%s' % var, what=what, progs=default_compilers,
-                          input=delayed_getattr(provided_compiler, 'compiler'))
+                          input=delayed_getattr(provided_compiler, 'compiler'),
+                          paths=toolchain_search_path)
 
     @depends(compiler, provided_compiler, compiler_wrapper, host_or_target)
     @checking('whether %s can be used' % what, lambda x: bool(x))
     @imports(_from='mozbuild.shellutil', _import='quote')
     def valid_compiler(compiler, provided_compiler, compiler_wrapper,
                        host_or_target):
         wrapper = list(compiler_wrapper or ())
         if provided_compiler:
@@ -694,16 +740,18 @@ def compiler(language, host_or_target, c
 
 c_compiler = compiler('C', target)
 cxx_compiler = compiler('C++', target, c_compiler=c_compiler)
 host_c_compiler = compiler('C', host, other_compiler=c_compiler)
 host_cxx_compiler = compiler('C++', host, c_compiler=host_c_compiler,
                              other_compiler=cxx_compiler,
                              other_c_compiler=c_compiler)
 
+include('compilechecks.configure')
+
 @depends(c_compiler)
 def default_debug_flags(compiler_info):
     # Debug info is ON by default.
     if compiler_info.type == 'msvc':
         return '-Zi'
     return '-g'
 
 option(env='MOZ_DEBUG_FLAGS',
@@ -774,9 +822,10 @@ add_old_configure_assignment('MOZ_DEBUG_
 @depends(c_compiler, target)
 def libcxx_inline_visibility(c_compiler, target):
     if c_compiler.type == 'clang' and target.os == 'Android':
         return ''
 
 set_define('_LIBCPP_INLINE_VISIBILITY', libcxx_inline_visibility)
 set_define('_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49', libcxx_inline_visibility)
 
+include('windows.configure')
 include('rust.configure')
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -80,23 +80,155 @@ def find_program(file, paths=None):
                     "not %r", paths)
             paths = list(itertools.chain(
                 *(p.split(pathsep) for p in paths if p)))
         return normsep(which(file, path=paths))
     except WhichError:
         return None
 
 
+@imports('os')
+@imports('subprocess')
+@imports(_from='mozbuild.configure.util', _import='LineIO')
+@imports(_from='tempfile', _import='mkstemp')
+def try_invoke_compiler(compiler, language, source, flags=None, onerror=None):
+    flags = flags or []
+
+    if not isinstance(flags, (list, tuple)):
+        die("Flags provided to try_compile must be a list of strings, "
+            "not %r", paths)
+
+    suffix = {
+        'C': '.c',
+        'C++': '.cpp',
+    }[language]
+
+    fd, path = mkstemp(prefix='conftest.', suffix=suffix)
+    try:
+        source = source.encode('ascii', 'replace')
+
+        log.debug('Creating `%s` with content:', path)
+        with LineIO(lambda l: log.debug('| %s', l)) as out:
+            out.write(source)
+
+        os.write(fd, source)
+        os.close(fd)
+        cmd = compiler + list(flags) + [path]
+        kwargs = {'onerror': onerror}
+        return check_cmd_output(*cmd, **kwargs)
+    finally:
+        os.remove(path)
+
+
 def unique_list(l):
     result = []
     for i in l:
         if l not in result:
             result.append(i)
     return result
 
+
+# Get values out of the Windows registry. This function can only be called on
+# Windows.
+# The `pattern` argument is a string starting with HKEY_ and giving the full
+# "path" of the registry key to get the value for, with backslash separators.
+# The string can contains wildcards ('*').
+# The result of this functions is an enumerator yielding tuples for each
+# match. Each of these tuples contains the key name matching wildcards
+# followed by the value.
+#
+# Examples:
+#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
+#                       r'Windows Kits\Installed Roots\KitsRoot*')
+#   yields e.g.:
+#     ('KitsRoot81', r'C:\Program Files (x86)\Windows Kits\8.1\')
+#     ('KitsRoot10', r'C:\Program Files (x86)\Windows Kits\10\')
+#
+#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
+#                       r'Windows Kits\Installed Roots\KitsRoot8.1')
+#   yields e.g.:
+#     (r'C:\Program Files (x86)\Windows Kits\8.1\',)
+#
+#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
+#                       r'Windows Kits\*\KitsRoot*')
+#   yields e.g.:
+#     ('Installed Roots', 'KitsRoot81',
+#      r'C:\Program Files (x86)\Windows Kits\8.1\')
+#     ('Installed Roots', 'KitsRoot10',
+#      r'C:\Program Files (x86)\Windows Kits\10\')
+#
+#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
+#                       r'VisualStudio\VC\*\x86\*\Compiler')
+#   yields e.g.:
+#     ('19.0', 'arm', r'C:\...\amd64_arm\cl.exe')
+#     ('19.0', 'x64', r'C:\...\amd64\cl.exe')
+#     ('19.0', 'x86', r'C:\...\amd64_x86\cl.exe')
+@imports(_import='_winreg', _as='winreg')
+@imports(_from='__builtin__', _import='WindowsError')
+@imports(_from='fnmatch', _import='fnmatch')
+def get_registry_values(pattern):
+    def enum_helper(func, key):
+        i = 0
+        while True:
+            try:
+                yield func(key, i)
+            except WindowsError:
+                break
+            i += 1
+
+    def get_keys(key, pattern):
+        try:
+            s = winreg.OpenKey(key, '\\'.join(pattern[:-1]))
+        except WindowsError:
+            return
+        for k in enum_helper(winreg.EnumKey, s):
+            if fnmatch(k, pattern[-1]):
+                try:
+                    yield k, winreg.OpenKey(s, k)
+                except WindowsError:
+                    pass
+
+    def get_values(key, pattern):
+        try:
+            s = winreg.OpenKey(key, '\\'.join(pattern[:-1]))
+        except WindowsError:
+            return
+        for k, v, t in enum_helper(winreg.EnumValue, s):
+            if fnmatch(k, pattern[-1]):
+                yield k, v
+
+    def split_pattern(pattern):
+        subpattern = []
+        for p in pattern:
+            subpattern.append(p)
+            if '*' in p:
+                yield subpattern
+                subpattern = []
+        if subpattern:
+            yield subpattern
+
+    pattern = pattern.split('\\')
+    assert pattern[0].startswith('HKEY_')
+    keys = [(getattr(winreg, pattern[0]),)]
+    pattern = list(split_pattern(pattern[1:]))
+    for i, p in enumerate(pattern):
+        next_keys = []
+        for base_key in keys:
+            matches = base_key[:-1]
+            base_key = base_key[-1]
+            if i == len(pattern) - 1:
+                want_name = '*' in p[-1]
+                for name, value in get_values(base_key, p):
+                    yield matches + ((name, value) if want_name else (value,))
+            else:
+                for name, k in get_keys(base_key, p):
+                    next_keys.append(matches + (name, k))
+        keys = next_keys
+
+
 @imports(_from='mozbuild.configure.util', _import='Version', _as='_Version')
 def Version(v):
     'A version number that can be compared usefully.'
     return _Version(v)
 
 # Denotes a deprecated option. Combines option() and @depends:
 # @deprecated_option('--option')
 # def option(value):
@@ -176,8 +308,18 @@ def depends_when(*args, **kwargs):
     when = kwargs['when']
     def decorator(fn):
         @depends(when, *args)
         def wrapper(val, *args):
             if val:
                 return fn(*args)
         return wrapper
     return decorator
+
+# Includes a file when the given condition evaluates to a truthy value.
+@template
+def include_when(filename, when):
+    # Assume, for now, our condition already depends on --help.
+    @depends(when, '--help')
+    def conditional_include(value, _):
+        if value:
+            return filename
+    include(conditional_include)
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/windows.configure
@@ -0,0 +1,195 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+option('--with-windows-version', nargs=1, default='603',
+       help='Windows SDK version to target. Win 8.1 (603) is currently'
+            'the minimum supported version.')
+
+@depends(target)
+def is_windows(target):
+    return target.kernel == 'WINNT'
+
+
+@template
+def depends_win(*args):
+    return depends_when(*args, when=is_windows)
+
+
+@depends_win('--with-windows-version')
+@imports(_from='__builtin__', _import='ValueError')
+def valid_windows_version(value):
+    if not value:
+        die('Cannot build with --without-windows-version')
+    try:
+        version = int(value[0], 16)
+        if version in (0x603,):
+            return version
+    except ValueError:
+        pass
+
+    die('Invalid value for --with-windows-version (%s)', value[0])
+
+
+option(env='WINDOWSSDKDIR', nargs=1,
+       help='Directory containing the Windows SDK')
+
+@depends_win('WINDOWSSDKDIR', host)
+def windows_sdk_dir(value, host):
+    if value:
+        return value
+    if host.kernel != 'WINNT':
+        return ()
+
+    return tuple(x[1] for x in get_registry_values(
+        r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots'
+        r'\KitsRoot*'))
+
+@imports(_from='mozbuild.shellutil', _import='quote')
+def valid_windows_sdk_dir_result(value):
+    if value:
+        return '0x%04x in %s' % (value.version, quote(value.path))
+
+@depends_win(c_compiler, windows_sdk_dir, valid_windows_version,
+             'WINDOWSSDKDIR')
+@checking('for Windows SDK', valid_windows_sdk_dir_result)
+@imports(_from='__builtin__', _import='sorted')
+@imports(_from='textwrap', _import='dedent')
+def valid_windows_sdk_dir(compiler, windows_sdk_dir, target_version,
+                          windows_sdk_dir_env):
+    if windows_sdk_dir_env:
+        windows_sdk_dir_env = windows_sdk_dir_env[0]
+    sdks = {}
+    for d in windows_sdk_dir:
+        um_dir = os.path.join(d, 'include', 'um')
+        shared_dir = os.path.join(d, 'include', 'shared')
+        if os.path.isdir(um_dir) and os.path.isdir(shared_dir):
+            check = dedent('''\
+            #include <winsdkver.h>
+            WINVER_MAXVER
+            ''')
+            result = try_preprocess(compiler.wrapper + [compiler.compiler] +
+                                    compiler.flags +
+                                    ['-I', um_dir, '-I', shared_dir], 'C',
+                                    check)
+            if result:
+                maxver = result.splitlines()[-1]
+                try:
+                    maxver = int(maxver, 0)
+                except:
+                    pass
+                else:
+                    sdks[d] = maxver
+                    continue
+        if d == windows_sdk_dir_env:
+            raise FatalCheckError(
+                'Error while checking the version of the SDK in '
+                'WINDOWSSDKDIR (%s). Please verify it contains a valid and '
+                'complete SDK installation.' % windows_sdk_dir_env)
+
+    valid_sdks = sorted(sdks, key=lambda x: sdks[x], reverse=True)
+    if valid_sdks:
+        biggest_version = sdks[valid_sdks[0]]
+    if not valid_sdks or biggest_version < target_version:
+        if windows_sdk_dir_env:
+            raise FatalCheckError(
+                'You are targeting Windows version 0x%04x, but your SDK only '
+                'supports up to version 0x%04x. Install and use an updated SDK, '
+                'or target a lower version using --with-windows-version. '
+                'Alternatively, try running the Windows SDK Configuration Tool '
+                'and selecting a newer SDK. See '
+                'https://developer.mozilla.org/En/Windows_SDK_versions for '
+                'details on fixing this.' % (target_version, biggest_version))
+
+        raise FatalCheckError(
+            'Cannot find a Windows SDK for version >= 0x%04x.' % target_version)
+
+    return namespace(
+        path=valid_sdks[0],
+        version=biggest_version,
+    )
+
+
+add_old_configure_assignment(
+    'WINDOWSSDKDIR',
+    delayed_getattr(valid_windows_sdk_dir, 'path'))
+add_old_configure_assignment(
+    'MOZ_WINSDK_MAXVER',
+    depends(valid_windows_sdk_dir)(
+        lambda x: '0x%04X0000' % x.version if x else None))
+
+
+option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool')
+
+@depends_win(valid_windows_sdk_dir)
+@imports(_from='os', _import='environ')
+@imports('platform')
+def sdk_bin_path(valid_windows_sdk_dir):
+    if not valid_windows_sdk_dir:
+        return
+
+    vc_host = {
+        'x86': 'x86',
+        'AMD64': 'x64',
+    }.get(platform.machine())
+
+    result = [
+        environ['PATH'],
+        os.path.join(valid_windows_sdk_dir.path, 'bin', vc_host)
+    ]
+    if vc_host == 'x64':
+        result.append(
+            os.path.join(valid_windows_sdk_dir.path, 'bin', 'x86'))
+    return result
+
+
+# Normally, we'd use `MT` instead of `_MT`, but for now, we want MT to only contain
+# mt.exe.
+mt = check_prog('_MT', depends_win()(lambda: ('mt.exe',)), what='mt',
+                input='MT', paths=sdk_bin_path)
+
+
+# Check that MT is not something unexpected like "magnetic tape manipulation
+# utility".
+@depends_win(mt)
+@checking('whether MT is really Microsoft Manifest Tool', lambda x: bool(x))
+@imports('re')
+@imports('subprocess')
+def valid_mt(path):
+    try:
+        out = subprocess.check_output([path]).splitlines()
+        out = '\n'.join(l for l in out
+                        if 'Microsoft (R) Manifest Tool' in l)
+        if out:
+              m = re.search(r'(?<=[^!-~])[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+',
+                            out)
+              if not m:
+                  raise FatalCheckError(
+                      'Unknown version of the Microsoft Manifest Tool')
+              return namespace(
+                  path=path,
+                  version=Version(m.group(0)),
+              )
+    except subprocess.CalledProcessError:
+        pass
+    raise FatalCheckError('%s is not Microsoft Manifest Tool')
+
+
+set_config('MT', depends_if(valid_mt)(lambda x: os.path.basename(x.path)))
+set_config('MSMANIFEST_TOOL', depends(valid_mt)(lambda x: bool(x)))
+
+
+# Normally, we'd just have CC, etc. set to absolute paths, but the build system
+# doesn't currently handle properly the case where the paths contain spaces.
+# Additionally, there's the issue described in toolchain.configure, in
+# valid_compiler().
+@depends_win(sdk_bin_path)
+@imports('os')
+def alter_path(sdk_bin_path):
+    path = os.pathsep.join(sdk_bin_path)
+    os.environ['PATH'] = path
+    return path
+
+set_config('PATH', alter_path)
--- a/build/subconfigure.py
+++ b/build/subconfigure.py
@@ -201,26 +201,29 @@ def prepare(srcdir, objdir, shell, args)
     if os.path.exists(data_file):
         with open(data_file, 'rb') as f:
             data = pickle.load(f)
             previous_args = data['args']
 
     # Msys likes to break environment variables and command line arguments,
     # so read those from stdin, as they are passed from the configure script
     # when necessary (on windows).
-    # However, for some reason, $PATH is not handled like other environment
-    # variables, and msys remangles it even when giving it is already a msys
-    # $PATH. Fortunately, the mangling/demangling is just find for $PATH, so
-    # we can just take the value from the environment. Msys will convert it
-    # back properly when calling subconfigure.
     input = sys.stdin.read()
     if input:
         data = {a: b for [a, b] in eval(input)}
         environ = {a: b for a, b in data['env']}
-        environ['PATH'] = os.environ['PATH']
+        # These environment variables as passed from old-configure may contain
+        # posix-style paths, which will not be meaningful to the js
+        # subconfigure, which runs as a native python process, so use their
+        # values from the environment. In the case of autoconf implemented
+        # subconfigures, Msys will re-convert them properly.
+        for var in ('HOME', 'TERM', 'PATH', 'TMPDIR', 'TMP',
+                    'TEMP', 'INCLUDE'):
+            if var in environ and var in os.environ:
+                environ[var] = os.environ[var]
         args = data['args']
     else:
         environ = os.environ
 
     args, others = parser.parse_known_args(args)
 
     data = {
         'target': args.target,
--- a/build/win32/mozconfig.vs2015-win64
+++ b/build/win32/mozconfig.vs2015-win64
@@ -1,14 +1,15 @@
 if [ -z "${VSPATH}" ]; then
     TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
     VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2015u2"
+    VSWINPATH="$(cd ${TOOLTOOL_DIR} && pwd -W)/vs2015u2"
 fi
 
-export WINDOWSSDKDIR="${VSPATH}/SDK"
+export WINDOWSSDKDIR="${VSWINPATH}/SDK"
 export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT"
 export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86"
 
 export PATH="${VSPATH}/VC/bin/amd64_x86:${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x86:${VSPATH}/SDK/bin/x64:${VSPATH}/DIASDK/bin:${PATH}"
 export PATH="${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}"
 
 export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/ucrt:${VSPATH}/SDK/Include/shared:${VSPATH}/SDK/Include/um:${VSPATH}/SDK/Include/winrt:${VSPATH}/DIASDK/include"
 export LIB="${VSPATH}/VC/lib:${VSPATH}/VC/atlmfc/lib:${VSPATH}/SDK/lib/ucrt/x86:${VSPATH}/SDK/lib/um/x86:${VSPATH}/DIASDK/lib"
--- a/build/win64/mozconfig.vs2015
+++ b/build/win64/mozconfig.vs2015
@@ -1,14 +1,15 @@
 if [ -z "${VSPATH}" ]; then
     TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
     VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2015u2"
+    VSWINPATH="$(cd ${TOOLTOOL_DIR} && pwd -W)/vs2015u2"
 fi
 
-export WINDOWSSDKDIR="${VSPATH}/SDK"
+export WINDOWSSDKDIR="${VSWINPATH}/SDK"
 export WIN32_REDIST_DIR=${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT
 export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"
 
 export PATH="${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x64:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${VSPATH}/DIASDK/bin/amd64:${PATH}"
 
 export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/ucrt:${VSPATH}/SDK/Include/shared:${VSPATH}/SDK/Include/um:${VSPATH}/SDK/Include/winrt:${VSPATH}/DIASDK/include"
 export LIB="${VSPATH}/VC/lib/amd64:${VSPATH}/VC/atlmfc/lib/amd64:${VSPATH}/SDK/lib/ucrt/x64:${VSPATH}/SDK/lib/um/x64:${VSPATH}/DIASDK/lib/amd64"
 
--- a/devtools/client/inspector/breadcrumbs.js
+++ b/devtools/client/inspector/breadcrumbs.js
@@ -346,17 +346,17 @@ HTMLBreadcrumbs.prototype = {
     this.separators.innerHTML =
                       "<div id='breadcrumb-separator-before'></div>" +
                       "<div id='breadcrumb-separator-after'></div>" +
                       "<div id='breadcrumb-separator-normal'></div>";
     this.container.parentNode.appendChild(this.separators);
 
     this.outer.addEventListener("click", this, true);
     this.outer.addEventListener("mouseover", this, true);
-    this.outer.addEventListener("mouseleave", this, true);
+    this.outer.addEventListener("mouseout", this, true);
     this.outer.addEventListener("focus", this, true);
 
     this.shortcuts = new KeyShortcuts({ window: this.chromeWin, target: this.outer });
     this.handleShortcut = this.handleShortcut.bind(this);
 
     this.shortcuts.on("Right", this.handleShortcut);
     this.shortcuts.on("Left", this.handleShortcut);
     this.shortcuts.on("Tab", this.handleShortcut);
@@ -477,17 +477,17 @@ HTMLBreadcrumbs.prototype = {
    * Generic event handler.
    * @param {DOMEvent} event.
    */
   handleEvent: function (event) {
     if (event.type == "click" && event.button == 0) {
       this.handleClick(event);
     } else if (event.type == "mouseover") {
       this.handleMouseOver(event);
-    } else if (event.type == "mouseleave") {
+    } else if (event.type == "mouseout") {
       this.handleMouseLeave(event);
     } else if (event.type == "focus") {
       this.handleFocus(event);
     }
   },
 
   /**
    * Focus event handler. When breadcrumbs container gets focus, if there is an
@@ -528,20 +528,20 @@ HTMLBreadcrumbs.prototype = {
   handleMouseOver: function (event) {
     let target = event.originalTarget;
     if (target.tagName == "button") {
       target.onBreadcrumbsHover();
     }
   },
 
   /**
-   * On mouse leave, make sure to unhighlight.
+   * On mouse out, make sure to unhighlight.
    * @param {DOMEvent} event.
    */
-  handleMouseLeave: function (event) {
+  handleMouseOut: function (event) {
     this.inspector.toolbox.highlighterUtils.unhighlight();
   },
 
   /**
    * Handle a keyboard shortcut supported by the breadcrumbs widget.
    *
    * @param {String} name
    *        Name of the keyboard shortcut received.
@@ -588,17 +588,17 @@ HTMLBreadcrumbs.prototype = {
   destroy: function () {
     this.selection.off("new-node-front", this.update);
     this.selection.off("pseudoclass", this.updateSelectors);
     this.selection.off("attribute-changed", this.updateSelectors);
     this.inspector.off("markupmutation", this.update);
 
     this.container.removeEventListener("click", this, true);
     this.container.removeEventListener("mouseover", this, true);
-    this.container.removeEventListener("mouseleave", this, true);
+    this.container.removeEventListener("mouseout", this, true);
     this.container.removeEventListener("focus", this, true);
     this.shortcuts.destroy();
 
     this.empty();
     this.separators.remove();
 
     this.arrowScrollBox.off("overflow", this.scroll);
     this.arrowScrollBox.destroy();
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -127,29 +127,29 @@ function MarkupView(inspector, frame, co
   this._mutationObserver = this._mutationObserver.bind(this);
   this._onDisplayChange = this._onDisplayChange.bind(this);
   this._onMouseClick = this._onMouseClick.bind(this);
   this._onMouseUp = this._onMouseUp.bind(this);
   this._onNewSelection = this._onNewSelection.bind(this);
   this._onCopy = this._onCopy.bind(this);
   this._onFocus = this._onFocus.bind(this);
   this._onMouseMove = this._onMouseMove.bind(this);
-  this._onMouseLeave = this._onMouseLeave.bind(this);
+  this._onMouseOut = this._onMouseOut.bind(this);
   this._onToolboxPickerHover = this._onToolboxPickerHover.bind(this);
   this._onCollapseAttributesPrefChange =
     this._onCollapseAttributesPrefChange.bind(this);
   this._isImagePreviewTarget = this._isImagePreviewTarget.bind(this);
   this._onBlur = this._onBlur.bind(this);
 
   EventEmitter.decorate(this);
 
   // Listening to various events.
   this._elt.addEventListener("click", this._onMouseClick, false);
   this._elt.addEventListener("mousemove", this._onMouseMove, false);
-  this._elt.addEventListener("mouseleave", this._onMouseLeave, false);
+  this._elt.addEventListener("mouseout", this._onMouseOut, false);
   this._elt.addEventListener("blur", this._onBlur, true);
   this.win.addEventListener("mouseup", this._onMouseUp);
   this.win.addEventListener("copy", this._onCopy);
   this._frame.addEventListener("focus", this._onFocus, false);
   this.walker.on("mutations", this._mutationObserver);
   this.walker.on("display-change", this._onDisplayChange);
   this._inspector.selection.on("new-node-front", this._onNewSelection);
   this._inspector.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
@@ -396,17 +396,22 @@ MarkupView.prototype = {
     if (this._hoveredNode) {
       this.getContainer(this._hoveredNode).hovered = false;
     }
 
     this.getContainer(nodeFront).hovered = true;
     this._hoveredNode = nodeFront;
   },
 
-  _onMouseLeave: function () {
+  _onMouseOut: function (event) {
+    // Emulate mouseleave by skipping any relatedTarget inside the markup-view.
+    if (this._elt.contains(event.relatedTarget)) {
+      return;
+    }
+
     if (this._autoScrollAnimationFrame) {
       this.win.cancelAnimationFrame(this._autoScrollAnimationFrame);
     }
     if (this.isDragging) {
       return;
     }
 
     this._hideBoxModel(true);
@@ -1736,17 +1741,17 @@ MarkupView.prototype = {
     this.undo.destroy();
     this.undo = null;
 
     this.popup.destroy();
     this.popup = null;
 
     this._elt.removeEventListener("click", this._onMouseClick, false);
     this._elt.removeEventListener("mousemove", this._onMouseMove, false);
-    this._elt.removeEventListener("mouseleave", this._onMouseLeave, false);
+    this._elt.removeEventListener("mouseout", this._onMouseOut, false);
     this._elt.removeEventListener("blur", this._onBlur, true);
     this.win.removeEventListener("mouseup", this._onMouseUp);
     this.win.removeEventListener("copy", this._onCopy);
     this._frame.removeEventListener("focus", this._onFocus, false);
     this.walker.off("mutations", this._mutationObserver);
     this.walker.off("display-change", this._onDisplayChange);
     this._inspector.selection.off("new-node-front", this._onNewSelection);
     this._inspector.toolbox.off("picker-node-hovered",
--- a/devtools/client/inspector/shared/style-inspector-overlays.js
+++ b/devtools/client/inspector/shared/style-inspector-overlays.js
@@ -60,17 +60,17 @@ function HighlightersOverlay(view) {
   this.view = view;
 
   let {CssRuleView} = require("devtools/client/inspector/rules/rules");
   this.isRuleView = view instanceof CssRuleView;
 
   this.highlighterUtils = this.view.inspector.toolbox.highlighterUtils;
 
   this._onMouseMove = this._onMouseMove.bind(this);
-  this._onMouseLeave = this._onMouseLeave.bind(this);
+  this._onMouseOut = this._onMouseOut.bind(this);
 
   this.highlighters = {};
 
   // Only initialize the overlay if at least one of the highlighter types is
   // supported
   this.supportsHighlighters =
     this.highlighterUtils.supportsCustomHighlighters();
 
@@ -86,17 +86,18 @@ HighlightersOverlay.prototype = {
    */
   addToView: function () {
     if (!this.supportsHighlighters || this._isStarted || this._isDestroyed) {
       return;
     }
 
     let el = this.view.element;
     el.addEventListener("mousemove", this._onMouseMove, false);
-    el.addEventListener("mouseleave", this._onMouseLeave, false);
+    el.addEventListener("mouseout", this._onMouseOut, false);
+    el.ownerDocument.defaultView.addEventListener("mouseout", this._onMouseOut, false);
 
     this._isStarted = true;
   },
 
   /**
    * Remove the overlay from the current view. This will stop tracking mouse
    * movement and showing highlighters
    */
@@ -104,17 +105,17 @@ HighlightersOverlay.prototype = {
     if (!this.supportsHighlighters || !this._isStarted || this._isDestroyed) {
       return;
     }
 
     this._hideCurrent();
 
     let el = this.view.element;
     el.removeEventListener("mousemove", this._onMouseMove, false);
-    el.removeEventListener("mouseleave", this._onMouseLeave, false);
+    el.removeEventListener("mouseout", this._onMouseOut, false);
 
     this._isStarted = false;
   },
 
   _onMouseMove: function (event) {
     // Bail out if the target is the same as for the last mousemove
     if (event.target === this._lastHovered) {
       return;
@@ -145,17 +146,24 @@ HighlightersOverlay.prototype = {
           .then(shown => {
             if (shown) {
               this.emit("highlighter-shown");
             }
           });
     }
   },
 
-  _onMouseLeave: function () {
+  _onMouseOut: function (event) {
+    // Only hide the highlighter if the mouse leaves the currently hovered node.
+    if (!this._lastHovered ||
+        (event && this._lastHovered.contains(event.relatedTarget))) {
+      return;
+    }
+
+    // Otherwise, hide the highlighter.
     this._lastHovered = null;
     this._hideCurrent();
   },
 
   /**
    * Is the current hovered node a css transform property value in the rule-view
    *
    * @param {Object} nodeInfo
--- a/devtools/client/inspector/shared/test/browser_styleinspector_transform-highlighter-03.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_transform-highlighter-03.js
@@ -55,17 +55,17 @@ add_task(function* () {
   let {valueSpan} = getRuleViewProperty(view, "body", "transform");
 
   info("Checking that the HighlighterFront's show/hide methods are called");
   let onHighlighterShown = hs.once("highlighter-shown");
   hs._onMouseMove({target: valueSpan});
   yield onHighlighterShown;
   ok(HighlighterFront.isShown, "The highlighter is shown");
   let onHighlighterHidden = hs.once("highlighter-hidden");
-  hs._onMouseLeave();
+  hs._onMouseOut();
   yield onHighlighterHidden;
   ok(!HighlighterFront.isShown, "The highlighter is hidden");
 
   info("Checking that hovering several times over the same property doesn't" +
     " show the highlighter several times");
   let nb = HighlighterFront.nbOfTimesShown;
   onHighlighterShown = hs.once("highlighter-shown");
   hs._onMouseMove({target: valueSpan});
--- a/devtools/client/shared/widgets/tooltip/TooltipToggle.js
+++ b/devtools/client/shared/widgets/tooltip/TooltipToggle.js
@@ -19,17 +19,17 @@ const DEFAULT_TOGGLE_DELAY = 50;
  * provided to the start() method to know whether or not the node being
  * hovered over should indeed receive the tooltip.
  */
 function TooltipToggle(tooltip) {
   this.tooltip = tooltip;
   this.win = tooltip.doc.defaultView;
 
   this._onMouseMove = this._onMouseMove.bind(this);
-  this._onMouseLeave = this._onMouseLeave.bind(this);
+  this._onMouseOut = this._onMouseOut.bind(this);
 
   this._onTooltipMouseOver = this._onTooltipMouseOver.bind(this);
   this._onTooltipMouseOut = this._onTooltipMouseOut.bind(this);
 }
 
 module.exports.TooltipToggle = TooltipToggle;
 
 TooltipToggle.prototype = {
@@ -79,17 +79,17 @@ TooltipToggle.prototype = {
     }
 
     this._baseNode = baseNode;
     this._targetNodeCb = targetNodeCb || (() => true);
     this._toggleDelay = toggleDelay;
     this._interactive = interactive;
 
     baseNode.addEventListener("mousemove", this._onMouseMove);
-    baseNode.addEventListener("mouseleave", this._onMouseLeave);
+    baseNode.addEventListener("mouseout", this._onMouseOut);
 
     if (this._interactive) {
       this.tooltip.container.addEventListener("mouseover", this._onTooltipMouseOver);
       this.tooltip.container.addEventListener("mouseout", this._onTooltipMouseOut);
     }
   },
 
   /**
@@ -100,17 +100,17 @@ TooltipToggle.prototype = {
   stop: function () {
     this.win.clearTimeout(this.toggleTimer);
 
     if (!this._baseNode) {
       return;
     }
 
     this._baseNode.removeEventListener("mousemove", this._onMouseMove);
-    this._baseNode.removeEventListener("mouseleave", this._onMouseLeave);
+    this._baseNode.removeEventListener("mouseout", this._onMouseOut);
 
     if (this._interactive) {
       this.tooltip.container.removeEventListener("mouseover", this._onTooltipMouseOver);
       this.tooltip.container.removeEventListener("mouseout", this._onTooltipMouseOut);
     }
 
     this._baseNode = null;
     this._targetNodeCb = null;
@@ -147,17 +147,22 @@ TooltipToggle.prototype = {
     let res = yield this._targetNodeCb(target, this.tooltip);
     if (res) {
       return res.nodeName ? res : target;
     }
 
     return null;
   }),
 
-  _onMouseLeave: function () {
+  _onMouseOut: function (event) {
+    // Only hide the tooltip if the mouse leaves baseNode.
+    if (event && this._baseNode && !this._baseNode.contains(event.relatedTarget)) {
+      return;
+    }
+
     this._lastHovered = null;
     this.win.clearTimeout(this.toggleTimer);
     this.toggleTimer = this.win.setTimeout(() => {
       this.tooltip.hide();
     }, this._toggleDelay);
   },
 
   _onTooltipMouseOver() {
--- a/dom/animation/ComputedTimingFunction.cpp
+++ b/dom/animation/ComputedTimingFunction.cpp
@@ -14,17 +14,16 @@ void
 ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
 {
   mType = aFunction.mType;
   if (nsTimingFunction::IsSplineType(mType)) {
     mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
                          aFunction.mFunc.mX2, aFunction.mFunc.mY2);
   } else {
     mSteps = aFunction.mSteps;
-    mStepSyntax = aFunction.mStepSyntax;
   }
 }
 
 static inline double
 StepTiming(uint32_t aSteps,
            double aPortion,
            ComputedTimingFunction::BeforeFlag aBeforeFlag,
            nsTimingFunction::Type aType)
@@ -136,19 +135,16 @@ ComputedTimingFunction::Compare(const Co
     if (order != 0) {
       return order;
     }
   } else if (mType == nsTimingFunction::Type::StepStart ||
              mType == nsTimingFunction::Type::StepEnd) {
     if (mSteps != aRhs.mSteps) {
       return int32_t(mSteps) - int32_t(aRhs.mSteps);
     }
-    if (mStepSyntax != aRhs.mStepSyntax) {
-      return int32_t(mStepSyntax) - int32_t(aRhs.mStepSyntax);
-    }
   }
 
   return 0;
 }
 
 void
 ComputedTimingFunction::AppendToString(nsAString& aResult) const
 {
@@ -157,18 +153,17 @@ ComputedTimingFunction::AppendToString(n
       nsStyleUtil::AppendCubicBezierTimingFunction(mTimingFunction.X1(),
                                                    mTimingFunction.Y1(),
                                                    mTimingFunction.X2(),
                                                    mTimingFunction.Y2(),
                                                    aResult);
       break;
     case nsTimingFunction::Type::StepStart:
     case nsTimingFunction::Type::StepEnd:
-      nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, mStepSyntax,
-                                             aResult);
+      nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, aResult);
       break;
     default:
       nsStyleUtil::AppendCubicBezierKeywordTimingFunction(mType, aResult);
       break;
   }
 }
 
 /* static */ int32_t
--- a/dom/animation/ComputedTimingFunction.h
+++ b/dom/animation/ComputedTimingFunction.h
@@ -26,24 +26,22 @@ public:
   const nsSMILKeySpline* GetFunction() const
   {
     NS_ASSERTION(HasSpline(), "Type mismatch");
     return &mTimingFunction;
   }
   nsTimingFunction::Type GetType() const { return mType; }
   bool HasSpline() const { return nsTimingFunction::IsSplineType(mType); }
   uint32_t GetSteps() const { return mSteps; }
-  nsTimingFunction::StepSyntax GetStepSyntax() const { return mStepSyntax; }
   bool operator==(const ComputedTimingFunction& aOther) const
   {
     return mType == aOther.mType &&
            (HasSpline() ?
             mTimingFunction == aOther.mTimingFunction :
-            (mSteps == aOther.mSteps &&
-             mStepSyntax == aOther.mStepSyntax));
+            mSteps == aOther.mSteps);
   }
   bool operator!=(const ComputedTimingFunction& aOther) const
   {
     return !(*this == aOther);
   }
   int32_t Compare(const ComputedTimingFunction& aRhs) const;
   void AppendToString(nsAString& aResult) const;
 
@@ -55,14 +53,13 @@ public:
   }
   static int32_t Compare(const Maybe<ComputedTimingFunction>& aLhs,
                          const Maybe<ComputedTimingFunction>& aRhs);
 
 private:
   nsTimingFunction::Type mType;
   nsSMILKeySpline mTimingFunction;
   uint32_t mSteps;
-  nsTimingFunction::StepSyntax mStepSyntax;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ComputedTimingFunction_h
--- a/dom/animation/test/css-animations/file_keyframeeffect-getkeyframes.html
+++ b/dom/animation/test/css-animations/file_keyframeeffect-getkeyframes.html
@@ -166,26 +166,22 @@ function assert_frames_equal(a, b, name)
 // getKeyframes() will group frames with the same easing function
 // together (by nsTimingFunction::Compare).
 const kTimingFunctionValues = [
   "ease",
   "linear",
   "ease-in",
   "ease-out",
   "ease-in-out",
-  "step-start",
   "steps(1, start)",
   "steps(2, start)",
-  "step-end",
   "steps(1)",
-  "steps(1, end)",
   "steps(2)",
-  "steps(2, end)",
   "cubic-bezier(0, 0, 1, 1)",
-  "cubic-bezier(0, 0.25, 0.75, 1)",
+  "cubic-bezier(0, 0.25, 0.75, 1)"
 ];
 
 test(function(t) {
   var div = addDiv(t);
 
   div.style.animation = 'anim-empty 100s';
   assert_equals(getKeyframes(div).length, 0,
                 "number of frames with empty @keyframes");
@@ -251,33 +247,33 @@ test(function(t) {
   div.style.animation = 'anim-simple-timing 100s';
   var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
   assert_equals(frames[0].easing, "linear",
                 "value of 'easing' on ComputedKeyframe #0");
   assert_equals(frames[1].easing, "ease-in-out",
                 "value of 'easing' on ComputedKeyframe #1");
-  assert_equals(frames[2].easing, "step-end",
+  assert_equals(frames[2].easing, "steps(1)",
                 "value of 'easing' on ComputedKeyframe #2");
 }, 'KeyframeEffectReadOnly.getKeyframes() returns frames with expected easing'
    + ' values, when the easing is specified on each keyframe');
 
 test(function(t) {
   var div = addDiv(t);
 
   div.style.animation = 'anim-simple-timing-some 100s step-start';
   var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
   assert_equals(frames[0].easing, "linear",
                 "value of 'easing' on ComputedKeyframe #0");
-  assert_equals(frames[1].easing, "step-start",
+  assert_equals(frames[1].easing, "steps(1, start)",
                 "value of 'easing' on ComputedKeyframe #1");
-  assert_equals(frames[2].easing, "step-start",
+  assert_equals(frames[2].easing, "steps(1, start)",
                 "value of 'easing' on ComputedKeyframe #2");
 }, 'KeyframeEffectReadOnly.getKeyframes() returns frames with expected easing'
    + ' values, when the easing is specified on some keyframes');
 
 test(function(t) {
   var div = addDiv(t);
 
   div.style.animation = 'anim-simple-shorthand 100s';
@@ -423,17 +419,17 @@ test(function(t) {
   div.style.animation = 'anim-different-props-and-easing 100s';
   var frames = getKeyframes(div);
 
   assert_equals(frames.length, 4, "number of frames");
 
   var expected = [
     { offset: 0, computedOffset: 0, easing: "linear",
       color: "rgb(0, 0, 0)", marginTop: "8px" },
-    { offset: 0.25, computedOffset: 0.25, easing: "step-end",
+    { offset: 0.25, computedOffset: 0.25, easing: "steps(1)",
       color: "rgb(0, 0, 255)" },
     { offset: 0.75, computedOffset: 0.75, easing: "ease-in",
       marginTop: "12px" },
     { offset: 1, computedOffset: 1, easing: "ease",
       color: "rgb(255, 255, 255)", marginTop: "16px" },
   ];
 
   for (var i = 0; i < frames.length; i++) {
@@ -469,17 +465,17 @@ test(function(t) {
   var div = addDiv(t);
 
   div.style.animation = 'anim-merge-offset-and-easing 100s';
   var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
 
   var expected = [
-    { offset: 0, computedOffset: 0, easing: "step-end",
+    { offset: 0, computedOffset: 0, easing: "steps(1)",
       color: "rgb(0, 0, 0)", fontSize: "16px" },
     { offset: 0, computedOffset: 0, easing: "linear",
       marginTop: "8px", paddingLeft: "2px" },
     { offset: 1, computedOffset: 1, easing: "ease",
       color: "rgb(255, 255, 255)", fontSize: "32px", marginTop: "16px",
       paddingLeft: "4px" },
   ];
 
@@ -491,26 +487,22 @@ test(function(t) {
    'different easing functions');
 
 test(function(t) {
   var div = addDiv(t);
 
   div.style.animation = 'anim-no-merge-equiv-easing 100s';
   var frames = getKeyframes(div);
 
-  assert_equals(frames.length, 5, "number of frames");
+  assert_equals(frames.length, 3, "number of frames");
 
   var expected = [
-    { offset: 0, computedOffset: 0, easing: "steps(1, end)",
-      marginTop: "0px" },
-    { offset: 0, computedOffset: 0, easing: "step-end",
-      marginRight: "0px" },
     { offset: 0, computedOffset: 0, easing: "steps(1)",
-      marginBottom: "0px" },
-    { offset: 0.5, computedOffset: 0.5, easing: "step-end",
+      marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
+    { offset: 0.5, computedOffset: 0.5, easing: "steps(1)",
       marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
     { offset: 1, computedOffset: 1, easing: "ease",
       marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
   ];
 
   for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
@@ -670,12 +662,11 @@ test(function(t) {
       marginRight: "100px",
       marginTop: "100px" },
   ];
   for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffectReadOnly.getKeyframes() returns expected values for ' +
    'animations with CSS variables as keyframe values in a shorthand property');
-
 done();
 </script>
 </body>
--- a/dom/animation/test/css-transitions/file_keyframeeffect-getkeyframes.html
+++ b/dom/animation/test/css-transitions/file_keyframeeffect-getkeyframes.html
@@ -54,17 +54,17 @@ test(function(t) {
   div.style.transition = 'left 100s steps(2,end)';
   div.style.left = '100px';
 
   var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
   var expected = [
-    { offset: 0, computedOffset: 0, easing: "steps(2, end)", left: "0px" },
+    { offset: 0, computedOffset: 0, easing: "steps(2)", left: "0px" },
     { offset: 1, computedOffset: 1, easing: "linear", left: "100px" },
   ];
 
   for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffectReadOnly.getKeyframes() returns expected frames for a simple'
    + ' transition with a non-default easing function');
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -81,25 +81,23 @@ GetErrorMessage(void* aUserRef, const un
 }
 
 uint16_t
 GetErrorArgCount(const ErrNum aErrorNumber)
 {
   return GetErrorMessage(nullptr, aErrorNumber)->argCount;
 }
 
-bool
-ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...)
+void
+binding_detail::ThrowErrorMessage(JSContext* aCx, const unsigned aErrorNumber, ...)
 {
   va_list ap;
   va_start(ap, aErrorNumber);
-  JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr,
-                         static_cast<const unsigned>(aErrorNumber), ap);
+  JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr, aErrorNumber, ap);
   va_end(ap);
-  return false;
 }
 
 bool
 ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
                  bool aSecurityError, const char* aInterfaceName)
 {
   NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName);
   // This should only be called for DOM methods/getters/setters, which
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -62,18 +62,28 @@ uint16_t constexpr ErrorFormatNumArgs[] 
 #include "mozilla/dom/Errors.msg"
 #undef MSG_DEF
 };
 #endif
 
 uint16_t
 GetErrorArgCount(const ErrNum aErrorNumber);
 
-bool
-ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
+namespace binding_detail {
+void ThrowErrorMessage(JSContext* aCx, const unsigned aErrorNumber, ...);
+} // namespace binding_detail
+
+template<typename... Ts>
+inline bool
+ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, Ts&&... aArgs)
+{
+  binding_detail::ThrowErrorMessage(aCx, static_cast<const unsigned>(aErrorNumber),
+                                    mozilla::Forward<Ts>(aArgs)...);
+  return false;
+}
 
 struct StringArrayAppender
 {
   static void Append(nsTArray<nsString>& aArgs, uint16_t aCount)
   {
     MOZ_RELEASE_ASSERT(aCount == 0, "Must give at least as many string arguments as are required by the ErrNum.");
   }
 
--- a/dom/bindings/GenerateCSS2PropertiesWebIDL.py
+++ b/dom/bindings/GenerateCSS2PropertiesWebIDL.py
@@ -42,29 +42,29 @@ def generate(output, idlFilename, prepro
         if not prop.startswith("Moz"):
             prop = prop[0].lower() + prop[1:]
         props += generateLine(prop, extendedAttrs)
 
         # Per spec, what's actually supposed to happen here is that we're supposed
         # to have properties for:
         #
         # 1) Each supported CSS property name, camelCased.
-        # 2) Each supported name that contains dashes but doesn't start with a
-        #    dash, without any changes to the name.
+        # 2) Each supported name that contains or starts with dashes,
+        #    without any changes to the name.
         # 3) cssFloat
         #
         # Note that "float" will cause a property called "float" to exist due to (1)
         # in that list.
         #
         # In practice, cssFloat is the only case in which "name" doesn't contain
         # "-" but also doesn't match "prop".  So the above generatePropLine() call
         # covered (3) and all of (1) except "float".  If we now output attributes
-        # for all the cases where "name" doesn't match "prop" and "name" doesn't
-        # start with "-", that will cover "float" and (2).
-        if prop != name and name[0] != "-":
+        # for all the cases where "name" doesn't match "prop", that will cover
+        # "float" and (2).
+        if prop != name:
             extendedAttrs.append('BinaryName="%s"' % prop)
             # Throw in a '_' before the attribute name, because some of these
             # property names collide with IDL reserved words.
             props += generateLine("_" + name, extendedAttrs)
 
 
     idlFile = open(idlFilename, "r")
     idlTemplate = idlFile.read()
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/WebGLContextEvent.h"
 #include "mozilla/EnumeratedArrayCycleCollection.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ProcessPriorityManager.h"
+#include "mozilla/ScopeExit.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
 #include "nsError.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIConsoleService.h"
 #include "nsIDOMEvent.h"
@@ -280,18 +281,20 @@ WebGLContext::DestroyResourcesAndContext
     mFakeBlack_2D_0001       = nullptr;
     mFakeBlack_CubeMap_0000  = nullptr;
     mFakeBlack_CubeMap_0001  = nullptr;
     mFakeBlack_3D_0000       = nullptr;
     mFakeBlack_3D_0001       = nullptr;
     mFakeBlack_2D_Array_0000 = nullptr;
     mFakeBlack_2D_Array_0001 = nullptr;
 
-    if (mFakeVertexAttrib0BufferObject)
+    if (mFakeVertexAttrib0BufferObject) {
         gl->fDeleteBuffers(1, &mFakeVertexAttrib0BufferObject);
+        mFakeVertexAttrib0BufferObject = 0;
+    }
 
     // disable all extensions except "WEBGL_lose_context". see bug #927969
     // spec: http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
     for (size_t i = 0; i < size_t(WebGLExtensionID::Max); ++i) {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
         if (!IsExtensionEnabled(extension) || (extension == WebGLExtensionID::WEBGL_lose_context))
             continue;
@@ -301,17 +304,19 @@ WebGLContext::DestroyResourcesAndContext
     }
 
     // We just got rid of everything, so the context had better
     // have been going away.
     if (GLContext::ShouldSpew()) {
         printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
     }
 
-    gl = nullptr;
+    MOZ_ASSERT(gl);
+    mGL_OnlyClearInDestroyResourcesAndContext = nullptr;
+    MOZ_ASSERT(!gl);
 }
 
 void
 WebGLContext::Invalidate()
 {
     if (!mCanvasElement)
         return;
 
@@ -664,32 +669,37 @@ WebGLContext::CreateAndInitGLWith(FnCrea
                                   const gl::SurfaceCaps& baseCaps,
                                   gl::CreateContextFlags flags,
                                   std::vector<FailureReason>* const out_failReasons)
 {
     std::queue<gl::SurfaceCaps> fallbackCaps;
     PopulateCapFallbackQueue(baseCaps, &fallbackCaps);
 
     MOZ_RELEASE_ASSERT(!gl, "GFX: Already have a context.");
-    gl = nullptr;
+    RefPtr<gl::GLContext> potentialGL;
     while (!fallbackCaps.empty()) {
         const gl::SurfaceCaps& caps = fallbackCaps.front();
-        gl = fnCreateGL(caps, flags, this, out_failReasons);
-        if (gl)
+        potentialGL = fnCreateGL(caps, flags, this, out_failReasons);
+        if (potentialGL)
             break;
 
         fallbackCaps.pop();
     }
-    if (!gl)
+    if (!potentialGL)
         return false;
 
     FailureReason reason;
+
+    mGL_OnlyClearInDestroyResourcesAndContext = potentialGL;
+    MOZ_RELEASE_ASSERT(gl);
     if (!InitAndValidateGL(&reason)) {
+        DestroyResourcesAndContext();
+        MOZ_RELEASE_ASSERT(!gl);
+
         // The fail reason here should be specific enough for now.
-        gl = nullptr;
         out_failReasons->push_back(reason);
         return false;
     }
 
     return true;
 }
 
 bool
@@ -839,16 +849,20 @@ WebGLContext::ThrowEvent_WebGLContextCre
 
     GenerateWarning("Failed to create WebGL context: %s", text.BeginReading());
 }
 
 NS_IMETHODIMP
 WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
 {
     if (signedWidth < 0 || signedHeight < 0) {
+        if (!gl) {
+            Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
+                                  NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_SIZE"));
+        }
         GenerateWarning("Canvas size is too large (seems like a negative value wrapped)");
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     uint32_t width = signedWidth;
     uint32_t height = signedHeight;
 
     // Early success return cases
@@ -894,16 +908,22 @@ WebGLContext::SetDimensions(int32_t sign
 
         // everything's good, we're done here
         mResetLayer = true;
         mBackbufferNeedsClear = true;
 
         return NS_OK;
     }
 
+    nsCString failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_UNKOWN");
+    auto autoTelemetry = mozilla::MakeScopeExit([&] {
+        Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
+                              failureId);
+    });
+
     // End of early return cases.
     // At this point we know that we're not just resizing an existing context,
     // we are initializing a new context.
 
     // if we exceeded either the global or the per-principal limit for WebGL contexts,
     // lose the oldest-used context now to free resources. Note that we can't do that
     // in the WebGLContext constructor as we don't have a canvas element yet there.
     // Here is the right place to do so, as we are about to create the OpenGL context
@@ -915,50 +935,47 @@ WebGLContext::SetDimensions(int32_t sign
     // context we're creating), we may have to dispatch a context lost
     // event.
 
     // If incrementing the generation would cause overflow,
     // don't allow it.  Allowing this would allow us to use
     // resource handles created from older context generations.
     if (!(mGeneration + 1).isValid()) {
         // exit without changing the value of mGeneration
-        Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
-                              NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY"));
+        failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY");
         const nsLiteralCString text("Too many WebGL contexts created this run.");
         ThrowEvent_WebGLContextCreationError(text);
         return NS_ERROR_FAILURE;
     }
 
     // increment the generation number - Do this early because later
     // in CreateOffscreenGL(), "default" objects are created that will
     // pick up the old generation.
     ++mGeneration;
 
     bool disabled = gfxPrefs::WebGLDisabled();
 
     // TODO: When we have software webgl support we should use that instead.
     disabled |= gfxPlatform::InSafeMode();
 
     if (disabled) {
-        Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
-                              NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DISABLED"));
+        failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DISABLED");
         const nsLiteralCString text("WebGL is currently disabled.");
         ThrowEvent_WebGLContextCreationError(text);
         return NS_ERROR_FAILURE;
     }
 
     if (gfxPrefs::WebGLDisableFailIfMajorPerformanceCaveat()) {
         mOptions.failIfMajorPerformanceCaveat = false;
     }
 
     if (mOptions.failIfMajorPerformanceCaveat) {
         nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
         if (!HasAcceleratedLayers(gfxInfo)) {
-            Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
-                                  NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_CAVEAT"));
+            failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_CAVEAT");
             const nsLiteralCString text("failIfMajorPerformanceCaveat: Compositor is not"
                                         " hardware-accelerated.");
             ThrowEvent_WebGLContextCreationError(text);
             return NS_ERROR_FAILURE;
         }
     }
 
     // Alright, now let's start trying.
@@ -970,50 +987,52 @@ WebGLContext::SetDimensions(int32_t sign
     if (!CreateAndInitGL(forceEnabled, &failReasons)) {
         nsCString text("WebGL creation failed: ");
         for (const auto& cur : failReasons) {
             Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID, cur.key);
 
             text.AppendASCII("\n* ");
             text.Append(cur.info);
         }
+        failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_REASON");
         ThrowEvent_WebGLContextCreationError(text);
         return NS_ERROR_FAILURE;
     }
     MOZ_ASSERT(gl);
     MOZ_ASSERT_IF(mOptions.alpha, gl->Caps().alpha);
 
     if (mOptions.failIfMajorPerformanceCaveat) {
         if (gl->IsWARP()) {
-            gl = nullptr;
-
-            Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
-                                  NS_LITERAL_CSTRING("FEATURE_FAILURE_PERF_WARP"));
+            DestroyResourcesAndContext();
+            MOZ_ASSERT(!gl);
+
+            failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_WARP");
             const nsLiteralCString text("failIfMajorPerformanceCaveat: Driver is not"
                                         " hardware-accelerated.");
             ThrowEvent_WebGLContextCreationError(text);
             return NS_ERROR_FAILURE;
         }
 
 #ifdef XP_WIN
         if (gl->GetContextType() == gl::GLContextType::WGL &&
             !gl::sWGLLib.HasDXInterop2())
         {
-            gl = nullptr;
-
+            DestroyResourcesAndContext();
+            MOZ_ASSERT(!gl);
+
+            failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DXGL_INTEROP2");
             const nsLiteralCString text("Caveat: WGL without DXGLInterop2.");
             ThrowEvent_WebGLContextCreationError(text);
             return NS_ERROR_FAILURE;
         }
 #endif
     }
 
     if (!ResizeBackbuffer(width, height)) {
-        Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
-                              NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_RESIZE"));
+        failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
         const nsLiteralCString text("Initializing WebGL backbuffer failed.");
         ThrowEvent_WebGLContextCreationError(text);
         return NS_ERROR_FAILURE;
     }
 
     if (GLContext::ShouldSpew()) {
         printf_stderr("--- WebGL context created: %p\n", gl.get());
     }
@@ -1088,18 +1107,17 @@ WebGLContext::SetDimensions(int32_t sign
     ClearBackbufferIfNeeded();
 
     mShouldPresent = true;
 
     //////
 
     reporter.SetSuccessful();
 
-    Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
-                          NS_LITERAL_CSTRING("SUCCESS"));
+    failureId = NS_LITERAL_CSTRING("SUCCESS");
     return NS_OK;
 }
 
 void
 WebGLContext::ClearBackbufferIfNeeded()
 {
     if (!mBackbufferNeedsClear)
         return;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1388,33 +1388,37 @@ protected:
 
     GLenum mPixelStore_ColorspaceConversion;
     bool mPixelStore_FlipY;
     bool mPixelStore_PremultiplyAlpha;
 
     ////////////////////////////////////
     class FakeBlackTexture {
     public:
+        static UniquePtr<FakeBlackTexture> Create(gl::GLContext* gl,
+                                                  TexTarget target,
+                                                  FakeBlackType type);
         gl::GLContext* const mGL;
         const GLuint mGLName;
 
-        FakeBlackTexture(gl::GLContext* gl, TexTarget target, FakeBlackType type);
         ~FakeBlackTexture();
+    protected:
+        explicit FakeBlackTexture(gl::GLContext* gl);
     };
 
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_0001;
     UniquePtr<FakeBlackTexture> mFakeBlack_CubeMap_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_CubeMap_0001;
     UniquePtr<FakeBlackTexture> mFakeBlack_3D_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_3D_0001;
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0001;
 
-    void BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
+    bool BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
 
     ////////////////////////////////////
 
     // Generic Vertex Attributes
     UniquePtr<GLenum[]> mVertexAttribType;
     GLfloat mVertexAttrib0Vector[4];
     GLfloat mFakeVertexAttrib0BufferObjectVector[4];
     size_t mFakeVertexAttrib0BufferObjectSize;
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -131,17 +131,23 @@ ScopedResolveTexturesForDraw::ScopedReso
                                          funcName);
                 *out_error = true;
                 return;
             }
 
             if (fakeBlack == FakeBlackType::None)
                 continue;
 
-            mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack);
+            if (!mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack)) {
+                mWebGL->ErrorOutOfMemory("%s: Failed to create fake black texture.",
+                                         funcName);
+                *out_error = true;
+                return;
+            }
+
             mRebindRequests.push_back({texUnit, tex});
         }
     }
 
     *out_error = false;
 }
 
 ScopedResolveTexturesForDraw::~ScopedResolveTexturesForDraw()
@@ -154,17 +160,17 @@ ScopedResolveTexturesForDraw::~ScopedRes
     for (const auto& itr : mRebindRequests) {
         gl->fActiveTexture(LOCAL_GL_TEXTURE0 + itr.texUnit);
         gl->fBindTexture(itr.tex->Target().get(), itr.tex->mGLName);
     }
 
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mWebGL->mActiveTexture);
 }
 
-void
+bool
 WebGLContext::BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack)
 {
     MOZ_ASSERT(fakeBlack == FakeBlackType::RGBA0000 ||
                fakeBlack == FakeBlackType::RGBA0001);
 
     const auto fnGetSlot = [this, target, fakeBlack]() -> UniquePtr<FakeBlackTexture>*
     {
         switch (fakeBlack) {
@@ -193,22 +199,26 @@ WebGLContext::BindFakeBlack(uint32_t tex
 
     UniquePtr<FakeBlackTexture>* slot = fnGetSlot();
     if (!slot) {
         MOZ_CRASH("GFX: fnGetSlot failed.");
     }
     UniquePtr<FakeBlackTexture>& fakeBlackTex = *slot;
 
     if (!fakeBlackTex) {
-        fakeBlackTex.reset(new FakeBlackTexture(gl, target, fakeBlack));
+        fakeBlackTex = FakeBlackTexture::Create(gl, target, fakeBlack);
+        if (!fakeBlackTex) {
+            return false;
+        }
     }
 
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + texUnit);
     gl->fBindTexture(target.get(), fakeBlackTex->mGLName);
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
+    return true;
 }
 
 ////////////////////////////////////////
 
 bool
 WebGLContext::DrawInstanced_check(const char* info)
 {
     MOZ_ASSERT(IsWebGL2() ||
@@ -868,97 +878,74 @@ static GLuint
 CreateGLTexture(gl::GLContext* gl)
 {
     MOZ_ASSERT(gl->IsCurrent());
     GLuint ret = 0;
     gl->fGenTextures(1, &ret);
     return ret;
 }
 
-WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget target,
-                                                 FakeBlackType type)
-    : mGL(gl)
-    , mGLName(CreateGLTexture(gl))
+UniquePtr<WebGLContext::FakeBlackTexture>
+WebGLContext::FakeBlackTexture::Create(gl::GLContext* gl, TexTarget target,
+                                       FakeBlackType type)
 {
     GLenum texFormat;
     switch (type) {
     case FakeBlackType::RGBA0000:
         texFormat = LOCAL_GL_RGBA;
         break;
 
     case FakeBlackType::RGBA0001:
         texFormat = LOCAL_GL_RGB;
         break;
 
     default:
         MOZ_CRASH("GFX: bad type");
     }
 
-    gl::ScopedBindTexture scopedBind(mGL, mGLName, target.get());
+    UniquePtr<FakeBlackTexture> result(new FakeBlackTexture(gl));
+    gl::ScopedBindTexture scopedBind(gl, result->mGLName, target.get());
 
-    mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
-    mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
+    gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
+    gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
 
     // We allocate our zeros on the heap, and we overallocate (16 bytes instead of 4) to
     // minimize the risk of running into a driver bug in texImage2D, as it is a bit
     // unusual maybe to create 1x1 textures, and the stack may not have the alignment that
     // TexImage2D expects.
 
     const webgl::DriverUnpackInfo dui = {texFormat, texFormat, LOCAL_GL_UNSIGNED_BYTE};
     UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation.
 
     MOZ_ASSERT(gl->IsCurrent());
-    auto logANGLEError = [](GLenum source, GLenum type, GLuint id, GLenum severity,
-                            GLsizei length, const GLchar* message, const GLvoid* userParam)
-    {
-        gfxCriticalNote << message;
-    };
-
-    if (gl->IsANGLE()) {
-      gl->fEnable(LOCAL_GL_DEBUG_OUTPUT);
-      gl->fDebugMessageCallback(logANGLEError, nullptr);
-      gl->fDebugMessageControl(LOCAL_GL_DONT_CARE,
-                               LOCAL_GL_DONT_CARE,
-                               LOCAL_GL_DONT_CARE,
-                               0, nullptr,
-                               true);
-    }
 
     if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
         for (int i = 0; i < 6; ++i) {
             const TexImageTarget curTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
-            const GLenum error = DoTexImage(mGL, curTarget.get(), 0, &dui, 1, 1, 1,
+            const GLenum error = DoTexImage(gl, curTarget.get(), 0, &dui, 1, 1, 1,
                                             zeros.get());
             if (error) {
-                const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
-                                           "for `curTarget`: 0x%04x, "
-                                           "`dui`: {0x%04x, 0x%04x, 0x%04x}.",
-                                           error, curTarget.get(), dui.internalFormat,
-                                           dui.unpackFormat, dui.unpackType);
-                gfxCriticalError() << text.BeginReading();
-                MOZ_CRASH("GFX: Unexpected error during cube map FakeBlack creation.");
+                return nullptr;
             }
         }
     } else {
-        const GLenum error = DoTexImage(mGL, target.get(), 0, &dui, 1, 1, 1,
+        const GLenum error = DoTexImage(gl, target.get(), 0, &dui, 1, 1, 1,
                                         zeros.get());
         if (error) {
-            const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
-                                       "for `target`: 0x%04x, "
-                                       "`dui`: {0x%04x, 0x%04x, 0x%04x}.",
-                                       error, target.get(), dui.internalFormat,
-                                       dui.unpackFormat, dui.unpackType);
-            gfxCriticalError() << text.BeginReading();
-            MOZ_CRASH("GFX: Unexpected error during FakeBlack creation.");
+            return nullptr;
         }
     }
 
-    if (gl->IsANGLE()) {
-      gl->fDisable(LOCAL_GL_DEBUG_OUTPUT);
-    }
+    return result;
+}
+
+WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl)
+    : mGL(gl)
+    , mGLName(CreateGLTexture(gl))
+{
 }
 
 WebGLContext::FakeBlackTexture::~FakeBlackTexture()
 {
     mGL->MakeCurrent();
     mGL->fDeleteTextures(1, &mGLName);
 }
 
--- a/dom/canvas/WebGLContextUnchecked.cpp
+++ b/dom/canvas/WebGLContextUnchecked.cpp
@@ -7,18 +7,19 @@
 #include "WebGLContextUnchecked.h"
 
 #include "GLContext.h"
 #include "WebGLBuffer.h"
 #include "WebGLSampler.h"
 
 namespace mozilla {
 
-WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* gl)
-    : gl(gl)
+WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* _gl)
+    : mGL_OnlyClearInDestroyResourcesAndContext(_gl)
+    , gl(mGL_OnlyClearInDestroyResourcesAndContext) // const reference
 { }
 
 
 // -----------------------------------------------------------------------------
 // Buffer Objects
 
 void
 WebGLContextUnchecked::BindBuffer(GLenum target, WebGLBuffer* buffer)
--- a/dom/canvas/WebGLContextUnchecked.h
+++ b/dom/canvas/WebGLContextUnchecked.h
@@ -34,15 +34,21 @@ public:
     GLint   GetSamplerParameteriv(WebGLSampler* sampler, GLenum pname);
     GLfloat GetSamplerParameterfv(WebGLSampler* sampler, GLenum pname);
 
     void SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param);
     void SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const GLint* param);
     void SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param);
     void SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const GLfloat* param);
 
-protected: // data
-    RefPtr<gl::GLContext> gl;
+protected:
+    // We've had issues in the past with nulling `gl` without actually releasing
+    // all of our resources. This construction ensures that we are aware that we
+    // should only null `gl` in DestroyResourcesAndContext.
+    RefPtr<gl::GLContext> mGL_OnlyClearInDestroyResourcesAndContext;
+public:
+    // Grab a const reference so we can see changes, but can't make changes.
+    const decltype(mGL_OnlyClearInDestroyResourcesAndContext)& gl;
 };
 
 } // namespace mozilla
 
 #endif // !WEBGLCONTEXTUNCHECKED_H
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -735,17 +735,17 @@ TextTrackManager::TimeMarchesOn()
   for (uint32_t i = 0; i < eventList.Length(); ++i) {
     NS_DispatchToMainThread(eventList[i].forget());
   }
 
   // Step 16.
   for (uint32_t i = 0; i < affectedTracks.Length(); ++i) {
     TextTrack* ttrack = affectedTracks[i];
     if (ttrack) {
-      ttrack->DispatchTrustedEvent(NS_LITERAL_STRING("cuechange"));
+      ttrack->DispatchAsyncTrustedEvent(NS_LITERAL_STRING("cuechange"));
       HTMLTrackElement* trackElement = ttrack->GetTrackElement();
       if (trackElement) {
         trackElement->DispatchTrackRunnable(NS_LITERAL_STRING("cuechange"));
       }
     }
   }
 
   mLastTimeMarchesOnCalled = currentPlaybackTime;
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -313,10 +313,21 @@ TextTrack::GetLanguage(nsAString& aLangu
 {
   if (mTrackElement) {
     mTrackElement->GetSrclang(aLanguage);
   } else {
     aLanguage = mLanguage;
   }
 }
 
+void
+TextTrack::DispatchAsyncTrustedEvent(const nsString& aEventName)
+{
+  RefPtr<TextTrack> self = this;
+  NS_DispatchToMainThread(
+    NS_NewRunnableFunction([self, aEventName]() {
+      self->DispatchTrustedEvent(aEventName);
+    })
+  );
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/TextTrack.h
+++ b/dom/media/TextTrack.h
@@ -111,16 +111,18 @@ public:
   TextTrackSource GetTextTrackSource() {
     return mTextTrackSource;
   }
 
   void SetCuesInactive();
 
   void NotifyCueUpdated(TextTrackCue *aCue);
 
+  void DispatchAsyncTrustedEvent(const nsString& aEventName);
+
 private:
   ~TextTrack();
 
   RefPtr<TextTrackList> mTextTrackList;
 
   TextTrackKind mKind;
   nsString mLabel;
   nsString mLanguage;
--- a/dom/media/eme/CDMCaps.cpp
+++ b/dom/media/eme/CDMCaps.cpp
@@ -48,16 +48,17 @@ CDMCaps::AutoLock::IsKeyUsable(const Cen
 {
   mData.mMonitor.AssertCurrentThreadOwns();
   const auto& keys = mData.mKeyStatuses;
   for (size_t i = 0; i < keys.Length(); i++) {
     if (keys[i].mId != aKeyId) {
       continue;
     }
     if (keys[i].mStatus == kGMPUsable ||
+        keys[i].mStatus == kGMPOutputRestricted ||
         keys[i].mStatus == kGMPOutputDownscaled) {
       return true;
     }
   }
   return false;
 }
 
 bool
--- a/dom/media/eme/EMEUtils.cpp
+++ b/dom/media/eme/EMEUtils.cpp
@@ -143,9 +143,15 @@ KeySystemToGMPName(const nsAString& aKey
   }
   if (aKeySystem.EqualsLiteral("com.widevine.alpha")) {
     return NS_LITERAL_STRING("gmp-widevinecdm");
   }
   MOZ_ASSERT(false, "We should only call this for known GMPs");
   return EmptyString();
 }
 
+bool
+IsClearkeyKeySystem(const nsAString& aKeySystem)
+{
+  return aKeySystem.EqualsLiteral("org.w3.clearkey");
+}
+
 } // namespace mozilla
--- a/dom/media/eme/EMEUtils.h
+++ b/dom/media/eme/EMEUtils.h
@@ -97,11 +97,14 @@ struct ArrayData {
 //
 // Only call this on a properly initialized ArrayBufferViewOrArrayBuffer.
 ArrayData
 GetArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView);
 
 nsString
 KeySystemToGMPName(const nsAString& aKeySystem);
 
+bool
+IsClearkeyKeySystem(const nsAString& aKeySystem);
+
 } // namespace mozilla
 
 #endif // EME_LOG_H_
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -263,29 +263,25 @@ EnsureMinCDMVersion(mozIGeckoMediaPlugin
 
 /* static */
 MediaKeySystemStatus
 MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
                                          int32_t aMinCdmVersion,
                                          nsACString& aOutMessage,
                                          nsACString& aOutCdmVersion)
 {
-  MOZ_ASSERT(MediaPrefs::EMEEnabled());
+  MOZ_ASSERT(MediaPrefs::EMEEnabled() || IsClearkeyKeySystem(aKeySystem));
   nsCOMPtr<mozIGeckoMediaPluginService> mps =
     do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   if (NS_WARN_IF(!mps)) {
     aOutMessage = NS_LITERAL_CSTRING("Failed to get GMP service");
     return MediaKeySystemStatus::Error;
   }
 
   if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
-    if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
-      aOutMessage = NS_LITERAL_CSTRING("ClearKey was disabled");
-      return MediaKeySystemStatus::Cdm_disabled;
-    }
     return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, aOutMessage, aOutCdmVersion);
   }
 
   if (Preferences::GetBool("media.gmp-eme-adobe.visible", false)) {
     if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
       if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
         aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
         return MediaKeySystemStatus::Cdm_disabled;
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ b/dom/media/eme/MediaKeySystemAccessManager.cpp
@@ -107,18 +107,20 @@ MediaKeySystemAccessManager::Request(Det
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
                           NS_LITERAL_CSTRING("Key system string is invalid,"
                                              " or key system is unsupported"));
     diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
                                           aKeySystem, false, __func__);
     return;
   }
 
-  if (!MediaPrefs::EMEEnabled()) {
+  if (!MediaPrefs::EMEEnabled() && !IsClearkeyKeySystem(aKeySystem)) {
     // EME disabled by user, send notification to chrome so UI can inform user.
+    // Clearkey is allowed even when EME is disabled because we want the pref
+    // "media.eme.enabled" only taking effect on proprietary DRMs.
     MediaKeySystemAccess::NotifyObservers(mWindow,
                                           aKeySystem,
                                           MediaKeySystemStatus::Api_disabled);
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
                           NS_LITERAL_CSTRING("EME has been preffed off"));
     diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
                                           aKeySystem, false, __func__);
     return;
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp
@@ -3,27 +3,31 @@
  * 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/. */
 
 #include "WidevineVideoDecoder.h"
 
 #include "mp4_demuxer/AnnexB.h"
 #include "WidevineUtils.h"
 #include "WidevineVideoFrame.h"
+#include "mozilla/Move.h"
 
 using namespace cdm;
 
 namespace mozilla {
 
 WidevineVideoDecoder::WidevineVideoDecoder(GMPVideoHost* aVideoHost,
                                            RefPtr<CDMWrapper> aCDMWrapper)
   : mVideoHost(aVideoHost)
   , mCDMWrapper(Move(aCDMWrapper))
   , mExtraData(new MediaByteBuffer())
   , mSentInput(false)
+  , mReturnOutputCallDepth(0)
+  , mDrainPending(false)
+  , mResetInProgress(false)
 {
   // Expect to start with a CDM wrapper, will release it in DecodingComplete().
   MOZ_ASSERT(mCDMWrapper);
   Log("WidevineVideoDecoder created this=%p", this);
 
   // Corresponding Release is in DecodingComplete().
   AddRef();
 }
@@ -77,16 +81,18 @@ WidevineVideoDecoder::InitDecode(const G
 
 void
 WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
                              bool aMissingFrames,
                              const uint8_t* aCodecSpecificInfo,
                              uint32_t aCodecSpecificInfoLength,
                              int64_t aRenderTimeMs)
 {
+  // We should not be given new input if a drain has been initiated
+  MOZ_ASSERT(!mDrainPending);
   // We may not get the same out of the CDM decoder as we put in, and there
   // may be some latency, i.e. we may need to input (say) 30 frames before
   // we receive output. So we need to store the durations of the frames input,
   // and retrieve them on output.
   mFrameDurations[aInputFrame->TimeStamp()] = aInputFrame->Duration();
 
   mSentInput = true;
   InputBuffer sample;
@@ -119,121 +125,247 @@ WidevineVideoDecoder::Decode(GMPVideoEnc
   aInputFrame = nullptr;
 
   if (rv == kSuccess) {
     if (!ReturnOutput(frame)) {
       Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
       mCallback->Error(GMPDecodeErr);
       return;
     }
-    mCallback->InputDataExhausted();
+    // A reset should only be started at most at level mReturnOutputCallDepth 1,
+    // and if it's started it should be finished by that call by the time
+    // the it returns, so it should always be false by this point.
+    MOZ_ASSERT(!mResetInProgress);
+    // Only request more data if we don't have pending samples.
+    if (mFrameAllocationQueue.empty()) {
+      MOZ_ASSERT(mCDMWrapper);
+      mCallback->InputDataExhausted();
+    }
   } else if (rv == kNeedMoreData) {
+    MOZ_ASSERT(mCDMWrapper);
     mCallback->InputDataExhausted();
   } else {
     mCallback->Error(ToGMPErr(rv));
   }
+  // Finish a drain if pending and we have no pending ReturnOutput calls on the stack.
+  if (mDrainPending && mReturnOutputCallDepth == 0) {
+    Drain();
+  }
 }
 
+// Util class to assist with counting mReturnOutputCallDepth.
+class CounterHelper {
+public:
+  // RAII, increment counter
+  explicit CounterHelper(int32_t& counter)
+    : mCounter(counter)
+  {
+    mCounter++;
+  }
+
+  // RAII, decrement counter
+  ~CounterHelper()
+  {
+    mCounter--;
+  }
+
+private:
+  int32_t& mCounter;
+};
+
+// Util class to make sure GMP frames are freed. Holds a GMPVideoi420Frame*
+// and will destroy it when the helper is destroyed unless the held frame
+// if forgotten with ForgetFrame.
+class FrameDestroyerHelper {
+public:
+  explicit FrameDestroyerHelper(GMPVideoi420Frame*& frame)
+    : frame(frame)
+  {
+  }
+
+  // RAII, destroy frame if held.
+  ~FrameDestroyerHelper()
+  {
+    if (frame) {
+      frame->Destroy();
+    }
+    frame = nullptr;
+  }
+
+  // Forget the frame without destroying it.
+  void ForgetFrame()
+  {
+    frame = nullptr;
+  }
+
+private:
+  GMPVideoi420Frame* frame;
+};
+
+
+// Special handing is needed around ReturnOutput as it spins the IPC message
+// queue when creating an empty frame and can end up with reentrant calls into
+// the class methods.
 bool
 WidevineVideoDecoder::ReturnOutput(WidevineVideoFrame& aCDMFrame)
 {
-  GMPVideoFrame* f = nullptr;
-  auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
-  if (GMP_FAILED(err) || !f) {
-    Log("Failed to create i420 frame!\n");
-    return false;
+  MOZ_ASSERT(mReturnOutputCallDepth >= 0);
+  CounterHelper counterHelper(mReturnOutputCallDepth);
+  mFrameAllocationQueue.push_back(Move(aCDMFrame));
+  if (mReturnOutputCallDepth > 1) {
+    // In a reentrant call.
+    return true;
   }
-  auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
-  Size size = aCDMFrame.Size();
-  const int32_t yStride = aCDMFrame.Stride(VideoFrame::kYPlane);
-  const int32_t uStride = aCDMFrame.Stride(VideoFrame::kUPlane);
-  const int32_t vStride = aCDMFrame.Stride(VideoFrame::kVPlane);
-  const int32_t halfHeight = size.height / 2;
-  err = gmpFrame->CreateEmptyFrame(size.width,
-                                   size.height,
-                                   yStride,
-                                   uStride,
-                                   vStride);
-  ENSURE_GMP_SUCCESS(err, false);
-
-  err = gmpFrame->SetWidth(size.width);
-  ENSURE_GMP_SUCCESS(err, false);
-
-  err = gmpFrame->SetHeight(size.height);
-  ENSURE_GMP_SUCCESS(err, false);
+  while (!mFrameAllocationQueue.empty()) {
+    MOZ_ASSERT(mReturnOutputCallDepth == 1);
+    // If we're at call level 1 a reset should not have been started. A
+    // reset may be received during CreateEmptyFrame below, but we should not
+    // be in a reset at this stage -- this would indicate receiving decode
+    // messages before completing our reset, which we should not.
+    MOZ_ASSERT(!mResetInProgress);
+    WidevineVideoFrame currentCDMFrame = Move(mFrameAllocationQueue.front());
+    mFrameAllocationQueue.pop_front();
+    GMPVideoFrame* f = nullptr;
+    auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
+    if (GMP_FAILED(err) || !f) {
+      Log("Failed to create i420 frame!\n");
+      return false;
+    }
+    auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
+    FrameDestroyerHelper frameDestroyerHelper(gmpFrame);
+    Size size = currentCDMFrame.Size();
+    const int32_t yStride = currentCDMFrame.Stride(VideoFrame::kYPlane);
+    const int32_t uStride = currentCDMFrame.Stride(VideoFrame::kUPlane);
+    const int32_t vStride = currentCDMFrame.Stride(VideoFrame::kVPlane);
+    const int32_t halfHeight = size.height / 2;
+    // This call can cause a shmem alloc, during this alloc other calls
+    // may be made to this class and placed on the stack. ***WARNING***:
+    // other IPC calls can happen during this call, resulting in calls
+    // being made to the CDM. After this call state can have changed,
+    // and should be reevaluated.
+    err = gmpFrame->CreateEmptyFrame(size.width,
+                                     size.height,
+                                     yStride,
+                                     uStride,
+                                     vStride);
+    // Assert possible reentrant calls or resets haven't altered level unexpectedly.
+    MOZ_ASSERT(mReturnOutputCallDepth == 1);
+    ENSURE_GMP_SUCCESS(err, false);
 
-  Buffer* buffer = aCDMFrame.FrameBuffer();
-  uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
-  ENSURE_TRUE(outBuffer != nullptr, false);
-  MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
-  memcpy(outBuffer,
-         buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kYPlane),
-         yStride * size.height);
+    // If a reset started we need to dump the current frame and complete the reset.
+    if (mResetInProgress) {
+      MOZ_ASSERT(mCDMWrapper);
+      MOZ_ASSERT(mFrameAllocationQueue.empty());
+      CompleteReset();
+      return true;
+    }
+
+    err = gmpFrame->SetWidth(size.width);
+    ENSURE_GMP_SUCCESS(err, false);
 
-  outBuffer = gmpFrame->Buffer(kGMPUPlane);
-  ENSURE_TRUE(outBuffer != nullptr, false);
-  MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
-  memcpy(outBuffer,
-         buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kUPlane),
-         uStride * halfHeight);
+    err = gmpFrame->SetHeight(size.height);
+    ENSURE_GMP_SUCCESS(err, false);
+
+    Buffer* buffer = currentCDMFrame.FrameBuffer();
+    uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
+    ENSURE_TRUE(outBuffer != nullptr, false);
+    MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
+    memcpy(outBuffer,
+           buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kYPlane),
+           yStride * size.height);
 
-  outBuffer = gmpFrame->Buffer(kGMPVPlane);
-  ENSURE_TRUE(outBuffer != nullptr, false);
-  MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
-  memcpy(outBuffer,
-         buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kVPlane),
-         vStride * halfHeight);
+    outBuffer = gmpFrame->Buffer(kGMPUPlane);
+    ENSURE_TRUE(outBuffer != nullptr, false);
+    MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
+    memcpy(outBuffer,
+           buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kUPlane),
+           uStride * halfHeight);
 
-  gmpFrame->SetTimestamp(aCDMFrame.Timestamp());
+    outBuffer = gmpFrame->Buffer(kGMPVPlane);
+    ENSURE_TRUE(outBuffer != nullptr, false);
+    MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
+    memcpy(outBuffer,
+           buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kVPlane),
+           vStride * halfHeight);
+
+    gmpFrame->SetTimestamp(currentCDMFrame.Timestamp());
 
-  auto d = mFrameDurations.find(aCDMFrame.Timestamp());
-  if (d != mFrameDurations.end()) {
-    gmpFrame->SetDuration(d->second);
-    mFrameDurations.erase(d);
+    auto d = mFrameDurations.find(currentCDMFrame.Timestamp());
+    if (d != mFrameDurations.end()) {
+      gmpFrame->SetDuration(d->second);
+      mFrameDurations.erase(d);
+    }
+
+    // Forget frame so it's not deleted, call back taking ownership.
+    frameDestroyerHelper.ForgetFrame();
+    mCallback->Decoded(gmpFrame);
   }
 
-  mCallback->Decoded(gmpFrame);
-
   return true;
 }
 
 void
 WidevineVideoDecoder::Reset()
 {
   Log("WidevineVideoDecoder::Reset() mSentInput=%d", mSentInput);
+  // We shouldn't reset if a drain is pending.
+  MOZ_ASSERT(!mDrainPending);
+  mResetInProgress = true;
   if (mSentInput) {
     CDM()->ResetDecoder(kStreamTypeVideo);
   }
+  // Remove queued frames, but do not reset mReturnOutputCallDepth, let the
+  // ReturnOutput calls unwind and decrement the counter as needed.
+  mFrameAllocationQueue.clear();
   mFrameDurations.clear();
+  // Only if no ReturnOutput calls are in progress can we complete, otherwise
+  // ReturnOutput needs to finalize the reset.
+  if (mReturnOutputCallDepth == 0) {
+    CompleteReset();
+  }
+}
+
+void
+WidevineVideoDecoder::CompleteReset()
+{
   mCallback->ResetComplete();
   mSentInput = false;
+  mResetInProgress = false;
 }
 
 void
 WidevineVideoDecoder::Drain()
 {
   Log("WidevineVideoDecoder::Drain()");
+  if (mReturnOutputCallDepth > 0) {
+    Log("Drain call is reentrant, postponing drain");
+    mDrainPending = true;
+    return;
+  }
 
   Status rv = kSuccess;
   while (rv == kSuccess) {
     WidevineVideoFrame frame;
     InputBuffer sample;
     Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame);
     Log("WidevineVideoDecoder::Drain();  DecryptAndDecodeFrame() rv=%d", rv);
     if (frame.Format() == kUnknownVideoFormat) {
       break;
     }
     if (rv == kSuccess) {
       if (!ReturnOutput(frame)) {
         Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
       }
     }
   }
+  // Shouldn't be reset while draining.
+  MOZ_ASSERT(!mResetInProgress);
 
   CDM()->ResetDecoder(kStreamTypeVideo);
+  mDrainPending = false;
   mCallback->DrainComplete();
 }
 
 void
 WidevineVideoDecoder::DecodingComplete()
 {
   Log("WidevineVideoDecoder::DecodingComplete()");
   if (mCDMWrapper) {
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
@@ -11,16 +11,17 @@
 #include "gmp-api/gmp-video-decode.h"
 #include "gmp-api/gmp-video-host.h"
 #include "MediaData.h"
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"
 #include "WidevineDecryptor.h"
 #include "WidevineVideoFrame.h"
 #include <map>
+#include <deque>
 
 namespace mozilla {
 
 class WidevineVideoDecoder : public GMPVideoDecoder {
 public:
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WidevineVideoDecoder)
 
@@ -47,21 +48,32 @@ private:
   cdm::ContentDecryptionModule_8* CDM() const {
     // CDM should only be accessed before 'DecodingComplete'.
     MOZ_ASSERT(mCDMWrapper);
     // CDMWrapper ensure the CDM is non-null, no need to check again.
     return mCDMWrapper->GetCDM();
   }
 
   bool ReturnOutput(WidevineVideoFrame& aFrame);
+  void CompleteReset();
 
   GMPVideoHost* mVideoHost;
   RefPtr<CDMWrapper> mCDMWrapper;
   RefPtr<MediaByteBuffer> mExtraData;
   RefPtr<MediaByteBuffer> mAnnexB;
   GMPVideoDecoderCallback* mCallback;
   std::map<uint64_t, uint64_t> mFrameDurations;
   bool mSentInput;
+  // Frames waiting on allocation
+  std::deque<WidevineVideoFrame> mFrameAllocationQueue;
+  // Number of calls of ReturnOutput currently in progress.
+  int32_t mReturnOutputCallDepth;
+  // If we're waiting to drain. Used to prevent drain completing while
+  // ReturnOutput calls are still on the stack.
+  bool mDrainPending;
+  // If a reset is being performed. Used to track if ReturnOutput should
+  // dump current frame.
+  bool mResetInProgress;
 };
 
 } // namespace mozilla
 
 #endif // WidevineVideoDecoder_h_
--- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
@@ -17,16 +17,29 @@ WidevineVideoFrame::WidevineVideoFrame()
   , mBuffer(nullptr)
   , mTimestamp(0)
 {
   Log("WidevineVideoFrame::WidevineVideoFrame() this=%p", this);
   memset(mPlaneOffsets, 0, sizeof(mPlaneOffsets));
   memset(mPlaneStrides, 0, sizeof(mPlaneStrides));
 }
 
+WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther)
+  : mFormat(aOther.mFormat)
+  , mSize(aOther.mSize)
+  , mBuffer(aOther.mBuffer)
+  , mTimestamp(aOther.mTimestamp)
+{
+  Log("WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) this=%p, other=%p",
+      this, &aOther);
+  memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets));
+  memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides));
+  aOther.mBuffer = nullptr;
+}
+
 WidevineVideoFrame::~WidevineVideoFrame()
 {
   if (mBuffer) {
     mBuffer->Destroy();
     mBuffer = nullptr;
   }
 }
 
--- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h
@@ -10,16 +10,17 @@
 #include "content_decryption_module.h"
 #include <vector>
 
 namespace mozilla {
 
 class WidevineVideoFrame : public cdm::VideoFrame {
 public:
   WidevineVideoFrame();
+  WidevineVideoFrame(WidevineVideoFrame&& other);
   ~WidevineVideoFrame();
 
   void SetFormat(cdm::VideoFormat aFormat) override;
   cdm::VideoFormat Format() const override;
 
   void SetSize(cdm::Size aSize) override;
   cdm::Size Size() const override;
 
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -24,16 +24,17 @@
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidDecoderModule.h"
 #endif
 #include "GMPDecoderModule.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/StaticPtr.h"
+#include "mozilla/SyncRunnable.h"
 #include "mozilla/TaskQueue.h"
 
 #include "MediaInfo.h"
 #include "MediaPrefs.h"
 #include "FuzzingWrapper.h"
 #include "H264Converter.h"
 
 #include "AgnosticDecoderModule.h"
@@ -82,27 +83,41 @@ PDMFactory::PDMFactory()
 
 PDMFactory::~PDMFactory()
 {
 }
 
 void
 PDMFactory::EnsureInit() const
 {
-  StaticMutexAutoLock mon(sMonitor);
-  if (!sInstance) {
-    sInstance = new PDMFactoryImpl();
+  {
+    StaticMutexAutoLock mon(sMonitor);
+    if (sInstance) {
+      // Quick exit if we already have an instance.
+      return;
+    }
     if (NS_IsMainThread()) {
+      // On the main thread and holding the lock -> Create instance.
+      sInstance = new PDMFactoryImpl();
       ClearOnShutdown(&sInstance);
-    } else {
-      nsCOMPtr<nsIRunnable> runnable =
-        NS_NewRunnableFunction([]() { ClearOnShutdown(&sInstance); });
-      NS_DispatchToMainThread(runnable);
+      return;
     }
   }
+
+  // Not on the main thread -> Sync-dispatch creation to main thread.
+  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableFunction([]() {
+      StaticMutexAutoLock mon(sMonitor);
+      if (!sInstance) {
+        sInstance = new PDMFactoryImpl();
+        ClearOnShutdown(&sInstance);
+      }
+    });
+  SyncRunnable::DispatchToThread(mainThread, runnable);
 }
 
 already_AddRefed<MediaDataDecoder>
 PDMFactory::CreateDecoder(const CreateDecoderParams& aParams)
 {
   const TrackInfo& config = aParams.mConfig;
   bool isEncrypted = mEMEPDM && config.mCrypto.mValid;
 
--- a/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
@@ -8,17 +8,16 @@
 #include "DecoderDoctorDiagnostics.h"
 #include "GMPAudioDecoder.h"
 #include "GMPVideoDecoder.h"
 #include "MediaDataDecoderProxy.h"
 #include "MediaPrefs.h"
 #include "mozIGeckoMediaPluginService.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/StaticMutex.h"
-#include "mozilla/SyncRunnable.h"
 #include "gmp-audio-decode.h"
 #include "gmp-video-decode.h"
 #ifdef XP_WIN
 #include "WMFDecoderModule.h"
 #endif
 
 namespace mozilla {
 
@@ -164,23 +163,17 @@ GMPDecoderModule::UpdateUsableCodecs()
                              nsDependentCString(gmp.mKeySystem));
   }
 }
 
 /* static */
 void
 GMPDecoderModule::Init()
 {
-  if (!NS_IsMainThread()) {
-    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
-    nsCOMPtr<nsIRunnable> runnable =
-      NS_NewRunnableFunction([]() { Init(); });
-    SyncRunnable::DispatchToThread(mainThread, runnable);
-    return;
-  }
+  MOZ_ASSERT(NS_IsMainThread());
   // GMPService::HasPluginForAPI is main thread only, so to implement
   // SupportsMimeType() we build a table of the codecs which each whitelisted
   // GMP has and update it when any GMPs are removed or added at runtime.
   UpdateUsableCodecs();
 }
 
 /* static */
 const Maybe<nsCString>
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DXVA2Manager.h"
 #include <d3d11.h>
 #include "nsThreadUtils.h"
 #include "ImageContainer.h"
 #include "gfxWindowsPlatform.h"
 #include "D3D9SurfaceImage.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/D3D11ShareHandleImage.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/Telemetry.h"
 #include "MediaTelemetryConstants.h"
 #include "mfapi.h"
 #include "MediaPrefs.h"
 #include "MFTDecoder.h"
 #include "DriverCrashGuard.h"
@@ -627,17 +628,17 @@ D3D11DXVA2Manager::Init(nsACString& aFai
 
   gfx::D3D11VideoCrashGuard crashGuard;
   if (crashGuard.Crashed()) {
     NS_WARNING("DXVA2D3D11 crash detected");
     aFailureReason.AssignLiteral("DXVA2D3D11 crashes detected in the past");
     return E_FAIL;
   }
 
-  mDevice = gfxWindowsPlatform::GetPlatform()->CreateD3D11DecoderDevice();
+  mDevice = gfx::DeviceManagerD3D11::Get()->CreateDecoderDevice();
   if (!mDevice) {
     aFailureReason.AssignLiteral("Failed to create D3D11 device for decoder");
     return E_FAIL;
   }
 
   mDevice->GetImmediateContext(getter_AddRefs(mContext));
   if (!mContext) {
     aFailureReason.AssignLiteral("Failed to get immediate context for d3d11 device");
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #include <algorithm>
+#include <winsdkver.h>
 #include "WMFVideoMFTManager.h"
 #include "MediaDecoderReader.h"
 #include "MediaPrefs.h"
 #include "WMFUtils.h"
 #include "ImageContainer.h"
 #include "VideoUtils.h"
 #include "DXVA2Manager.h"
 #include "nsThreadUtils.h"
@@ -32,17 +33,17 @@
 
 #define LOG(...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
 
 using mozilla::layers::Image;
 using mozilla::layers::IMFYCbCrImage;
 using mozilla::layers::LayerManager;
 using mozilla::layers::LayersBackend;
 
-#if MOZ_WINSDK_MAXVER < 0x0A000000
+#if WINVER_MAXVER < 0x0A00
 // Windows 10+ SDK has VP80 and VP90 defines
 const GUID MFVideoFormat_VP80 =
 {
   0x30385056,
   0x0000,
   0x0010,
   {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
 };
--- a/dom/media/test/test_eme_request_notifications.html
+++ b/dom/media/test/test_eme_request_notifications.html
@@ -57,46 +57,39 @@ function Test(test) {
       );
     });
   });
 }
 
 var tests = [
   {
     keySystem: CLEARKEY_KEYSYSTEM,
-    shouldPass: false,
-    expectedStatus: 'api-disabled',
-    prefs: [["media.eme.enabled", false], ["media.eme.clearkey.enabled", true]]
+    shouldPass: true,
+    expectedStatus: 'cdm-created',
+    prefs: [["media.eme.enabled", false]]
   },
   {
-    keySystem: CLEARKEY_KEYSYSTEM,
-    shouldPass: false,
-    expectedStatus: 'cdm-disabled',
-    prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", false]]
-  },
-  {
-    keySystem: CLEARKEY_KEYSYSTEM + '.10000' , // A stupendously high min CDM version, presumably not installed.
+    keySystem: CLEARKEY_KEYSYSTEM + '.10000', // A stupendously high min CDM version, presumably not installed.
     shouldPass: false,
     expectedStatus: 'cdm-insufficient-version',
-    prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
+    prefs: [["media.eme.enabled", true]]
   },
   {
     keySystem: CLEARKEY_KEYSYSTEM,
     shouldPass: true,
     expectedStatus: 'cdm-created',
-    prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
+    prefs: [["media.eme.enabled", true]]
   },
 ];
 
 SetupEMEPref(function() {
   tests.reduce(function(p,c,i,array) {
     return p.then(function() { return Test(c); });
   }, Promise.resolve()).then(SimpleTest.finish);
 });
 
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
 </body>
 </html>
-
--- a/dom/plugins/ipc/D3D11SurfaceHolder.cpp
+++ b/dom/plugins/ipc/D3D11SurfaceHolder.cpp
@@ -1,44 +1,44 @@
 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
 /* 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/. */
 #include "nsDebug.h"
 #include "D3D11SurfaceHolder.h"
-#include "gfxWindowsPlatform.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include <d3d11.h>
 
 namespace mozilla {
 namespace plugins {
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 D3D11SurfaceHolder::D3D11SurfaceHolder(ID3D11Texture2D* back,
                                        SurfaceFormat format,
                                        const IntSize& size)
- : mDevice11(gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice()),
+ : mDevice11(DeviceManagerD3D11::Get()->GetContentDevice()),
    mBack(back),
    mFormat(format),
    mSize(size)
 {
 }
 
 D3D11SurfaceHolder::~D3D11SurfaceHolder()
 {
 }
 
 bool
 D3D11SurfaceHolder::IsValid()
 {
   // If a TDR occurred, platform devices will be recreated.
-  if (gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice() != mDevice11) {
+  if (DeviceManagerD3D11::Get()->GetContentDevice() != mDevice11) {
      return false;
   }
   return true;
 }
 
 bool
 D3D11SurfaceHolder::CopyToTextureClient(TextureClient* aClient)
 {
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -40,16 +40,17 @@
 #include "GLContextProvider.h"
 #include "gfxPrefs.h"
 #include "LayersLogging.h"
 #include "mozilla/layers/TextureWrapperImage.h"
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #if defined(XP_WIN)
 # include "mozilla/layers/D3D11ShareHandleImage.h"
+# include "mozilla/gfx/DeviceManagerD3D11.h"
 # include "mozilla/layers/TextureD3D11.h"
 #endif
 
 #ifdef XP_MACOSX
 #include "MacIOSurfaceImage.h"
 #endif
 
 #if defined(OS_WIN)
@@ -395,17 +396,17 @@ bool
 PluginInstanceParent::AnswerNPN_GetValue_PreferredDXGIAdapter(DxgiAdapterDesc* aOutDesc)
 {
     PodZero(aOutDesc);
 #ifdef XP_WIN
     if (!AllowDirectDXGISurfaceDrawing()) {
         return false;
     }
 
-    ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
+    RefPtr<ID3D11Device> device = DeviceManagerD3D11::Get()->GetContentDevice();
     if (!device) {
         return false;
     }
 
     RefPtr<IDXGIDevice> dxgi;
     if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgi))) || !dxgi) {
         return false;
     }
@@ -676,17 +677,17 @@ PluginInstanceParent::RecvInitDXGISurfac
         return true;
     }
 
     ImageBridgeChild* forwarder = ImageBridgeChild::GetSingleton();
     if (!forwarder) {
         return true;
     }
 
-    RefPtr<ID3D11Device> d3d11 = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
+    RefPtr<ID3D11Device> d3d11 = DeviceManagerD3D11::Get()->GetContentDevice();
     if (!d3d11) {
         return true;
     }
 
     // Create the texture we'll give to the plugin process.
     HANDLE sharedHandle = 0;
     RefPtr<ID3D11Texture2D> back;
     {
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -190,17 +190,19 @@ nsXBLDocumentInfo::ReadPrototypeBindings
 {
   *aDocInfo = nullptr;
 
   nsAutoCString spec(kXBLCachePrefix);
   nsresult rv = PathifyURI(aURI, spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   StartupCache* startupCache = StartupCache::GetSingleton();
-  NS_ENSURE_TRUE(startupCache, NS_ERROR_FAILURE);
+  if (!startupCache) {
+    return NS_ERROR_FAILURE;
+  }
 
   UniquePtr<char[]> buf;
   uint32_t len;
   rv = startupCache->GetBuffer(spec.get(), &buf, &len);
   // GetBuffer will fail if the binding is not in the cache.
   if (NS_FAILED(rv))
     return rv;
 
@@ -257,17 +259,19 @@ nsXBLDocumentInfo::WritePrototypeBinding
   if (!nsContentUtils::IsSystemPrincipal(mDocument->NodePrincipal()))
     return NS_OK;
 
   nsAutoCString spec(kXBLCachePrefix);
   nsresult rv = PathifyURI(DocumentURI(), spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   StartupCache* startupCache = StartupCache::GetSingleton();
-  NS_ENSURE_TRUE(startupCache, rv);
+  if (!startupCache) {
+    return rv;
+  }
 
   nsCOMPtr<nsIObjectOutputStream> stream;
   nsCOMPtr<nsIStorageStream> storageStream;
   rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(stream),
                                            getter_AddRefs(storageStream),
                                            true);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt
+++ b/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt
@@ -1,11 +1,11 @@
 en_US-mozilla Hunspell Dictionary
-Generated from SCOWL Version 2016.01.19
-Thu Jan 21 14:36:28 EST 2016
+Generated from SCOWL Version 2016.06.26
+Tue Jul 26 12:40:24 EDT 2016
 
 http://wordlist.sourceforge.net
 
 README file for English Hunspell dictionaries derived from SCOWL.
 
 These dictionaries are created using the speller/make-hunspell-dict
 script in SCOWL.
 
@@ -314,9 +314,9 @@ from the Ispell distribution they are un
   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
 
-Build Date: Thu Jan 21 14:36:28 EST 2016
+Build Date: Tue Jul 26 12:40:24 EDT 2016
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added
@@ -4952,17 +4952,16 @@ Viv's
 Vivi
 Vivi's
 Viviana
 Viviana's
 Vivie
 Vivie's
 Vivien
 Vivien's
-VoIP
 Vodafone
 Vodafone's
 Von
 Von's
 WASPs
 Wadsworth
 Wadsworth's
 Wainwright
@@ -5308,17 +5307,16 @@ cryptologist's
 cryptologists
 cryptosystem
 cryptosystems
 cul-de-sac
 cultivar's
 cyber
 cytokine
 cytokine's
-cytokines
 datasheet
 datasheet's
 datasheets
 decertification
 decertifications
 decertified
 decertifies
 decertify
@@ -5421,18 +5419,16 @@ grey's
 greybeard's
 greybeards
 greyed
 greyer
 greyest
 greying
 greyness's
 greys
-guestbook's
-guestbooks
 hentai
 hexane's
 hexanes
 hijabs
 hippopotami
 holdem
 iPods
 idolator
@@ -5503,17 +5499,16 @@ metadata's
 methoxy
 migrator
 migrator's
 migrators
 misandrist
 misandrist's
 misandrists
 misandry
-miscommunications
 misjudgement
 misjudgement's
 misjudgements
 mitigations
 modeller
 modeller's
 modellers
 modelling
@@ -5525,16 +5520,24 @@ motorsports
 multicast
 murine
 musculus
 namespace
 namespace's
 namespaces
 nano
 natively
+na´ve
+na´vely
+na´ver
+na´vest
+na´vety
+na´vety's
+na´vetÚ
+na´vetÚ's
 neurophysiology's
 neuroscience's
 neurosciences
 neuroscientist
 neuroscientist's
 neuroscientists
 newswires
 octopi
@@ -5543,34 +5546,32 @@ opposable
 opposer
 parallelization
 parallelization's
 parallelizations
 parallelize
 parallelized
 parallelizes
 parallelizing
-parkour
 permalink
 permalink's
 permalinks
 permittee
 phlebotomist
 phlebotomist's
 phlebotomists
 phlebotomize
 phlebotomized
 phlebotomizes
 phlebotomizing
 pho
 phosphorylate
 phosphorylated
 phosphorylates
 phosphorylating
-phosphorylation
 plaintext
 polynucleotide
 polynucleotide's
 polynucleotides
 polypeptide's
 poutine
 poutines
 prejudgement
@@ -5661,17 +5662,16 @@ signups
 snarkily
 sommelier
 sommelier's
 sommeliers
 spelt
 spick
 spicks
 spywares
-stent's
 substituent's
 substituents
 subsumptions
 syllabi
 synches
 synesthesia
 synesthete
 synesthetes
@@ -5721,17 +5721,16 @@ uncancelled
 uncheck
 unchecking
 unchecks
 undeliverables
 undesignated
 unironic
 unironically
 unlabelled
-username's
 validator
 validators
 vertebrata
 volcanological
 volcanologist
 volcanologist's
 volcanologists
 volcanology
@@ -5740,12 +5739,11 @@ weaponized
 weaponizes
 weaponizing
 webdesign
 webdesign's
 webdesigns
 whitepaper
 whitepaper's
 whitepapers
-widescreen's
 wildcard's
 wildcards
 wop's
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
@@ -1,11 +1,11 @@
 en_US-custom Hunspell Dictionary
-Generated from SCOWL Version 2016.01.19
-Thu Jan 21 14:36:27 EST 2016
+Generated from SCOWL Version 2016.06.26
+Tue Jul 26 12:40:23 EDT 2016
 
 http://wordlist.sourceforge.net
 
 README file for English Hunspell dictionaries derived from SCOWL.
 
 These dictionaries are created using the speller/make-hunspell-dict
 script in SCOWL.
 
@@ -314,10 +314,10 @@ from the Ispell distribution they are un
   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
 
-Build Date: Thu Jan 21 14:36:27 EST 2016
+Build Date: Tue Jul 26 12:40:23 EDT 2016
 With Input Command: ../mk-list -v1 --accents=both en_US 60
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
@@ -1,9 +1,9 @@
-49404
+49464
 0/nm
 0th/pt
 1/n1
 1st/p
 1th/tc
 2/nm
 2nd/p
 2th/tc
@@ -32,16 +32,17 @@ ABM/SM
 ABS
 AC/M
 ACLU/M
 ACT
 ACTH/M
 AD/M
 ADC
 ADD
+ADM
 ADP/M
 AF
 AFAIK
 AFB
 AFC/M
 AFDC
 AFN
 AFT
@@ -529,16 +530,17 @@ Apatosaurus
 Apennines/M
 Aphrodite/M
 Apia/M
 Apocalypse/M
 Apocrypha/M
 Apollinaire/M
 Apollo/SM
 Apollonian/M
+Apostle/M
 Appalachia/M
 Appalachian/SM
 Appalachians/M
 Appaloosa/SM
 Apple/M
 Appleseed/M
 Appleton/M
 Appomattox/M
@@ -712,16 +714,17 @@ Athens/M
 Atkins/M
 Atkinson/M
 Atlanta/M
 Atlantes
 Atlantic/M
 Atlantis/M
 Atlas/MS
 Atman/M
+Atonement
 Atreus/M
 Atria/M
 Atropos/M
 Attic/M
 Attica/M
 Attila/M
 Attlee/M
 Attn
@@ -1274,16 +1277,17 @@ Boise/M
 Bojangles/M
 Boleyn/M
 Bolivar/M
 Bolivia/M
 Bolivian/MS
 Bollywood/M
 Bologna/M
 Bolshevik/SM
+Bolsheviki
 Bolshevism/M
 Bolshevist/M
 Bolshoi/M
 Bolton/M
 Boltzmann/M
 Bombay/M
 Bonaparte/M
 Bonaventure/M
@@ -2184,16 +2188,17 @@ Coltrane/M
 Columbia/M
 Columbine/M
 Columbus/M
 Com
 Comanche/MS
 Combs/M
 Comdr
 Comintern/M
+Commandment
 Commons/M
 Commonwealth
 Communion/SM
 Communism
 Communist/SM
 Como/M
 Comoran
 Comoros/M
@@ -2562,16 +2567,17 @@ Dayton/M
 DeGeneres/M
 Deadhead/M
 Dean/M
 Deana/M
 Deandre/M
 Deann/M
 Deanna/M
 Deanne/M
+Death/M
 Debbie/M
 Debby/M
 Debian/M
 Debora/M
 Deborah/M
 Debouillet/M
 Debra/M
 Debs/M
@@ -3561,16 +3567,17 @@ GE/M
 GED
 GHQ/M
 GHz
 GI
 GIF
 GIGO
 GM/M
 GMAT
+GMO
 GMT/M
 GNP/M
 GNU/M
 GOP/M
 GP/M
 GPA
 GPO
 GPS
@@ -4542,16 +4549,17 @@ IOU/M
 IP
 IPA
 IPO
 IQ/M
 IRA/SM
 IRC
 IRS/M
 ISBN
+ISIS
 ISO/M
 ISP
 ISS
 IT
 IUD
 IV/SM
 IVF
 Ia
@@ -5617,16 +5625,17 @@ Lewinsky/M
 Lewis/M
 Lexington/M
 Lexus/M
 Lhasa/MS
 Lhotse/M
 Li/MY
 Libby/M
 Liberace/M
+Liberal
 Liberia/M
 Liberian/SM
 Libra/MS
 LibreOffice/M
 Libreville/M
 Librium/M
 Libya/M
 Libyan/SM
@@ -5933,16 +5942,17 @@ Mackenzie/M
 Mackinac/M
 Mackinaw/M
 Macmillan/M
 Macon/M
 Macumba/M
 Macy/M
 Madagascan/SM
 Madagascar/M
+Madam
 Madden/M
 Maddox/M
 Madeira/SM
 Madeleine/M
 Madeline/M
 Madelyn/M
 Madge/M
 Madison/M
@@ -6433,16 +6443,17 @@ Mesolithic/M
 Mesopotamia/M
 Mesopotamian
 Mesozoic/M
 Messerschmidt/M
 Messiaen/M
 Messiah/M
 Messiahs
 Messianic
+Messieurs
 Metallica/M
 Metamucil/M
 Methodism/SM
 Methodist/SM
 Methuselah/M
 Metternich/M
 Meuse/M
 Mex
@@ -6642,16 +6653,17 @@ Mongoloid
 Monica/M
 Monique/M
 Monk/M
 Monmouth/M
 Monongahela/M
 Monroe/M
 Monrovia/M
 Monsanto/M
+Monsieur/M
 Monsignor/SM
 Mont/M
 Montague/M
 Montaigne/M
 Montana/M
 Montanan/SM
 Montcalm/M
 Monte/M
@@ -6838,16 +6850,17 @@ NP
 NPR/M
 NR
 NRA
 NRC
 NS
 NSA/M
 NSC
 NSF
+NSFW
 NT
 NV
 NW/M
 NWT
 NY
 NYC
 NYSE
 NZ
@@ -7055,17 +7068,17 @@ Nirenberg/M
 Nirvana/M
 Nisan/M
 Nisei/M
 Nissan/M
 Nita/M
 Nivea/M
 Nixon/M
 Nkrumah/M
-No/M
+No/SM
 NoDoz/M
 Noah/M
 Nobel/M
 Nobelist/MS
 Noble/M
 Noe/M
 Noel/SM
 Noelle/M
@@ -7278,32 +7291,34 @@ Ontarian
 Ontario/M
 Oort/M
 Opal/M
 Opel/M
 OpenOffice/M
 Ophelia/M
 Ophiuchus/M
 Oppenheimer/M
+Opposition
 Oprah/M
 Ora/M
 Oracle/M
 Oran/M
 Orange/M
 Oranjestad/M
 Orbison/M
 Ordovician/M
 Ore/N
 Oreg
 Oregon/M
 Oregonian/SM
 Oreo/M
 Orestes/M
 Orient/M
 Oriental/MS
+Orientalism
 Orin/M
 Orinoco/M
 Orion/M
 Oriya/M
 Orizaba/M
 Orkney/M
 Orlando/M
 Orleans/M
@@ -7467,16 +7482,17 @@ Parana/M
 Paraná/M
 Parcheesi/M
 Pareto/M
 Paris/M
 Parisian/MS
 Park/SMR
 Parker/M
 Parkinson/M
+Parkinsonism
 Parkman/M
 Parks/M
 Parliament/M
 Parmenides
 Parmesan/MS
 Parnassus/MS
 Parnell/M
 Parr/M
@@ -8435,16 +8451,17 @@ SD
 SDI
 SE/M
 SEATO
 SEC/M
 SF
 SGML/M
 SIDS/M
 SJ
+SJW
 SK
 SLR
 SO/S
 SOB/M
 SOP/M
 SOS/M
 SOSes
 SPCA
@@ -8786,16 +8803,17 @@ Seward/M
 Sextans/M
 Sexton/M
 Seychelles/M
 Seyfert/M
 Seymour/M
 Sgt
 Shackleton/M
 Shaffer/M
+Shah/M
 Shaka/M
 Shaker
 Shakespeare/M
 Shakespearean/M
 Shana/M
 Shane/M
 Shanghai/M
 Shankara/M
@@ -9881,16 +9899,17 @@ Urquhart/M
 Ursa/M
 Ursula/M
 Ursuline/M
 Uruguay/M
 Uruguayan/MS
 Urumqi/M
 Usenet/MS
 Ustinov/M
+Ut
 Utah/M
 Utahan/MS
 Ute/SM
 Utopia/SM
 Utopian/SM
 Utrecht/M
 Utrillo/M
 Uzbek/M
@@ -10070,16 +10089,17 @@ Vivaldi/M
 Vivekananda/M
 Vivian/M
 Vivienne/M
 Vlad/M
 Vladimir/M
 Vladivostok/M
 Vlaminck/M
 Vlasic/M
+VoIP
 Vogue/M
 Volcker/M
 Voldemort/M
 Volga/M
 Volgograd/M
 Volkswagen/M
 Volstead/M
 Volta/M
@@ -10532,16 +10552,17 @@ Zeus/M
 Zhdanov
 Zhengzhou/M
 Zhivago/M
 Zhukov/M
 Zibo/M
 Ziegfeld/M
 Ziegler/M
 Ziggy/M
+Zika
 Zimbabwe/M
 Zimbabwean/SM
 Zimmerman/M
 Zinfandel/M
 Zion/SM
 Zionism/SM
 Zionist/SM
 Ziploc/M
@@ -10971,16 +10992,17 @@ additive/SM
 addle/GDS
 address's
 address/AGDS
 addressable
 addressed/U
 addressee/SM
 adduce/GDS
 adenine/M
+adenocarcinoma
 adenoid/SM
 adenoidal
 adept/MYPS
 adeptness/M
 adequacy/IM
 adequate/IY
 adequateness/M
 adhere/GDS
@@ -11646,17 +11668,17 @@ amethyst/SM
 amiability/M
 amiable
 amiably
 amicability/M
 amicable
 amicably
 amid
 amide/MS
-amidships
+amidship/S
 amidst
 amigo/MS
 amino
 amir/SM
 amiss
 amity/M
 ammeter/SM
 ammo/M
@@ -12310,16 +12332,17 @@ ardor/MS
 arduous/YP
 arduousness/M
 are/SMB
 area/SM
 areal
 aren't
 arena/MS
 argent/M
+arginine
 argon/M
 argosy/SM
 argot/MS
 arguable/IU
 arguably/U
 argue/ZGDRS
 arguer/M
 argument/MS
@@ -13212,16 +13235,17 @@ baptist/S
 baptistery/SM
 baptistry/SM
 baptize/ZGDRS
 baptized/U
 baptizer/M
 bar's
 bar/ECUTS
 barb/SZGMDR
+barbacoa
 barbarian/SM
 barbarianism/MS
 barbaric
 barbarically
 barbarism/SM
 barbarity/SM
 barbarize/DSG
 barbarous/Y
@@ -15117,33 +15141,33 @@ burghs
 burglar/MS
 burglarize/GDS
 burglarproof
 burglary/SM
 burgle/DSG
 burgomaster/SM
 burgundy/SM
 burial/ASM
-burka/S
+burka/SM
 burl/MDS
 burlap/M
 burlesque/MGDS
 burliness/M
 burly/RPT
 burn/MDRZGSB
 burnable/SM
 burner/M
 burnish/ZGMDRS
 burnisher/M
 burnoose/MS
 burnous/MS
 burnout/MS
 burnt
 burp/MDGS
-burqa/S
+burqa/SM
 burr/MDGS
 burrito/MS
 burro/SM
 burrow/SMDRZG
 burrower/M
 bursa/M
 bursae
 bursar/SM
@@ -16219,16 +16243,17 @@ chastisement/SM
 chastiser/M
 chastity/M
 chasuble/SM
 chat/SM
 chateau/SM
 chateaux
 chatelaine/SM
 chatline/S
+chatroom/M
 chatted
 chattel/MS
 chatter/MDRZGS
 chatterbox/MS
 chatterer/M
 chattily
 chattiness/M
 chatting
@@ -16664,16 +16689,17 @@ citric
 citron/MS
 citronella/M
 citrous
 citrus/MS
 city/SM
 citywide
 civet/MS
 civic/S
+civically
 civics/M
 civil/UY
 civilian/MS
 civility/ISM
 civilization/MS
 civilize/GDS
 civilized/U
 civvies/M
@@ -17960,16 +17986,17 @@ contortion/MS
 contortionist/SM
 contraband/M
 contrabassoon/S
 contraception/M
 contraceptive/SM
 contract/MDG
 contractible
 contractile
+contractility
 contraction/S
 contractual/Y
 contradict/SDG
 contradiction/SM
 contradictory
 contradistinction/MS
 contraflow/S
 contrail/MS
@@ -18362,17 +18389,19 @@ counterfeit/ZGMDRS
 counterfeiter/M
 counterfoil/MS
 countering
 counterinsurgency/SM
 counterintelligence/M
 counterman/M
 countermand/GMDS
 countermeasure/SM
+countermelody/S
 countermen
+countermove/S
 counteroffensive/SM
 counteroffer/SM
 counterpane/SM
 counterpart/SM
 counterpetition
 counterpoint/MDGS
 counterpoise/MGDS
 counterproductive
@@ -19025,17 +19054,17 @@ cutthroat/SM
 cutting/MYS
 cuttlefish/MS
 cutup/SM
 cutworm/MS
 cw
 cwt
 cyan/M
 cyanide/M
-cyberbully/S
+cyberbully/SM
 cybercafe/S
 cybercaf├ę/S
 cybernetic/S
 cybernetics/M
 cyberpunk/SM
 cybersex
 cyberspace/MS
 cyborg/SM
@@ -19061,16 +19090,17 @@ cynic/SM
 cynical/Y
 cynicism/M
 cynosure/MS
 cypher/M
 cypress/MS
 cyst/MS
 cystic
 cystitis
+cytokines
 cytologist/SM
 cytology/M
 cytoplasm/M
 cytoplasmic
 cytosine/M
 czar/MS
 czarina/SM
 czarism
@@ -19968,17 +19998,17 @@ diamondback/MS
 diapason/SM
 diaper/SMDG
 diaphanous
 diaphragm/SM
 diaphragmatic
 diarist/SM
 diarrhea/M
 diary/SM
-diaspora
+diaspora/SM
 diastase/M
 diastole/M
 diastolic
 diathermy/M
 diatom/SM
 diatomic
 diatonic
 diatribe/SM
@@ -21342,17 +21372,17 @@ effendi/SM
 efferent
 effervesce/GDS
 effervescence/M
 effervescent/Y
 effete/YP
 effeteness/M
 efficacious/Y
 efficacy/IM
-efficiency/IM
+efficiency/ISM
 efficient/IY
 effigy/SM
 efflorescence/M
 efflorescent
 effluence/M
 effluent/MS
 effluvia
 effluvium/M
@@ -21645,17 +21675,17 @@ emir/MS
 emirate/MS
 emissary/SM
 emission/SM
 emit/S
 emitted
 emitter/MS
 emitting
 emo/SM
-emoji
+emoji/SM
 emollient/MS
 emolument/MS
 emote/XDSGNV
 emoticon/SM
 emotion/M
 emotional/UY
 emotionalism/M
 emotionalize/GDS
@@ -21777,17 +21807,17 @@ endmost
 endocarditis
 endocrine/MS
 endocrinologist/MS
 endocrinology/M
 endogenous/Y
 endometrial
 endometriosis
 endometrium
-endorphin/M
+endorphin/MS
 endorse/LZGDRS
 endorsement/MS
 endorser/M
 endoscope/MS
 endoscopic
 endoscopy/M
 endothelial
 endothermic
@@ -23024,17 +23054,18 @@ fear/MDGS
 fearful/YP
 fearfulness/M
 fearless/PY
 fearlessness/M
 fearsome
 feasibility/M
 feasible/IU
 feasibly
-feast/SMDG
+feast/SMDRZG
+feaster/M
 feat/MS
 feather/SGMD
 featherbedding/M
 featherbrained
 featherless
 featherweight/MS
 feathery/TR
 feature/DSMG
@@ -23610,19 +23641,16 @@ flimsily
 flimsiness/M
 flimsy/TRP
 flinch/GMDS
 fling/GM
 flint/SM
 flintlock/SM
 flinty/TR
 flip/MS
-flipflop/S
-flipflopped
-flipflopping
 flippancy/M
 flippant/Y
 flipped
 flipper/MS
 flippest
 flipping
 flippy/S
 flirt/SGMD
@@ -24256,17 +24284,17 @@ friary/SM
 fricassee/DSM
 fricasseeing
 fricative/SM
 friction/SM
 frictional
 fridge/SM
 friedcake/MS
 friend's
-friend/US
+friend/UGSDY
 friendless
 friendlies
 friendliness/UM
 friendly's
 friendly/UPTR
 friendship/MS
 frieze/SM
 frig/S
@@ -24330,17 +24358,17 @@ frontward/S
 frosh/M
 frost's
 frost/CSDG
 frostbit
 frostbite/MGS
 frostbitten
 frostily
 frostiness/M
-frosting/M
+frosting/SM
 frosty/TPR
 froth/MDG
 frothiness/M
 froths
 frothy/TPR
 froufrou/M
 froward/P
 frowardness/M
@@ -25705,17 +25733,17 @@ guava/SM
 gubernatorial
 guerilla/SM
 guerrilla/SM
 guess/ZGBMDRS
 guesser/M
 guesstimate/DSMG
 guesswork/M
 guest/SGMD
-guestbook
+guestbook/SM
 guesthouse/S
 guestroom/S
 guff/M
 guffaw/MDGS
 guidance/M
 guide/DRSMZG
 guidebook/SM
 guided/U
@@ -25870,17 +25898,17 @@ habitu├ę/SM
 hacienda/SM
 hack/MDRZGS
 hacker/M
 hacking/M
 hackish
 hackle/MS
 hackney/SMDG
 hacksaw/SM
-hacktivist/S
+hacktivist/MS
 hackwork/M
 had
 haddock/SM
 hadn't
 hadst
 hafnium/M
 haft/MS
 hag/SM
@@ -26423,16 +26451,17 @@ heliotrope/SM
 helipad/S
 heliport/MS
 helium/M
 helix/M
 hell/M
 hellbent
 hellcat/MS
 hellebore/M
+hellfire
 hellhole/MS
 hellion/MS
 hellish/YP
 hellishness/M
 hello/SM
 helluva
 helm/MS
 helmet/SMD
@@ -28043,17 +28072,16 @@ industriousness/M
 industry/SM
 indwell/SG
 inebriate/MGNDS
 inebriation/M
 inedible
 ineffability/M
 ineffable
 ineffably
-inefficiency/S
 inelastic
 ineligible/MS
 ineligibly
 ineluctable
 ineluctably
 inept/YP
 ineptitude/M
 ineptness/M
@@ -28981,16 +29009,17 @@ jesting/Y
 jet/SM
 jetliner/SM
 jetport/MS
 jetsam/M
 jetted
 jetting
 jettison/MDSG
 jetty/SM
+jew
 jewel/SZGMDR
 jeweler/M
 jewelry/SM
 jg
 jib/SGMD
 jibbed
 jibbing
 jibe/MS
@@ -29119,16 +29148,17 @@ joylessness/M
 joyous/YP
 joyousness/M
 joyridden
 joyride/RSMZG
 joyrider/M
 joyriding/M
 joyrode
 joystick/SM
+jr
 jubilant/Y
 jubilation/M
 jubilee/SM
 judder/GDS
 judge's
 judge/ADSG
 judgemental
 judgeship/M
@@ -29517,17 +29547,18 @@ kronur
 krypton/M
 kr├│na/M
 kr├│nur
 kt
 kuchen/SM
 kudos/M
 kudzu/SM
 kumquat/MS
-kvetch/GMDS
+kvetch/ZGMDRS
+kvetcher/M
 kw
 l/SDXTGJ
 la/M
 lab/SM
 label's
 label/ASDG
 labeled/U
 labia
@@ -29613,17 +29644,17 @@ lambast/GDS
 lambaste/S
 lambda/SM
 lambency/M
 lambent/Y
 lambkin/SM
 lambskin/SM
 lambswool
 lame/MYZTGDRSP
-lamebrain/MS
+lamebrain/MDS
 lameness/M
 lament/BSMDG
 lamentably
 lamentation/MS
 lamina/M
 laminae
 laminar
 laminate/MGNDS
@@ -30031,16 +30062,17 @@ letterbox/S
 lettered/U
 letterer/M
 letterhead/MS
 lettering/M
 letterpress/M
 letting/S
 lettuce/MS
 letup/SM
+leucine
 leucotomy/S
 leukemia/M
 leukemic/SM
 leukocyte/MS
 levee/SM
 level/PSZGMDRY
 leveler/M
 levelheaded/P
@@ -30162,16 +30194,17 @@ lighthouse/MS
 lighting's
 lightly
 lightness/M
 lightning/MDS
 lightproof
 lightship/MS
 lightweight/SM
 ligneous
+lignin
 lignite/M
 lii
 likability/M
 likable/P
 likableness/M
 like/EMGDST
 likeability/M
 likeable/P
@@ -30462,26 +30495,26 @@ logged
 logger/SM
 loggerhead/SM
 loggia/SM
 logging/M
 logic/M
 logical/Y
 logicality/M
 logician/MS
-login/S
+login/SM
 logistic/S
 logistical/Y
 logistics/M
 logjam/SM
 logo/MS
-logoff/S
-logon/S
+logoff/SM
+logon/SM
 logotype/SM
-logout/S
+logout/SM
 logrolling/M
 logy/RT
 loin/MS
 loincloth/M
 loincloths
 loiter/ZGSDR
 loiterer/M
 loitering/M
@@ -30820,19 +30853,20 @@ maddest
 madding
 made/AU
 mademoiselle/MS
 madhouse/SM
 madman/M
 madmen
 madness/M
 madras/MS
-madrasa/S
-madrassah
-madrassahs
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
 madrigal/SM
 madwoman/M
 madwomen
 maelstrom/SM
 maestro/SM
 mafia/SM
 mafiosi
 mafioso/M
@@ -31534,17 +31568,17 @@ melon/SM
 melt's
 melt/ADSG
 meltdown/SM
 member's
 member/EAS
 membership/SM
 membrane/SM
 membranous
-meme/S
+meme/MS
 memento/MS
 memo/MS
 memoir/MS
 memorabilia/M
 memorability/M
 memorable/U
 memorably
 memorandum/MS
@@ -31764,16 +31798,17 @@ mgr
 mi/MNX
 miasma/MS
 mic/S
 mica/M
 mice
 mick/S
 mickey/MS
 micro/SM
+microaggression/SM
 microbe/MS
 microbial
 microbiological
 microbiologist/MS
 microbiology/M
 microbrewery/SM
 microchip/MS
 microcircuit/SM
@@ -31899,17 +31934,17 @@ milkman/M
 milkmen
 milkshake/SM
 milksop/MS
 milkweed/SM
 milky/RTP
 mill/MDRSZGJ
 millage/M
 millennia
-millennial/MS
+millennial/M
 millennium/MS
 miller/M
 millet/M
 milliard/MS
 millibar/MS
 milligram/MS
 milliliter/MS
 millimeter/MS
@@ -31978,17 +32013,17 @@ minibus/MS
 minicab/S
 minicam/MS
 minicomputer/SM
 minifloppies
 minim/SM
 minimal/Y
 minimalism/M
 minimalist/MS
-minimization
+minimization/M
 minimize/DSG
 minimum/MS
 mining/M
 minion/M
 miniseries/M
 miniskirt/MS
 minister/SGMD
 ministerial
@@ -32060,17 +32095,17 @@ miscegenation/M
 miscellaneous/Y
 miscellany/SM
 mischance/SM
 mischief/M
 mischievous/YP
 mischievousness/M
 miscibility/M
 miscible
-miscommunication
+miscommunication/S
 misconceive/GDS
 misconception/SM
 misconduct/MDGS
 misconstruction/MS
 misconstrue/GDS
 miscount/MDSG
 miscreant/SM
 miscue/DSMG
@@ -32207,24 +32242,26 @@ mitigate/DSGN
 mitigated/U
 mitigation/M
 mitochondria
 mitochondrial
 mitochondrion
 mitoses
 mitosis/M
 mitotic
+mitral
 mitt/MNSX
 mitten/M
 mix/ZGMDRSB
 mixed/U
 mixer/M
 mixture/SM
 mizzen/MS
 mizzenmast/SM
+mkay
 mks
 ml
 mm
 mnemonic/MS
 mnemonically
 mo/CKHS
 moan/MDRSZG
 moaner/M
@@ -32236,17 +32273,17 @@ mobbing/C
 mobile/MS
 mobility/M
 mobilization/CM
 mobilizations
 mobilize/CDSG
 mobilizer/SM
 mobster/SM
 moccasin/SM
-mocha/M
+mocha/SM
 mock/DRSZG
 mocker/M
 mockery/SM
 mocking/Y
 mockingbird/SM
 mod/STM
 modal/SM
 modality/S
@@ -32639,16 +32676,17 @@ mousetrap/SM
 mousetrapped
 mousetrapping
 mousey
 mousiness/M
 moussaka/S
 mousse/MGDS
 mousy/PTR
 mouth/GMD
+mouthfeel
 mouthful/MS
 mouthiness/M
 mouthpiece/MS
 mouths
 mouthwash/MS
 mouthwatering
 mouthy/PTR
 mouton/M
@@ -32741,16 +32779,17 @@ multicultural
 multiculturalism/M
 multidimensional
 multidisciplinary
 multifaceted
 multifamily
 multifarious/PY
 multifariousness/M
 multiform
+multigrain
 multilateral/Y
 multilayered
 multilevel
 multilingual
 multilingualism/M
 multimedia/M
 multimillionaire/SM
 multinational/SM
@@ -32885,16 +32924,17 @@ mutineer/SM
 mutinous/Y
 mutiny/GDSM
 mutt/MS
 mutter/ZGJMDRS
 mutterer/M
 muttering/M
 mutton/M
 muttonchops/M
+muttony
 mutual/Y
 mutuality/M
 muumuu/MS
 muzak
 muzzily
 muzzle/DSMG
 muzzy/P
 my
@@ -33170,17 +33210,17 @@ nelson/SM
 nematode/SM
 nemeses
 nemesis/M
 neoclassic
 neoclassical
 neoclassicism/M
 neocolonialism/M
 neocolonialist/MS
-neocon/S
+neocon/SM
 neoconservative/SM
 neodymium/M
 neolithic
 neologism/SM
 neon/M
 neonatal
 neonate/MS
 neophilia
@@ -33188,16 +33228,17 @@ neophyte/MS
 neoplasm/MS
 neoplastic
 neoprene/M
 nepenthe/M
 nephew/SM
 nephrite/M
 nephritic
 nephritis/M
+nephropathy
 nepotism/M
 nepotist/SM
 nepotistic
 neptunium/M
 nerd/MS
 nerdy/RT
 nerve's
 nerve/UDSG
@@ -33318,17 +33359,17 @@ nickelodeon/SM
 nicker/MDG
 nickle/S
 nickname/DSMG
 nicotine/M
 niece/SM
 niff
 niffy
 nifty/TR
-nigga/S
+nigga/SM
 niggard/SMY
 niggardliness/M
 niggaz
 nigger/SM!
 niggle/MZGDRS
 niggler/M
 nigh/RT
 night/SMY
@@ -33624,17 +33665,17 @@ nonnative/MS
 nonnegotiable
 nonnuclear
 nonnumerical
 nonobjective
 nonobligatory
 nonobservance/M
 nonobservant
 nonoccupational
-nonoccurrence/M
+nonoccurence
 nonofficial
 nonoperational
 nonoperative
 nonparallel/MS
 nonpareil/MS
 nonparticipant/MS
 nonparticipating
 nonpartisan/SM
@@ -34423,17 +34464,17 @@ orator/SM
 oratorical/Y
 oratorio/MS
 oratory/SM
 orb/SM
 orbicular
 orbit/MDRZGS
 orbital/SM
 orbiter/M
-orc/S
+orc/SM
 orchard/SM
 orchestra/MS
 orchestral
 orchestrate/DSXGN
 orchestration/M
 orchid/SM
 ordain/SDLG
 ordainment/M
@@ -35343,16 +35384,17 @@ parimutuel/MS
 paring/M
 parish/MS
 parishioner/MS
 parity/ESM
 park/MDSG
 parka/SM
 parking/M
 parkland
+parkour
 parkway/MS
 parky
 parlance/M
 parlay/GMDS
 parley/GMDS
 parliament/SM
 parliamentarian/SM
 parliamentary
@@ -35361,16 +35403,17 @@ parlous
 parmigiana
 parmigiano
 parochial/Y
 parochialism/M
 parodist/SM
 parody/GDSM
 parole/MGDS
 parolee/MS
+parotid
 paroxysm/SM
 paroxysmal
 parquet/MDSG
 parquetry/M
 parred
 parricidal
 parricide/MS
 parring
@@ -36066,30 +36109,33 @@ pg
 phaeton/MS
 phage/S
 phagocyte/SM
 phalanger/SM
 phalanges
 phalanx/MS
 phalli
 phallic
+phallocentric
+phallocentrism
 phallus/M
 phantasm/MS
 phantasmagoria/MS
 phantasmagorical
 phantasmal
 phantom/SM
 pharaoh/M
 pharaohs
 pharisaic
 pharisee/SM
 pharmaceutic/MS
 pharmaceutical/SM
 pharmaceutics/M
 pharmacist/MS
+pharmacologic
 pharmacological
 pharmacologist/SM
 pharmacology/M
 pharmacopeia/SM
 pharmacopoeia/MS
 pharmacy/SM
 pharyngeal
 pharynges
@@ -36176,18 +36222,18 @@ phooey
 phosphate/MS
 phosphodiesterase
 phosphor/MS
 phosphorescence/M
 phosphorescent/Y
 phosphoric
 phosphorous
 phosphorus/M
+phosphorylation
 photo/SGMD
-photobomb/DGS
 photocell/MS
 photocopier/M
 photocopy/DRSMZG
 photoelectric
 photoelectrically
 photoengrave/DRSJZG
 photoengraver/M
 photoengraving/M
@@ -36687,18 +36733,16 @@ plughole/S
 plugin/SM
 plum/GMDS
 plumage/M
 plumb/MDRSZGJ
 plumbed/U
 plumber/M
 plumbing/M
 plume/MS
-plummer
-plummest
 plummet/SGMD
 plummy
 plump/MDRYSTGP
 plumpness/M
 plumy/RT
 plunder/SZGMDR
 plunderer/M
 plunge/DRSMZG
@@ -36736,17 +36780,17 @@ poaching/M
 pock/GMDS
 pocket/SMDG
 pocketbook/SM
 pocketful/SM
 pocketknife/M
 pocketknives
 pockmark/MDGS
 pod/SM
-podcast/SM
+podcast/SMG
 podded
 podding
 podiatrist/SM
 podiatry/M
 podium/SM
 poem/MS
 poesy/M
 poet/MS
@@ -37078,16 +37122,17 @@ postnatal
 postoperative
 postpaid
 postpartum
 postpone/DSGL
 postponement/SM
 postprandial
 postscript/SM
 postseason/SM
+postsynaptic
 postulate/XDSMGN
 postulation/M
 postural
 posture/MGJDS
 posturing/M
 postwar
 postwoman
 postwomen
@@ -37296,16 +37341,17 @@ preferably
 preference/MS
 preferential/Y
 preferment/M
 preferred
 preferring
 prefigure/GDS
 prefix/MDSG
 preform/GSD
+prefrontal
 pregame/SM
 pregnancy/SM
 pregnant
 preheat/GSD
 prehensile
 prehistorian/S
 prehistoric
 prehistorical/Y
@@ -38202,22 +38248,23 @@ pyre/MS
 pyrimidine/MS
 pyrite/SM
 pyrites/M
 pyromania/M
 pyromaniac/SM
 pyrotechnic/S
 pyrotechnical
 pyrotechnics/M
+pyruvate
 python/SM
 pyx/MS
 pzazz
 q
 qr
-qt
+qt/S
 qty
 qua
 quack/GMDS
 quackery/M
 quad/MS
 quadrangle/SM
 quadrangular
 quadrant/MS
@@ -38589,16 +38636,17 @@ rangy/RTP
 rani/MS
 rank/TGJPMDRYS
 ranking/M
 rankle/DSG
 rankness/M
 ransack/SGD
 ransom/SZGMDR
 ransomer/M
+ransomware
 rant/ZGMDJRS
 ranter/M
 rap/SZGMDR
 rapacious/PY
 rapaciousness/M
 rapacity/M
 rape/MS
 raper/M
@@ -39192,17 +39240,17 @@ renovate/DSXGN
 renovation/M
 renovator/MS
 renown/MD
 rent/ZGMDRS
 rental/SM
 renter/M
 renunciation/SM
 reopen/SDG
-reorg/DSG
+reorg/MDSG
 rep/SM
 repaint/GDS
 repair/BZR
 repairer/M
 repairman/M
 repairmen
 reparable
 reparation/MS
@@ -39755,17 +39803,17 @@ roasting/M
 rob/S
 robbed
 robber/MS
 robbery/SM
 robbing
 robe's
 robe/EGDS
 robin/MS
-robocall/SGD
+robocall/SGMD
 robot/MS
 robotic/S
 robotics/M
 robotize/GDS
 robust/RYPT
 robustness/M
 rock/ZGMDRS
 rockabilly/M
@@ -40050,32 +40098,35 @@ ruthenium/M
 rutherfordium/M
 ruthless/YP
 ruthlessness/M
 rutted
 rutting
 rutty/RT
 rye/M
 s/NYXB
+sabbath/M
+sabbaths
 sabbatical/SM
 saber/MS
 sable/MS
 sabot/MS
 sabotage/DSMG
 saboteur/SM
 sabra/MS
 sabre/MS
 sac/SM
 saccharin/M
 saccharine
 sacerdotal
 sachem/SM
 sachet/SM
-sack/GMDJS
+sack/ZGMDRJS
 sackcloth/M
+sacker/M
 sackful/MS
 sacking/M
 sacra
 sacrament/MS
 sacramental
 sacred/YP
 sacredness/M
 sacrifice/DSMG
@@ -40216,16 +40267,17 @@ same/SP
 sameness/M
 samey
 samizdat/S
 samosa/S
 samovar/SM
 sampan/SM
 sample/DRSMZGJ
 sampler/M
+sampling/M
 samurai/SM
 sanatorium/SM
 sanctification/M
 sanctify/GDSN
 sanctimonious/YP
 sanctimoniousness/M
 sanctimony/M
 sanction/GSMD
@@ -41411,17 +41463,17 @@ shibboleth/M
 shibboleths
 shield/MDGS
 shift/GMDS
 shiftily
 shiftiness/M
 shiftless/PY
 shiftlessness/M
 shifty/RPT
-shiitake/S
+shiitake/SM
 shill/GMDSJ
 shillelagh/M
 shillelaghs
 shilling/M
 shim/MS
 shimmed
 shimmer/SMDG
 shimmery
@@ -41503,17 +41555,17 @@ shogunate/M
 shone
 shoo/GDS
 shook
 shoot/ZGMRSJ
 shooter/M
 shooting/M
 shootout/MS
 shop/MS
-shopaholic/S
+shopaholic/MS
 shopfitter/S
 shopfitting
 shopfront/S
 shopkeeper/MS
 shoplift/DRZGS
 shoplifter/M
 shoplifting/M
 shoppe/MZGDRS
@@ -41766,17 +41818,17 @@ silt/GMDS
 silty/TR
 silvan
 silver/GMDS
 silverfish/MS
 silversmith/M
 silversmiths
 silverware/M
 silvery
-sim/S
+sim/SM
 simian/MS
 similar/Y
 similarity/ESM
 simile/MS
 similitude/EM
 simmer/GMDS
 simonize/DSG
 simony/M
@@ -42623,16 +42675,17 @@ soot/M
 sooth/MDRSZG
 soothe
 soother/M
 soothing/Y
 soothsayer/MS
 soothsaying/M
 sooty/RT
 sop/SM
+soph
 sophism/M
 sophist/MS
 sophistic
 sophistical
 sophisticate/DSMGN
 sophisticated/U
 sophistication/M
 sophistry/SM
@@ -42677,17 +42730,17 @@ souffl├ę/SM
 sough/MDG
 soughs
 sought/U
 souk/S
 soul/MS
 soulful/YP
 soulfulness/M
 soulless/YP
-soulmate/S
+soulmate/SM
 sound/JPSMDRYZTG
 soundalike/S
 soundbar/S
 soundbite/S
 soundboard/MS
 soundcheck/S
 sounder/M
 sounding/M
@@ -42880,17 +42933,17 @@ speedwell/M
 speedy/TPR
 speleological
 speleologist/MS
 speleology/M
 spell/JSMDRZG
 spellbind/ZGRS
 spellbinder/M
 spellbound
-spellcheck/DRZGS
+spellcheck/MDRZGS
 spellchecker/M
 spelldown/SM
 speller/M
 spelling/M
 spelunker/MS
 spelunking/M
 spend/BSRZG
 spender/M
@@ -43441,17 +43494,17 @@ stemming
 stemware/M
 stench/MS
 stencil/GMDS
 steno/SM
 stenographer/SM
 stenographic
 stenography/M
 stenosis
-stent/S
+stent/SM
 stentorian
 step/IMS
 stepbrother/SM
 stepchild/M
 stepchildren/M
 stepdad/MS
 stepdaughter/SM
 stepfather/SM
@@ -43836,17 +43889,17 @@ studentship/S
 studied/U
 studiedly
 studio/MS
 studious/PY
 studiousness/M
 studly/RT
 study's
 study/AGDS
-stuff/GSMD
+stuff/GSMDJ
 stuffily
 stuffiness/M
 stuffing/M
 stuffy/RPT
 stultification/M
 stultify/DSNG
 stumble/DRSMZG
 stumbler/M
@@ -44165,17 +44218,17 @@ sumptuousness/M
 sun/SM
 sunbath/ZGMDRS
 sunbathe
 sunbather/M
 sunbathing/M
 sunbaths
 sunbeam/SM
 sunbed/S
-sunbelt
+sunbelt/SM
 sunblock/MS
 sunbonnet/SM
 sunburn/SGMD
 sunburst/MS
 sundae/MS
 sundeck/S
 sunder/DSG
 sundial/SM
@@ -44931,17 +44984,17 @@ taxman
 taxmen
 taxon
 taxonomic
 taxonomical
 taxonomist/MS
 taxonomy/SM
 taxpayer/MS
 taxpaying
-tbs
+tb/S
 tbsp
 tea/SM
 teabag/S
 teacake/SM
 teach/ZGRSBJ
 teachable/U
 teacher/M
 teaching/M
@@ -45126,17 +45179,17 @@ tenantry/M
 tench
 tend/IEFDGS
 tended/U
 tendency/SM
 tendentious/YP
 tendentiousness/M
 tender/SMDRYTGP
 tenderfoot/MS
-tenderhearted/PY
+tenderhearted/P
 tenderheartedness/M
 tenderize/ZGDRS
 tenderizer/M
 tenderloin/SM
 tenderness/M
 tendinitis/M
 tendon/SM
 tendonitis/M
@@ -45599,16 +45652,17 @@ tighten/ZGDR
 tightener/M
 tightfisted
 tightness/M
 tightrope/MS
 tights/M
 tightwad/MS
 tigress/MS
 til
+tilapia
 tilde/SM
 tile/MZGDRS
 tiler/M
 tiling/M
 till's
 till/EDRZGS
 tillable
 tillage/M
@@ -46497,25 +46551,27 @@ trust/ESGMD
 trustee/MS
 trusteeship/SM
 trustful/EY
 trustfulness/M
 trusting/Y
 trustworthiness/M
 trustworthy/TPR
 trusty/TRSM
-truth/UM
+truth/ZMR
+truther/M
 truthful/UYP
 truthfulness/UM
 truthiness
 truths/U
 try's
 try/AGDS
 trying/Y
 tryout/SM
+tryptophan
 tryst/SMDG
 tsarists
 tsetse/MS
 tsp
 tsunami/SM
 ttys
 tub/SZGMDR
 tuba/MS
@@ -46654,18 +46710,19 @@ twangy/RT
 twas
 twat/S
 tweak/SMDG
 twee
 tweed/SM
 tweeds/M
 tweedy/RT
 tween
-tweet/SMDRZG
-tweeter/M
+tweet's
+tweet/ASDG
+tweeter/SM
 tweezers/M
 twelfth/M
 twelfths
 twelve/SM
 twelvemonth/M
 twelvemonths
 twentieth/M
 twentieths
@@ -46764,20 +46821,21 @@ ubiquitous/Y
 ubiquity/M
 udder/SM
 ufologist/SM
 ufology/M
 ugh
 ugliness/M
 ugly/RTP
 uh
+uhf
 ukase/SM
 ukulele/SM
 ulcer/SM
-ulcerate/DSGN
+ulcerate/XDSGN
 ulceration/M
 ulcerous
 ulna/M
 ulnae
 ulnar
 ulster/MS
 ult
 ulterior
@@ -47050,17 +47108,16 @@ unflagging/Y
 unflappability/M
 unflappable
 unflappably
 unflattering
 unflinching/Y
 unforgettably
 unforgivably
 unfortunate/MS
-unfriend/GD
 unfriendly/T
 unfrock/DG
 unfruitful
 unfunny
 ungainliness/M
 ungainly/RPT
 ungenerous
 ungentle
@@ -47231,16 +47288,17 @@ unthinking/Y
 untidy/PTR
 until
 untimely/T
 untiring/Y
 untouchable/MS
 untoward
 untrue/RT
 untrustworthy
+untruth/M
 unutterable
 unutterably
 unwarrantable
 unwary/T
 unwavering
 unwed
 unwelcome/G
 unwell
@@ -47272,16 +47330,17 @@ upholder/M
 upholster/ASGD
 upholsterer/MS
 upholstery/M
 upkeep/M
 upland/MS
 uplift/JSMDG
 upload/SDG
 upmarket
+upmost
 upon
 upped
 upper/SM
 uppercase/M
 upperclassman/M
 upperclassmen
 upperclasswoman
 upperclasswomen
@@ -47366,17 +47425,17 @@ usable/UA
 usage/SM
 use/AEDSMG
 used/U
 useful/PY
 usefulness/M
 useless/YP
 uselessness/M
 user/MS
-username/S
+username/MS
 usher/SMDG
 usherette/SM
 usu
 usual's
 usual/UY
 usurer/SM
 usurious
 usurp/SDRZG
@@ -47929,16 +47988,17 @@ viviparous
 vivisect/DGS
 vivisection/M
 vivisectional
 vivisectionist/SM
 vixen/SM
 vixenish/Y
 viz
 vizier/SM
+vlf
 vocab
 vocable/MS
 vocabulary/SM
 vocal/SMY
 vocalic
 vocalist/SM
 vocalization/MS
 vocalize/DSG
@@ -47951,17 +48011,17 @@ vociferous/YP
 vociferousness/M
 vodka/SM
 vogue/SM
 voguish
 voice/IDSMG
 voiced/U
 voiceless/PY
 voicelessness/M
-voicemail/M
+voicemail/SM
 void/MDSGB
 voila
 voile/M
 voilà
 vol/S
 volatile
 volatility/M
 volatilize/DSG
@@ -48031,17 +48091,17 @@ vulpine
 vulture/SM
 vulturous
 vulva/M
 vulvae
 vuvuzela/MS
 vying
 w/DNXTGVJ
 wabbit/S
-wack/RTS
+wack/MRTS
 wackiness/M
 wacko/SM
 wacky/RPT
 wad/SZGMDR
 wadded
 wadding/M
 waddle/DSMG
 wade/MS
@@ -48193,17 +48253,17 @@ warrior/SM
 warship/SM
 wart/MS
 warthog/SM
 wartime/M
 warty/TR
 wary/UPRT
 was
 wasabi
-wash/BMDRSZG
+wash/BJMDRSZG
 washable/SM
 washbasin/SM
 washboard/SM
 washbowl/SM
 washcloth/M
 washcloths
 washed/U
 washer/M
@@ -48244,17 +48304,18 @@ watchmaking/M
 watchman/M
 watchmen
 watchstrap/S
 watchtower/SM
 watchword/MS
 water/GSMD
 waterbed/MS
 waterbird/SM
-waterboard/DJSG
+waterboard/MDJSG
+waterboarding/M
 waterborne
 watercolor/MS
 watercourse/SM
 watercraft/M
 watercress/M
 waterfall/SM
 waterfowl/SM
 waterfront/MS
@@ -48362,17 +48423,16 @@ webcam/MS
 webcast/SMG
 webfeet
 webfoot/M
 webinar/SM
 webisode/MS
 weblog/MS
 webmaster/SM
 webmistress/MS
-webpage/SM
 website/SM
 wed/AS
 wedded/A
 wedder
 wedding/SM
 wedge/DSMG
 wedgie/MS
 wedlock/M
@@ -48655,17 +48715,17 @@ wickedness/M
 wicker/M
 wickerwork/M
 wicket/SM
 wide/YTRP
 widemouthed
 widen/SDRZG
 widener/M
 wideness/M
-widescreen/S
+widescreen/MS
 widespread
 widgeon/MS
 widget/S
 widow/SMDRZG
 widower/M
 widowhood/M
 width/M
 widths
@@ -48813,17 +48873,17 @@ wisdom/M
 wise/MYTGDRS
 wiseacre/SM
 wisecrack/MDSG
 wiseguy/S
 wish/MDRSZG
 wishbone/SM
 wisher/M
 wishful/Y
-wishlist/SM
+wishlist's
 wisp/MS
 wispy/RT
 wist
 wisteria/SM
 wistful/YP
 wistfulness/M
 wit/SM
 witch/MDSG
--- a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic
+++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic
@@ -1,9 +1,9 @@
-52286
+52342
 0/nm
 0th/pt
 1/n1
 1st/p
 1th/tc
 2/nm
 2nd/p
 2th/tc
@@ -32,16 +32,17 @@ ABM/SM
 ABS
 AC/M
 ACLU/M
 ACT
 ACTH/M
 AD/M
 ADC
 ADD
+ADM
 ADP/M
 AF
 AFAIK
 AFB
 AFC/M
 AFDC
 AFN
 AFT
@@ -706,16 +707,17 @@ Apatosaurus
 Apennines/M
 Aphrodite/M
 Apia/M
 Apocalypse/M
 Apocrypha/M
 Apollinaire/M
 Apollo/SM
 Apollonian/M
+Apostle/M
 Appalachia/M
 Appalachian/SM
 Appalachians/M
 Appaloosa/SM
 Apple/M
 Appleseed/M
 Appleton/M
 Appomattox/M
@@ -931,16 +933,17 @@ Athlon/M
 Atkins/M
 Atkinson/M
 Atlanta/M
 Atlantes
 Atlantic/M
 Atlantis/M
 Atlas/MS
 Atman/M
+Atonement
 Atreus/M
 Atria/M
 Atropos/M
 Attic/M
 Attica/M
 Attila/M
 Attlee/M
 Attn
@@ -1618,16 +1621,17 @@ Boise/M
 Bojangles/M
 Boleyn/M
 Bolivar/M
 Bolivia/M
 Bolivian/MS
 Bollywood/M
 Bologna/M
 Bolshevik/SM
+Bolsheviki
 Bolshevism/M
 Bolshevist/M
 Bolshoi/M
 Bolton/M
 Boltzmann/M
 Bombay/M
 Bonaparte/M
 Bonaventure/M
@@ -2719,16 +2723,17 @@ Columbia/M
 Columbine/M
 Columbus/M
 Com
 Comanche/MS
 Combs/M
 Comcast/M
 Comdr
 Comintern/M
+Commandment
 Commons/M
 Commonwealth
 Communion/SM
 Communism
 Communist/SM
 Como/M
 Comoran
 Comoros/M
@@ -3209,16 +3214,17 @@ Deadhead/M
 DealTime/M
 Dean/M
 Deana/M
 Deandre/M
 Deane/M
 Deann/M
 Deanna/M
 Deanne/M
+Death/M
 Deb/SM
 Debbi/M
 Debbie/M
 Debby/M
 Debi/M
 Debian/M
 Debora/M
 Deborah/M
@@ -4521,16 +4527,17 @@ GE/M
 GED
 GHQ/M
 GHz/M
 GI
 GIF
 GIGO
 GM/M
 GMAT
+GMO
 GMT/M
 GNP/M
 GNU/M
 GOP/M
 GP/M
 GPA
 GPO
 GPS
@@ -5777,16 +5784,17 @@ IOU/M
 IP
 IPA
 IPO/SM
 IQ/M
 IRA/SM
 IRC
 IRS/M
 ISBN
+ISIS
 ISO/M
 ISP
 ISS
 IT
 IUD
 IV/SM
 IVF
 Ia
@@ -7163,16 +7171,17 @@ Liam/M
 Lian/M
 Liana/M
 Liane/M
 Lianne/M
 Libbey/M
 Libbie/M
 Libby/M
 Liberace/M
+Liberal
 Liberia/M
 Liberian/SM
 Libra/MS
 LibreOffice/M
 Libreville/M
 Librium/M
 Libya/M
 Libyan/SM
@@ -7558,16 +7567,17 @@ Macmillan/M
 Macon/M
 Macromedia/M
 Macumba/M
 Macy/M
 Mada/M
 Madagascan/SM
 Madagascar/M
 Madalyn/M
+Madam
 Maddalena/M
 Madden/M
 Maddi/M
 Maddie/M
 Maddox/M
 Maddy/M
 Madeira/SM
 Madelaine/M
@@ -8206,16 +8216,17 @@ Mesolithic/M
 Mesopotamia/M
 Mesopotamian
 Mesozoic/M
 Messerschmidt/M
 Messiaen/M
 Messiah/M
 Messiahs
 Messianic
+Messieurs
 Metacafe/M
 Metallica/M
 Metamucil/M
 Methodism/SM
 Methodist/SM
 Methuselah/M
 Metternich/M
 Meuse/M
@@ -8453,16 +8464,17 @@ Monika/M
 Monique/M
 Monk/M
 Monmouth/M
 Monongahela/M
 Monro/M
 Monroe/M
 Monrovia/M
 Monsanto/M
+Monsieur/M
 Monsignor/SM
 Mont/M
 Montague/M
 Montaigne/M
 Montana/M
 Montanan/SM
 Montcalm/M
 Monte/M
@@ -8676,16 +8688,17 @@ NP
 NPR/M
 NR
 NRA
 NRC
 NS
 NSA/M
 NSC
 NSF
+NSFW
 NSPR/M
 NSS/M
 NT
 NV
 NW/M
 NWT
 NY
 NYC
@@ -8967,17 +8980,17 @@ Nisan/M
 Nisei/M
 Nissan/M
 Nita/M
 Niue/M
 Nivea/M
 Niven/M
 Nixon/M
 Nkrumah/M
-No/M
+No/SM
 NoDoz/M
 Noah/M
 Noam/M
 Nobel/M
 Nobelist/MS
 Noble/M
 Noe/M
 Noel/SM
@@ -9218,16 +9231,17 @@ Oort/M
 Opal/M
 Opaline/M
 Opel/M
 OpenBSD/M
 OpenOffice/M
 Ophelia/M
 Ophiuchus/M
 Oppenheimer/M
+Opposition
 Oprah/M
 Ora/M
 Oracle/M
 Oran/M
 Orange/M
 Oranjestad/M
 Orazio/M
 Orbison/M
@@ -9238,16 +9252,17 @@ Oregon/M
 Oregonian/SM
 Orel
 Oren/M
 Oreo/M
 Orestes/M
 Oriana/M
 Orient/M
 Oriental/MS
+Orientalism
 Orin/M
 Orinoco/M
 Orion/M
 Oriya/M
 Orizaba/M
 Orkney/M
 Orlan/M
 Orland/M
@@ -9442,16 +9457,17 @@ Paranß/M
 Parcheesi/M
 Pareto/M
 Paris/M
 Parisian/MS
 Park/SMR
 Parke/M
 Parker/M
 Parkinson/M
+Parkinsonism
 Parkman/M
 Parks/M
 Parliament/M
 Parmenides
 Parmesan/MS
 Parnassus/MS
 Parnell/M
 Parr/M
@@ -10656,16 +10672,17 @@ SD
 SDI
 SE/M
 SEATO
 SEC/M
 SF
 SGML/M
 SIDS/M
 SJ
+SJW
 SK
 SLR
 SNP/SM
 SO/S
 SOB/M
 SOP/M
 SOS/M
 SOSes
@@ -11055,16 +11072,17 @@ Seward/M
 Sextans/M
 Sexton/M
 Seychelles/M
 Seyfert/M
 Seymour/M
 Sgt
 Shackleton/M
 Shaffer/M
+Shah/M
 Shaka/M
 Shaker
 Shakespeare/M
 Shakespearean/M
 Shalom's
 Shamus/M
 Shana/M
 Shandy/M
@@ -12391,16 +12409,17 @@ Urquhart/M
 Ursa/M
 Ursula/M
 Ursuline/M
 Uruguay/M
 Uruguayan/MS
 Urumqi/M
 Usenet/MS
 Ustinov/M
+Ut
 Uta/M
 Utah/M
 Utahan/MS
 Ute/SM
 Utopia/SM
 Utopian/SM
 Utrecht/M
 Utrillo/M
@@ -13203,16 +13222,17 @@ Zhivago/M
 Zhou/M
 Zhukov/M
 Zia/M
 Zibo/M
 Ziegfeld/M
 Ziegler/M
 Ziff/M
 Ziggy/M
+Zika
 Zimbabwe/M
 Zimbabwean/SM
 Zimmerman/M
 Zinfandel/M
 Zion/SM
 Zionism/SM
 Zionist/SM
 Ziploc/M
@@ -13646,16 +13666,17 @@ additive/SM
 addle/GDS
 address's
 address/AGDS
 addressable
 addressed/U
 addressee/SM
 adduce/GDS
 adenine/M
+adenocarcinoma
 adenoid/SM
 adenoidal
 adept/MYPS
 adeptness/M
 adequacy/IM
 adequate/IY
 adequateness/M
 adhere/GDS
@@ -14324,17 +14345,17 @@ amethyst/SM
 amiability/M
 amiable
 amiably
 amicability/M
 amicable
 amicably
 amid
 amide/MS
-amidships
+amidship/S
 amidst
 amigo/MS
 amino
 amir/SM
 amiss
 amity/M
 ammeter/SM
 ammo/M
@@ -14996,16 +15017,17 @@ ardor/MS
 arduous/YP
 arduousness/M
 are/SMB
 area/SM
 areal
 aren't
 arena/MS
 argent/M
+arginine
 argon/M
 argosy/SM
 argot/MS
 arguable/IU
 arguably/U
 argue/ZGDRS
 arguer/M
 argument/MS
@@ -15908,16 +15930,17 @@ baptist/S
 baptistery/SM
 baptistry/SM
 baptize/ZGDRS
 baptized/U
 baptizer/M
 bar's
 bar/ECUTS
 barb/SZGMDR
+barbacoa
 barbarian/SM
 barbarianism/MS
 barbaric
 barbarically
 barbarism/SM
 barbarity/SM
 barbarize/DSG
 barbarous/Y
@@ -17820,33 +17843,33 @@ burghs
 burglar/MS
 burglarize/GDS
 burglarproof
 burglary/SM
 burgle/DSG
 burgomaster/SM
 burgundy/SM
 burial/ASM
-burka/S
+burka/SM
 burl/MDS
 burlap/M
 burlesque/MGDS
 burliness/M
 burly/RPT
 burn/MDRZGSB
 burnable/SM
 burner/M
 burnish/ZGMDRS
 burnisher/M
 burnoose/MS
 burnous/MS
 burnout/MS
 burnt
 burp/MDGS
-burqa/S
+burqa/SM
 burr/MDGS
 burrito/MS
 burro/SM
 burrow/SMDRZG
 burrower/M
 bursa/M
 bursae
 bursar/SM
@@ -18929,16 +18952,17 @@ chastisement/SM
 chastiser/M
 chastity/M
 chasuble/SM
 chat/SM
 chateau/SM
 chateaux
 chatelaine/SM
 chatline/S
+chatroom/M
 chatted
 chattel/MS
 chatter/MDRZGS
 chatterbox/MS
 chatterer/M
 chattily
 chattiness/M
 chatting
@@ -19375,16 +19399,17 @@ citric
 citron/MS
 citronella/M
 citrous
 citrus/MS
 city/SM
 citywide
 civet/MS
 civic/S
+civically
 civics/M
 civil/UY
 civilian/MS
 civility/ISM
 civilization/MS
 civilize/GDS
 civilized/U
 civvies/M
@@ -20675,16 +20700,17 @@ contortion/MS
 contortionist/SM
 contraband/M
 contrabassoon/S
 contraception/M
 contraceptive/SM
 contract/MDG
 contractible
 contractile
+contractility
 contraction/S
 contractual/Y
 contradict/SDG
 contradiction/SM
 contradictory
 contradistinction/MS
 contraflow/S
 contrail/MS
@@ -21079,17 +21105,19 @@ counterfeit/ZGMDRS
 counterfeiter/M
 counterfoil/MS
 countering
 counterinsurgency/SM
 counterintelligence/M
 counterman/M
 countermand/GMDS
 countermeasure/SM
+countermelody/S
 countermen
+countermove/S
 counteroffensive/SM
 counteroffer/SM
 counterpane/SM
 counterpart/SM
 counterpetition
 counterpoint/MDGS
 counterpoise/MGDS
 counterproductive
@@ -21747,17 +21775,17 @@ cutting/MYS
 cuttlefish/MS
 cutup/SM
 cutworm/MS
 cw
 cwt
 cyan/M
 cyanide/M
 cyber
-cyberbully/S
+cyberbully/SM
 cybercafe/S
 cybercafÚ/S
 cybernetic/S
 cybernetics/M
 cyberpunk/SM
 cybersex
 cyberspace/MS
 cyborg/SM
@@ -22694,17 +22722,17 @@ diamondback/MS
 diapason/SM
 diaper/SMDG
 diaphanous
 diaphragm/SM
 diaphragmatic
 diarist/SM
 diarrhea/M
 diary/SM
-diaspora
+diaspora/SM
 diastase/M
 diastole/M
 diastolic
 diathermy/M
 diatom/SM
 diatomaceous
 diatomic
 diatonic
@@ -24075,17 +24103,17 @@ effendi/SM
 efferent
 effervesce/GDS
 effervescence/M
 effervescent/Y
 effete/YP
 effeteness/M
 efficacious/Y
 efficacy/IM
-efficiency/IM
+efficiency/ISM
 efficient/IY
 effigy/SM
 efflorescence/M
 efflorescent
 effluence/M
 effluent/MS
 effluvia
 effluvium/M
@@ -24379,17 +24407,17 @@ emir/MS
 emirate/MS
 emissary/SM
 emission/SM
 emit/S
 emitted
 emitter/MS
 emitting
 emo/SM
-emoji
+emoji/SM
 emollient/MS
 emolument/MS
 emote/XDSGNV
 emoticon/SM
 emotion/M
 emotional/UY
 emotionalism/M
 emotionalize/GDS
@@ -24512,17 +24540,17 @@ endmost
 endocarditis
 endocrine/MS
 endocrinologist/MS
 endocrinology/M
 endogenous/Y
 endometrial
 endometriosis
 endometrium
-endorphin/M
+endorphin/MS
 endorse/LZGDRS
 endorsement/MS
 endorser/M
 endoscope/MS
 endoscopic
 endoscopy/M
 endothelial
 endothermic
@@ -25764,17 +25792,18 @@ fear/MDGS
 fearful/YP
 fearfulness/M
 fearless/PY
 fearlessness/M
 fearsome
 feasibility/M
 feasible/IU
 feasibly
-feast/SMDG
+feast/SMDRZG
+feaster/M
 feat/MS
 feather/SGMD
 featherbedding/M
 featherbrained
 featherless
 featherweight/MS
 feathery/TR
 feature/DSMG
@@ -26351,19 +26380,16 @@ flimsily
 flimsiness/M
 flimsy/TRP
 flinch/GMDS
 fling/GM
 flint/SM
 flintlock/SM
 flinty/TR
 flip/MS
-flipflop/S
-flipflopped
-flipflopping
 flippancy/M
 flippant/Y
 flipped
 flipper/MS
 flippest
 flipping
 flippy/S
 flirt/SGMD
@@ -27003,17 +27029,17 @@ friary/SM
 fricassee/DSM
 fricasseeing
 fricative/SM
 friction/SM
 frictional
 fridge/SM
 friedcake/MS
 friend's
-friend/US
+friend/UGSDY
 friendless
 friendlies
 friendliness/UM
 friendly's
 friendly/UPTR
 friendship/MS
 frieze/SM
 frig/S
@@ -27077,17 +27103,17 @@ frontward/S
 frosh/M
 frost's
 frost/CSDG
 frostbit
 frostbite/MGS
 frostbitten
 frostily
 frostiness/M
-frosting/M
+frosting/SM
 frosty/TPR
 froth/MDG
 frothiness/M
 froths
 frothy/TPR
 froufrou/M
 froward/P
 frowardness/M
@@ -28627,17 +28653,17 @@ habituÚ/SM
 hacienda/SM
 hack/MDRZGS
 hacker/M
 hacking/M
 hackish
 hackle/MS
 hackney/SMDG
 hacksaw/SM
-hacktivist/S
+hacktivist/MS
 hackwork/M
 had
 haddock/SM
 hadn't
 hadst
 hafnium/M
 haft/MS
 hag/SM
@@ -29180,16 +29206,17 @@ heliotrope/SM
 helipad/S
 heliport/MS
 helium/M
 helix/M
 hell/M
 hellbent
 hellcat/MS
 hellebore/M
+hellfire
 hellhole/MS
 hellion/MS
 hellish/YP
 hellishness/M
 hello/SM
 helluva
 helm/MS
 helmet/SMD
@@ -30805,17 +30832,16 @@ industriousness/M
 industry/SM
 indwell/SG
 inebriate/MGNDS
 inebriation/M
 inedible
 ineffability/M
 ineffable
 ineffably
-inefficiency/S
 inelastic
 ineligible/MS
 ineligibly
 ineluctable
 ineluctably
 inept/YP
 ineptitude/M
 ineptness/M
@@ -31752,16 +31778,17 @@ jesting/Y
 jet/SM
 jetliner/SM
 jetport/MS
 jetsam/M
 jetted
 jetting
 jettison/MDSG
 jetty/SM
+jew
 jewel/SZGMDR
 jeweler/M
 jewellery
 jewelry/SM
 jg
 jib/SGMD
 jibbed
 jibbing
@@ -31891,16 +31918,17 @@ joylessness/M
 joyous/YP
 joyousness/M
 joyridden
 joyride/RSMZG
 joyrider/M
 joyriding/M
 joyrode
 joystick/SM
+jr
 jubilant/Y
 jubilation/M
 jubilee/SM
 judder/GDS
 judge's
 judge/ADSG
 judgement/SM
 judgemental
@@ -32293,17 +32321,18 @@ kronur
 krypton/M
 krˇna/M
 krˇnur
 kt
 kuchen/SM
 kudos/M
 kudzu/SM
 kumquat/MS
-kvetch/GMDS
+kvetch/ZGMDRS
+kvetcher/M
 kw
 l/SDXTGJ
 la/M
 lab/SM
 label's
 label/ASDG
 labeled/U
 labelled/U
@@ -32390,17 +32419,17 @@ lambast/GDS
 lambaste/S
 lambda/SM
 lambency/M
 lambent/Y
 lambkin/SM
 lambskin/SM
 lambswool
 lame/MYZTGDRSP
-lamebrain/MS
+lamebrain/MDS
 lameness/M
 lament/BSMDG
 lamentably
 lamentation/MS
 lamina/M
 laminae
 laminar
 laminate/MGNDS
@@ -32810,16 +32839,17 @@ letterbox/S
 lettered/U
 letterer/M
 letterhead/MS
 lettering/M
 letterpress/M
 letting/S
 lettuce/MS
 letup/SM
+leucine
 leucotomy/S
 leukemia/M
 leukemic/SM
 leukocyte/MS
 levee/SM
 level/PSZGMDRY
 leveler/M
 levelheaded/P
@@ -32941,16 +32971,17 @@ lighthouse/MS
 lighting's
 lightly
 lightness/M
 lightning/MDS
 lightproof
 lightship/MS
 lightweight/SM
 ligneous
+lignin
 lignite/M
 lii
 likability/M
 likable/P
 likableness/M
 like/EMGDST
 likeability/M
 likeable/P
@@ -33243,26 +33274,26 @@ logged
 logger/SM
 loggerhead/SM
 loggia/SM
 logging/M
 logic/M
 logical/Y
 logicality/M
 logician/MS
-login/S
+login/SM
 logistic/S
 logistical/Y
 logistics/M
 logjam/SM
 logo/MS
-logoff/S
-logon/S
+logoff/SM
+logon/SM
 logotype/SM
-logout/S
+logout/SM
 logrolling/M
 logy/RT
 loin/MS
 loincloth/M
 loincloths
 loiter/ZGSDR
 loiterer/M
 loitering/M
@@ -33602,19 +33633,20 @@ maddest
 madding
 made/AU
 mademoiselle/MS
 madhouse/SM
 madman/M
 madmen
 madness/M
 madras/MS
-madrasa/S
-madrassah
-madrassahs
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
 madrigal/SM
 madwoman/M
 madwomen
 maelstrom/SM
 maestro/SM
 mafia/SM
 mafiosi
 mafioso/M
@@ -34319,17 +34351,17 @@ melon/SM
 melt's
 melt/ADSG
 meltdown/SM
 member's
 member/EAS
 membership/SM
 membrane/SM
 membranous
-meme/S
+meme/MS
 memento/MS
 memo/MS
 memoir/MS
 memorabilia/M
 memorability/M
 memorable/U
 memorably
 memorandum/MS
@@ -34551,16 +34583,17 @@ mgr
 mi/MNX
 miasma/MS
 mic/S
 mica/M
 mice
 mick/S
 mickey/MS
 micro/SM
+microaggression/SM
 microbe/MS
 microbial
 microbiological
 microbiologist/MS
 microbiology/M
 microbrewery/SM
 microchip/MS
 microcircuit/SM
@@ -34687,17 +34720,17 @@ milkman/M
 milkmen
 milkshake/SM
 milksop/MS
 milkweed/SM
 milky/RTP
 mill/MDRSZGJ
 millage/M
 millennia
-millennial/MS
+millennial/M
 millennium/MS
 miller/M
 millet/M
 milliard/MS
 millibar/MS
 milligram/MS
 milliliter/MS
 millimeter/MS
@@ -34766,17 +34799,17 @@ minibus/MS
 minicab/S
 minicam/MS
 minicomputer/SM
 minifloppies
 minim/SM
 minimal/Y
 minimalism/M
 minimalist/MS
-minimization
+minimization/M
 minimize/DSG
 minimum/MS
 mining/M
 minion/M
 miniseries/M
 miniskirt/MS
 minister/SGMD
 ministerial
@@ -34998,24 +35031,26 @@ mitigate/XDSGN
 mitigated/U
 mitigation/M
 mitochondria
 mitochondrial
 mitochondrion
 mitoses
 mitosis/M
 mitotic
+mitral
 mitt/MNSX
 mitten/M
 mix/ZGMDRSB
 mixed/U
 mixer/M
 mixture/SM
 mizzen/MS
 mizzenmast/SM
+mkay
 mks
 ml
 mm
 mnemonic/MS
 mnemonically
 mo/CKHS
 moan/MDRSZG
 moaner/M
@@ -35027,17 +35062,17 @@ mobbing/C
 mobile/MS
 mobility/M
 mobilization/CM
 mobilizations
 mobilize/CDSG
 mobilizer/SM
 mobster/SM
 moccasin/SM
-mocha/M
+mocha/SM
 mock/DRSZG
 mocker/M
 mockery/SM
 mocking/Y
 mockingbird/SM
 mod/STM
 modal/SM
 modality/S
@@ -35433,16 +35468,17 @@ mousetrap/SM
 mousetrapped
 mousetrapping
 mousey
 mousiness/M
 moussaka/S
 mousse/MGDS
 mousy/PTR
 mouth/GMD
+mouthfeel
 mouthful/MS
 mouthiness/M
 mouthpiece/MS
 mouths
 mouthwash/MS
 mouthwatering
 mouthy/PTR
 mouton/M
@@ -35536,16 +35572,17 @@ multicultural
 multiculturalism/M
 multidimensional
 multidisciplinary
 multifaceted
 multifamily
 multifarious/PY
 multifariousness/M
 multiform
+multigrain
 multilateral/Y
 multilayered
 multilevel
 multilingual
 multilingualism/M
 multimedia/M
 multimillionaire/SM
 multinational/SM
@@ -35682,16 +35719,17 @@ mutineer/SM
 mutinous/Y
 mutiny/GDSM
 mutt/MS
 mutter/ZGJMDRS
 mutterer/M
 muttering/M
 mutton/M
 muttonchops/M
+muttony
 mutual/Y
 mutuality/M
 muumuu/MS
 muzak
 muzzily
 muzzle/DSMG
 muzzy/P
 my
@@ -35972,17 +36010,17 @@ nelson/SM
 nematode/SM
 nemeses
 nemesis/M
 neoclassic
 neoclassical
 neoclassicism/M
 neocolonialism/M
 neocolonialist/MS
-neocon/S
+neocon/SM
 neoconservative/SM
 neodymium/M
 neolithic
 neologism/SM
 neon/M
 neonatal
 neonate/MS
 neophilia
@@ -35990,16 +36028,17 @@ neophyte/MS
 neoplasm/MS
 neoplastic
 neoprene/M
 nepenthe/M
 nephew/SM
 nephrite/M
 nephritic
 nephritis/M
+nephropathy
 nepotism/M
 nepotist/SM
 nepotistic
 neptunium/M
 nerd/MS
 nerdy/RT
 nerve's
 nerve/UDSG
@@ -36125,17 +36164,17 @@ nickelodeon/SM
 nicker/MDG
 nickle/S
 nickname/DSMG
 nicotine/M
 niece/SM
 niff
 niffy
 nifty/TR
-nigga/S
+nigga/SM
 niggard/SMY
 niggardliness/M
 niggaz
 nigger/SM!
 niggle/MZGDRS
 niggler/M
 nigh/RT
 night/SMY
@@ -36430,17 +36469,17 @@ nonnative/MS
 nonnegotiable
 nonnuclear
 nonnumerical
 nonobjective
 nonobligatory
 nonobservance/M
 nonobservant
 nonoccupational
-nonoccurrence/M
+nonoccurence
 nonofficial
 nonoperational
 nonoperative
 nonparallel/MS
 nonpareil/MS
 nonparticipant/MS
 nonparticipating
 nonpartisan/SM
@@ -37231,17 +37270,17 @@ orator/SM
 oratorical/Y
 oratorio/MS
 oratory/SM
 orb/SM
 orbicular
 orbit/MDRZGS
 orbital/SM
 orbiter/M
-orc/S
+orc/SM
 orchard/SM
 orchestra/MS
 orchestral
 orchestrate/DSXGN
 orchestration/M
 orchid/SM
 ordain/SDLG
 ordainment/M
@@ -38172,16 +38211,17 @@ parlous
 parmigiana
 parmigiano
 parochial/Y
 parochialism/M
 parodist/SM
 parody/GDSM
 parole/MGDS
 parolee/MS
+parotid
 paroxysm/SM
 paroxysmal
 parquet/MDSG
 parquetry/M
 parred
 parricidal
 parricide/MS
 parring
@@ -38880,30 +38920,33 @@ pg
 phaeton/MS
 phage/S
 phagocyte/SM
 phalanger/SM
 phalanges
 phalanx/MS
 phalli
 phallic
+phallocentric
+phallocentrism
 phallus/M
 phantasm/MS
 phantasmagoria/MS
 phantasmagorical
 phantasmal
 phantom/SM
 pharaoh/M
 pharaohs
 pharisaic
 pharisee/SM
 pharmaceutic/MS
 pharmaceutical/SM
 pharmaceutics/M
 pharmacist/MS
+pharmacologic
 pharmacological
 pharmacologist/SM
 pharmacology/M
 pharmacopeia/SM
 pharmacopoeia/MS
 pharmacy/SM
 pharyngeal
 pharynges
@@ -38995,17 +39038,16 @@ phosphodiesterase
 phosphor/MS
 phosphorescence/M
 phosphorescent/Y
 phosphoric
 phosphorous
 phosphorus/M
 phosphorylate/DSGN
 photo/SGMD
-photobomb/DGS
 photocell/MS
 photocopier/M
 photocopy/DRSMZG
 photoelectric
 photoelectrically
 photoengrave/DRSJZG
 photoengraver/M
 photoengraving/M
@@ -39506,18 +39548,16 @@ plughole/S
 plugin/SM
 plum/GMDS
 plumage/M
 plumb/MDRSZGJ
 plumbed/U
 plumber/M
 plumbing/M
 plume/MS
-plummer
-plummest
 plummet/SGMD
 plummy
 plump/MDRYSTGP
 plumpness/M
 plumy/RT
 plunder/SZGMDR
 plunderer/M
 plunge/DRSMZG
@@ -39555,17 +39595,17 @@ poaching/M
 pock/GMDS
 pocket/SMDG
 pocketbook/SM
 pocketful/SM
 pocketknife/M
 pocketknives
 pockmark/MDGS
 pod/SM
-podcast/SM
+podcast/SMG
 podded
 podding
 podiatrist/SM
 podiatry/M
 podium/SM
 poem/MS
 poesy/M
 poet/MS
@@ -39899,16 +39939,17 @@ postnatal
 postoperative
 postpaid
 postpartum
 postpone/DSGL
 postponement/SM
 postprandial
 postscript/SM
 postseason/SM
+postsynaptic
 postulate/XDSMGN
 postulation/M
 postural
 posture/MGJDS
 posturing/M
 postwar
 postwoman
 postwomen
@@ -40118,16 +40159,17 @@ preferably
 preference/MS
 preferential/Y
 preferment/M
 preferred
 preferring
 prefigure/GDS
 prefix/MDSG
 preform/GSD
+prefrontal
 pregame/SM
 pregnancy/SM
 pregnant
 preheat/GSD
 prehensile
 prehistorian/S
 prehistoric
 prehistorical/Y
@@ -41030,22 +41072,23 @@ pyre/MS
 pyrimidine/MS
 pyrite/SM
 pyrites/M
 pyromania/M
 pyromaniac/SM
 pyrotechnic/S
 pyrotechnical
 pyrotechnics/M
+pyruvate
 python/SM
 pyx/MS
 pzazz
 q
 qr
-qt
+qt/S
 qty
 qua
 quack/GMDS
 quackery/M
 quad/MS
 quadrangle/SM
 quadrangular
 quadrant/MS
@@ -41419,16 +41462,17 @@ rangy/RTP
 rani/MS
 rank/TGJPMDRYS
 ranking/M
 rankle/DSG
 rankness/M
 ransack/SGD
 ransom/SZGMDR
 ransomer/M
+ransomware
 rant/ZGMDJRS
 ranter/M
 rap/SZGMDR
 rapacious/PY
 rapaciousness/M
 rapacity/M
 rape/MS
 raper/M
@@ -42028,17 +42072,17 @@ renovate/DSXGN
 renovation/M
 renovator/MS
 renown/MD
 rent/ZGMDRS
 rental/SM
 renter/M
 renunciation/SM
 reopen/SDG
-reorg/DSG
+reorg/MDSG
 rep/SM
 repaint/GDS
 repair/BZR
 repairer/M
 repairman/M
 repairmen
 reparable
 reparation/MS
@@ -42594,17 +42638,17 @@ roasting/M
 rob/S
 robbed
 robber/MS
 robbery/SM
 robbing
 robe's
 robe/EGDS
 robin/MS
-robocall/SGD
+robocall/SGMD
 robot/MS
 robotic/S
 robotics/M
 robotize/GDS
 robust/RYPT
 robustness/M
 rock/ZGMDRS
 rockabilly/M
@@ -42890,32 +42934,35 @@ ruthenium/M
 rutherfordium/M
 ruthless/YP
 ruthlessness/M
 rutted
 rutting
 rutty/RT
 rye/M
 s/NYXB
+sabbath/M
+sabbaths
 sabbatical/SM
 saber/MS
 sable/MS
 sabot/MS
 sabotage/DSMG
 saboteur/SM
 sabra/MS
 sabre/MS
 sac/SM
 saccharin/M
 saccharine
 sacerdotal
 sachem/SM
 sachet/SM
-sack/GMDJS
+sack/ZGMDRJS
 sackcloth/M
+sacker/M
 sackful/MS
 sacking/M
 sacra
 sacrament/MS
 sacramental
 sacred/YP
 sacredness/M
 sacrifice/DSMG
@@ -43056,16 +43103,17 @@ same/SP
 sameness/M
 samey
 samizdat/S
 samosa/S
 samovar/SM
 sampan/SM
 sample/DRSMZGJ
 sampler/M
+sampling/M
 samurai/SM
 sanatorium/SM
 sanctification/M
 sanctify/GDSN
 sanctimonious/YP
 sanctimoniousness/M
 sanctimony/M
 sanction/GSMD
@@ -44261,17 +44309,17 @@ shibboleth/M
 shibboleths
 shield/MDGS
 shift/GMDS
 shiftily
 shiftiness/M
 shiftless/PY
 shiftlessness/M
 shifty/RPT
-shiitake/S
+shiitake/SM
 shill/GMDSJ
 shillelagh/M
 shillelaghs
 shilling/M
 shim/MS
 shimmed
 shimmer/SMDG
 shimmery
@@ -44355,17 +44403,17 @@ shogunate/M
 shone
 shoo/GDS
 shook
 shoot/ZGMRSJ
 shooter/M
 shooting/M
 shootout/MS
 shop/MS
-shopaholic/S
+shopaholic/MS
 shopfitter/S
 shopfitting
 shopfront/S
 shopkeeper/MS
 shoplift/DRZGS
 shoplifter/M
 shoplifting/M
 shoppe/MZGDRS
@@ -44619,17 +44667,17 @@ silt/GMDS
 silty/TR
 silvan
 silver/GMDS
 silverfish/MS
 silversmith/M
 silversmiths
 silverware/M
 silvery
-sim/S
+sim/SM
 simian/MS
 similar/Y
 similarity/ESM
 simile/MS
 similitude/EM
 simmer/GMDS
 simonize/DSG
 simony/M
@@ -45476,16 +45524,17 @@ soot/M
 sooth/MDRSZG
 soothe
 soother/M
 soothing/Y
 soothsayer/MS
 soothsaying/M
 sooty/RT
 sop/SM
+soph
 sophism/M
 sophist/MS
 sophistic
 sophistical
 sophisticate/DSMGN
 sophisticated/U
 sophistication/M
 sophistry/SM
@@ -45530,17 +45579,17 @@ soufflÚ/SM
 sough/MDG
 soughs
 sought/U
 souk/S
 soul/MS
 soulful/YP
 soulfulness/M
 soulless/YP
-soulmate/S
+soulmate/SM
 sound/JPSMDRYZTG
 soundalike/S
 soundbar/S
 soundbite/S
 soundboard/MS
 soundcheck/S
 sounder/M
 sounding/M
@@ -45733,17 +45782,17 @@ speedwell/M
 speedy/TPR
 speleological
 speleologist/MS
 speleology/M
 spell/JSMDRZG
 spellbind/ZGRS
 spellbinder/M
 spellbound
-spellcheck/DRZGS
+spellcheck/MDRZGS
 spellchecker/M
 spelldown/SM
 speller/M
 spelling/M
 spelt
 spelunker/MS
 spelunking/M
 spend/BSRZG
@@ -46691,17 +46740,17 @@ studentship/S
 studied/U
 studiedly
 studio/MS
 studious/PY
 studiousness/M
 studly/RT
 study's
 study/AGDS
-stuff/GSMD
+stuff/GSMDJ
 stuffily
 stuffiness/M
 stuffing/M
 stuffy/RPT
 stultification/M
 stultify/DSNG
 stumble/DRSMZG
 stumbler/M
@@ -47021,17 +47070,17 @@ sumptuousness/M
 sun/SM
 sunbath/ZGMDRS
 sunbathe
 sunbather/M
 sunbathing/M
 sunbaths
 sunbeam/SM
 sunbed/S
-sunbelt
+sunbelt/SM
 sunblock/MS
 sunbonnet/SM
 sunburn/SGMD
 sunburst/MS
 sundae/MS
 sundeck/S
 sunder/DSG
 sundial/SM
@@ -47794,17 +47843,17 @@ taxman
 taxmen
 taxon
 taxonomic
 taxonomical
 taxonomist/MS
 taxonomy/SM
 taxpayer/MS
 taxpaying
-tbs
+tb/S
 tbsp
 tea/SM
 teabag/S
 teacake/SM
 teach/ZGRSBJ
 teachable/U
 teacher/M
 teaching/M
@@ -47990,17 +48039,17 @@ tenantry/M
 tench
 tend/IFEDGS
 tended/U
 tendency/SM
 tendentious/YP
 tendentiousness/M
 tender/SMDRYTGP
 tenderfoot/MS
-tenderhearted/PY
+tenderhearted/P
 tenderheartedness/M
 tenderize/ZGDRS
 tenderizer/M
 tenderloin/SM
 tenderness/M
 tendinitis/M
 tendon/SM
 tendonitis/M
@@ -48468,16 +48517,17 @@ tighten/ZGDR
 tightener/M
 tightfisted
 tightness/M
 tightrope/MS
 tights/M
 tightwad/MS
 tigress/MS
 til
+tilapia
 tilde/SM
 tile/MZGDRS
 tiler/M
 tiling/M
 till's
 till/EDRZGS
 tillable
 tillage/M
@@ -49372,25 +49422,27 @@ trust/ESGMD
 trustee/MS
 trusteeship/SM
 trustful/EY
 trustfulness/M
 trusting/Y
 trustworthiness/M
 trustworthy/TPR
 trusty/TRSM
-truth/UM
+truth/ZMR
+truther/M
 truthful/UYP
 truthfulness/UM
 truthiness
 truths/U
 try's
 try/AGDS
 trying/Y
 tryout/SM
+tryptophan
 tryst/SMDG
 tsarists
 tsetse/MS
 tsp
 tsunami/SM
 ttys
 tub/SZGMDR
 tuba/MS
@@ -49530,18 +49582,19 @@ twas
 twat/S
 tweak/SMDG
 twee
 tweed/SM
 tweeds/M
 tweedy/RT
 tween
 tweep/S
-tweet/SMDRZG
-tweeter/M
+tweet's
+tweet/ASDG
+tweeter/SM
 tweezers/M
 twelfth/M
 twelfths
 twelve/SM
 twelvemonth/M
 twelvemonths
 twentieth/M
 twentieths
@@ -49640,20 +49693,21 @@ ubiquitous/Y
 ubiquity/M
 udder/SM
 ufologist/SM
 ufology/M
 ugh
 ugliness/M
 ugly/RTP
 uh
+uhf
 ukase/SM
 ukulele/SM
 ulcer/SM
-ulcerate/DSGN
+ulcerate/XDSGN
 ulceration/M
 ulcerous
 ulna/M
 ulnae
 ulnar
 ulster/MS
 ult
 ulterior
@@ -49926,17 +49980,16 @@ unflagging/Y
 unflappability/M
 unflappable
 unflappably
 unflattering
 unflinching/Y
 unforgettably
 unforgivably
 unfortunate/MS
-unfriend/GD
 unfriendly/T
 unfrock/DG
 unfruitful
 unfunny
 ungainliness/M
 ungainly/RPT
 ungenerous
 ungentle
@@ -50106,16 +50159,17 @@ unthinking/Y
 untidy/PTR
 until
 untimely/T
 untiring/Y
 untouchable/MS
 untoward
 untrue/RT
 untrustworthy
+untruth/M
 unutterable
 unutterably
 unwarrantable
 unwary/T
 unwavering
 unwed
 unwelcome/G
 unwell
@@ -50147,16 +50201,17 @@ upholder/M
 upholster/ASGD
 upholsterer/MS
 upholstery/M
 upkeep/M
 upland/MS
 uplift/JSMDG
 upload/SDG
 upmarket
+upmost
 upon
 upped
 upper/SM
 uppercase/M
 upperclassman/M
 upperclassmen
 upperclasswoman
 upperclasswomen
@@ -50806,16 +50861,17 @@ viviparous
 vivisect/DGS
 vivisection/M
 vivisectional
 vivisectionist/SM
 vixen/SM
 vixenish/Y
 viz
 vizier/SM
+vlf
 vocab
 vocable/MS
 vocabulary/SM
 vocal/SMY
 vocalic
 vocalist/SM
 vocalization/MS
 vocalize/DSG
@@ -50828,17 +50884,17 @@ vociferous/YP
 vociferousness/M
 vodka/SM
 vogue/SM
 voguish
 voice/IDSMG
 voiced/U
 voiceless/PY
 voicelessness/M
-voicemail/M
+voicemail/SM
 void/MDSGB
 voila
 voile/M
 voilÓ
 vol/S
 volatile
 volatility/M
 volatilize/DSG
@@ -50911,17 +50967,17 @@ vulpine
 vulture/SM
 vulturous
 vulva/M
 vulvae
 vuvuzela/MS
 vying
 w/DNXTGVJ
 wabbit/S
-wack/RTS
+wack/MRTS
 wackiness/M
 wacko/SM
 wacky/RPT
 wad/SZGMDR
 wadded
 wadding/M
 waddle/DSMG
 wade/MS
@@ -51073,17 +51129,17 @@ warrior/SM
 warship/SM
 wart/MS
 warthog/SM
 wartime/M
 warty/TR
 wary/UPRT
 was
 wasabi
-wash/BMDRSZG
+wash/BJMDRSZG
 washable/SM
 washbasin/SM
 washboard/SM
 washbowl/SM
 washcloth/M
 washcloths
 washed/U
 washer/M
@@ -51124,17 +51180,18 @@ watchmaking/M
 watchman/M
 watchmen
 watchstrap/S
 watchtower/SM
 watchword/MS
 water/GSMD
 waterbed/MS
 waterbird/SM
-waterboard/DJSG
+waterboard/MDJSG
+waterboarding/M
 waterborne
 watercolor/MS
 watercourse/SM
 watercraft/M
 watercress/M
 waterfall/SM
 waterfowl/SM
 waterfront/MS
@@ -51243,17 +51300,16 @@ webcast/SMG
 webdesign/MS
 webfeet
 webfoot/M
 webinar/SM
 webisode/MS
 weblog/MS
 webmaster/SM
 webmistress/MS
-webpage/SM
 website/SM
 wed/AS
 wedded/A
 wedder
 wedding/SM
 wedge/DSMG
 wedgie/MS
 wedlock/M
@@ -51695,17 +51751,17 @@ wisdom/M
 wise/MYTGDRS
 wiseacre/SM
 wisecrack/MDSG
 wiseguy/S
 wish/MDRSZG
 wishbone/SM
 wisher/M
 wishful/Y
-wishlist/SM
+wishlist's
 wisp/MS
 wispy/RT
 wist
 wisteria/SM
 wistful/YP
 wistfulness/M
 wit/SM
 witch/MDSG
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -16,17 +16,17 @@
 #include "gfx2DGlue.h"
 #include "../layers/ipc/ShadowLayers.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/TextureClientSharedSurface.h"
 
 #ifdef XP_WIN
 #include "SharedSurfaceANGLE.h"         // for SurfaceFactory_ANGLEShareHandle
 #include "SharedSurfaceD3D11Interop.h"  // for SurfaceFactory_D3D11Interop
-#include "gfxWindowsPlatform.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include "SharedSurfaceGralloc.h"
 #include "nsXULAppAPI.h"
 #endif
 
 #ifdef XP_MACOSX
@@ -103,19 +103,20 @@ GLScreenBuffer::CreateFactory(GLContext*
                 }
 #endif
                 break;
             }
             case mozilla::layers::LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
                 // Enable surface sharing only if ANGLE and compositing devices
                 // are both WARP or both not WARP
+                gfx::DeviceManagerD3D11* dm = gfx::DeviceManagerD3D11::Get();
                 if (gl->IsANGLE() &&
-                    (gl->IsWARP() == gfxWindowsPlatform::GetPlatform()->IsWARP()) &&
-                    gfxWindowsPlatform::GetPlatform()->CompositorD3D11TextureSharingWorks())
+                    (gl->IsWARP() == dm->IsWARP()) &&
+                    dm->TextureSharingWorks())
                 {
                     factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, allocator, flags);
                 }
 
                 if (!factory && gfxPrefs::WebGLDXGLEnabled()) {
                   factory = SurfaceFactory_D3D11Interop::Create(gl, caps, allocator, flags);
                 }
 #endif
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -1,19 +1,19 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* 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/. */
 
 #include "SharedSurfaceANGLE.h"
 
 #include <d3d11.h>
-#include "gfxWindowsPlatform.h"
 #include "GLContextEGL.h"
 #include "GLLibraryEGL.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 
 namespace mozilla {
 namespace gl {
 
 // Returns `EGL_NO_SURFACE` (`0`) on error.
 static EGLSurface
 CreatePBufferSurface(GLLibraryEGL* egl,
@@ -191,18 +191,19 @@ public:
             }
 
             if (FAILED(hr)) {
                 NS_WARNING("Failed to lock the texture");
                 return;
             }
         }
 
-        RefPtr<ID3D11Device> device;
-        if (!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device)) {
+        RefPtr<ID3D11Device> device =
+          gfx::DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
+        if (!device) {
             return;
         }
 
         device->GetImmediateContext(getter_AddRefs(mDeviceContext));
 
         mTexture->GetDesc(&mDesc);
         mDesc.BindFlags = 0;
         mDesc.Usage = D3D11_USAGE_STAGING;
@@ -247,18 +248,19 @@ public:
     D3D11_MAPPED_SUBRESOURCE mSubresource;
 };
 
 bool
 SharedSurface_ANGLEShareHandle::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
 {
     MOZ_ASSERT(out_surface);
 
-    RefPtr<ID3D11Device> device;
-    if (!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device)) {
+    RefPtr<ID3D11Device> device =
+      gfx::DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
+    if (!device) {
         return false;
     }
 
     RefPtr<ID3D11Texture2D> tex;
     HRESULT hr = device->OpenSharedResource(mShareHandle,
                                             __uuidof(ID3D11Texture2D),
                                             (void**)(ID3D11Texture2D**)getter_AddRefs(tex));
 
--- a/gfx/gl/SharedSurfaceD3D11Interop.cpp
+++ b/gfx/gl/SharedSurfaceD3D11Interop.cpp
@@ -5,16 +5,17 @@
 
 #include "SharedSurfaceD3D11Interop.h"
 
 #include <d3d11.h>
 #include "gfxPrefs.h"
 #include "GLContext.h"
 #include "WGLLibrary.h"
 #include "nsPrintfCString.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 
 namespace mozilla {
 namespace gl {
 
 /*
 Sample Code for WGL_NV_DX_interop2:
 Example: Render to Direct3D 11 backbuffer with openGL:
 
@@ -120,19 +121,18 @@ public:
 
     WGLLibrary* const mWGL;
     const RefPtr<ID3D11Device> mD3D; // Only needed for lifetime guarantee.
     const HANDLE mDXGLDeviceHandle;
 
     static already_AddRefed<DXGLDevice> Open(WGLLibrary* wgl)
     {
         MOZ_ASSERT(wgl->HasDXInterop2());
-        gfxWindowsPlatform* plat = gfxWindowsPlatform::GetPlatform();
 
-        RefPtr<ID3D11Device> d3d = plat->GetD3D11ContentDevice();
+        RefPtr<ID3D11Device> d3d = gfx::DeviceManagerD3D11::Get()->GetContentDevice();
         if (!d3d) {
             NS_WARNING("Failed to create D3D11 device.");
             return nullptr;
         }
 
         HANDLE dxglDeviceHandle = wgl->fDXOpenDevice(d3d);
         if (!dxglDeviceHandle) {
             NS_WARNING("Failed to open D3D device for use by WGL.");
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -2,16 +2,17 @@
  * 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/. */
 
 #include "IMFYCbCrImage.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include "mozilla/layers/CompositableClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/layers/TextureClient.h"
 #include "d3d9.h"
 
 namespace mozilla {
 namespace layers {
 
 IMFYCbCrImage::IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer)
@@ -219,18 +220,18 @@ IMFYCbCrImage::GetD3D9TextureClient(Comp
 
 TextureClient*
 IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
 {
   if (mTextureClient) {
     return mTextureClient;
   }
 
-  RefPtr<ID3D11Device> device;
-  gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(&device);
+  RefPtr<ID3D11Device> device =
+    gfx::DeviceManagerD3D11::Get()->GetImageBridgeDevice();
 
   LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType();
   if (!device || backend != LayersBackend::LAYERS_D3D11) {
     if (backend == LayersBackend::LAYERS_D3D9 ||
         backend == LayersBackend::LAYERS_D3D11) {
       return GetD3D9TextureClient(aClient);
     }
     return nullptr;
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -164,17 +164,17 @@ ScrollFrame(nsIContent* aContent,
   // input events to compensate.
   // Note that if the main-thread had a change in its scroll position, we don't
   // want to record that difference here, because it can be large and throw off
   // input events by a large amount. It is also going to be transient, because
   // any main-thread scroll position change will be synced to APZ and we will
   // get another repaint request when APZ confirms. In the interval while this
   // is happening we can just leave the callback transform as it was.
   bool mainThreadScrollChanged =
-    sf && sf->CurrentScrollGeneration() != aMetrics.GetScrollGeneration();
+    sf && sf->CurrentScrollGeneration() != aMetrics.GetScrollGeneration() && nsLayoutUtils::CanScrollOriginClobberApz(sf->LastScrollOrigin());
   if (aContent && !mainThreadScrollChanged) {
     CSSPoint scrollDelta = apzScrollOffset - actualScrollOffset;
     aContent->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(scrollDelta),
                           nsINode::DeleteProperty<CSSPoint>);
   }
 }
 
 static void
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -30,17 +30,17 @@
 #include "TiledLayerBuffer.h"
 #include "mozilla/dom/WindowBinding.h"  // for Overfill Callback
 #include "FrameLayerBuilder.h"          // for FrameLayerbuilder
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #include "LayerMetricsWrapper.h"
 #endif
 #ifdef XP_WIN
-#include "gfxWindowsPlatform.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #endif
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
@@ -767,17 +767,17 @@ ClientLayerManager::GetBackendName(nsASt
 {
   switch (mForwarder->GetCompositorBackendType()) {
     case LayersBackend::LAYERS_NONE: aName.AssignLiteral("None"); return;
     case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
     case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
     case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
     case LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
-      if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
+      if (DeviceManagerD3D11::Get()->IsWARP()) {
         aName.AssignLiteral("Direct3D 11 WARP");
       } else {
         aName.AssignLiteral("Direct3D 11");
       }
 #endif
       return;
     }
     default: NS_RUNTIMEABORT("Invalid backend");
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -29,16 +29,17 @@
 #include "LayersLogging.h"              // for AppendToString
 #include "gfxUtils.h"                   // for gfxUtils::GetAsLZ4Base64Str
 #include "IPDLActor.h"
 #include "BufferTexture.h"
 #include "gfxPrefs.h"
 #include "mozilla/layers/ShadowLayers.h"
 
 #ifdef XP_WIN
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/TextureD3D9.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include "mozilla/layers/TextureDIB.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #endif
 #ifdef MOZ_X11
 #include "mozilla/layers/TextureClientX11.h"
@@ -1034,17 +1035,17 @@ TextureClient::CreateForDrawing(TextureF
   int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
 #endif
 
 #ifdef XP_WIN
   if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
       (moz2DBackend == gfx::BackendType::DIRECT2D ||
        moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
        (!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
-        gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())) &&
+        DeviceManagerD3D11::Get()->GetContentDevice())) &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize)
   {
     data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
   }
   if (aLayersBackend == LayersBackend::LAYERS_D3D9 &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -7,16 +7,17 @@
 
 #include "TextureD3D11.h"
 #include "CompositorD3D11Shaders.h"
 #include "CompositorD3D11ShadersVR.h"
 
 #include "gfxWindowsPlatform.h"
 #include "nsIWidget.h"
 #include "nsIGfxInfo.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/ImageHost.h"
 #include "mozilla/layers/ContentHost.h"
 #include "mozilla/layers/Effects.h"
 #include "nsWindowsHelpers.h"
 #include "gfxPrefs.h"
 #include "gfxConfig.h"
 #include "gfxCrashReporterUtils.h"
 #include "gfxVR.h"
@@ -198,17 +199,18 @@ bool
 CompositorD3D11::Initialize(nsCString* const out_failureReason)
 {
   ScopedGfxFeatureReporter reporter("D3D11 Layers");
 
   MOZ_ASSERT(gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING));
 
   HRESULT hr;
 
-  if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&mDevice)) {
+  mDevice = DeviceManagerD3D11::Get()->GetCompositorDevice();
+  if (!mDevice) {
     *out_failureReason = "FEATURE_FAILURE_D3D11_NO_DEVICE";
     return false;
   }
 
   mDevice->GetImmediateContext(getter_AddRefs(mContext));
 
   if (!mContext) {
     gfxCriticalNote << "[D3D11] failed to get immediate context";
@@ -1252,17 +1254,18 @@ CompositorD3D11::EndFrame()
   CD3D11_QUERY_DESC  desc(D3D11_QUERY_EVENT);
   mDevice->CreateQuery(&desc, getter_AddRefs(query));
   if (query) {
     mContext->End(query);
   }
 
   UINT presentInterval = 0;
 
-  if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
+  bool isWARP = DeviceManagerD3D11::Get()->IsWARP();
+  if (isWARP) {
     // When we're using WARP we cannot present immediately as it causes us
     // to tear when rendering. When not using WARP it appears the DWM takes
     // care of tearing for us.
     presentInterval = 1;
   }
 
   if (oldSize == mSize) {
     RefPtr<IDXGISwapChain1> chain;
@@ -1275,18 +1278,17 @@ CompositorD3D11::EndFrame()
     if (partialPresentPref > 0) {
       allowPartialPresent = true;
     } else if (partialPresentPref < 0) {
       allowPartialPresent = false;
     } else if (partialPresentPref == 0) {
       nsString vendorID;
       nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
       gfxInfo->GetAdapterVendorID(vendorID);
-      allowPartialPresent = !vendorID.EqualsLiteral("0x10de") ||
-                            gfxWindowsPlatform::GetPlatform()->IsWARP();
+      allowPartialPresent = !vendorID.EqualsLiteral("0x10de") || isWARP;
     }
 
     if (SUCCEEDED(hr) && chain && allowPartialPresent) {
       DXGI_PRESENT_PARAMETERS params;
       PodZero(&params);
       params.DirtyRectsCount = mInvalidRegion.GetNumRects();
       StackArray<RECT, 4> rects(params.DirtyRectsCount);
 
@@ -1500,17 +1502,17 @@ CompositorD3D11::UpdateRenderTarget()
 
   return true;
 }
 
 bool
 DeviceAttachmentsD3D11::InitSyncObject()
 {
   // Sync object is not supported on WARP.
-  if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
+  if (DeviceManagerD3D11::Get()->IsWARP()) {
     return true;
   }
 
   // It's okay to do this on Windows 8. But for now we'll just bail
   // whenever we're using WARP.
   CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1,
                              D3D11_BIND_SHADER_RESOURCE |
                              D3D11_BIND_RENDER_TARGET);
@@ -1702,18 +1704,17 @@ CompositorD3D11::HandleError(HRESULT hr,
   if (SUCCEEDED(hr)) {
     return;
   }
 
   if (aSeverity == Critical) {
     MOZ_CRASH("GFX: Unrecoverable D3D11 error");
   }
 
-  RefPtr<ID3D11Device> device;
-  if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device) || device != mDevice) {
+  if (mDevice && DeviceManagerD3D11::Get()->GetCompositorDevice() != mDevice) {
     gfxCriticalError() << "Out of sync D3D11 devices in HandleError, " << (int)mVerifyBuffersFailed;
   }
 
   HRESULT hrOnReset = S_OK;
   bool deviceRemoved = hr == DXGI_ERROR_DEVICE_REMOVED;
 
   if (deviceRemoved && mDevice) {
     hrOnReset = mDevice->GetDeviceRemovedReason();
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -6,16 +6,17 @@
 #include "TextureD3D11.h"
 #include "CompositorD3D11.h"
 #include "gfxContext.h"
 #include "Effects.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #include "gfxPrefs.h"
 #include "ReadbackManagerD3D11.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/gfx/Logging.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
@@ -356,20 +357,21 @@ DXGITextureData::Create(IntSize aSize, S
   return D3D11TextureData::Create(aSize, aFormat, aFlags);
 }
 
 DXGITextureData*
 D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags,
                          ID3D11Device* aDevice)
 {
   RefPtr<ID3D11Device> device = aDevice;
-  if (!device &&
-      !gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device))
-  {
-    return nullptr;
+  if (!device) {
+    device = DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
+    if (!device) {
+      return nullptr;
+    }
   }
 
   CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
                                 aSize.width, aSize.height, 1, 1,
                                 D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
 
   newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
   if (!NS_IsMainThread() || !!(aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT)) {
@@ -652,19 +654,17 @@ DXGITextureHostD3D11::OpenSharedHandle()
 
 RefPtr<ID3D11Device>
 DXGITextureHostD3D11::GetDevice()
 {
   if (mFlags & TextureFlags::INVALID_COMPOSITOR) {
     return nullptr;
   }
 
-  RefPtr<ID3D11Device> device;
-  gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device);
-  return device;
+  return DeviceManagerD3D11::Get()->GetCompositorDevice();
 }
 
 static CompositorD3D11* AssertD3D11Compositor(Compositor* aCompositor)
 {
   CompositorD3D11* compositor = aCompositor ? aCompositor->AsCompositorD3D11()
                                             : nullptr;
   if (!compositor) {
     gfxCriticalNote << "[D3D11] Attempt to set an incompatible compositor";
@@ -790,19 +790,17 @@ DXGIYCbCrTextureHostD3D11::OpenSharedHan
 
 RefPtr<ID3D11Device>
 DXGIYCbCrTextureHostD3D11::GetDevice()
 {
   if (mFlags & TextureFlags::INVALID_COMPOSITOR) {
     return nullptr;
   }
 
-  RefPtr<ID3D11Device> device;
-  gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device);
-  return device;
+  return DeviceManagerD3D11::Get()->GetCompositorDevice();
 }
 
 void
 DXGIYCbCrTextureHostD3D11::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = AssertD3D11Compositor(aCompositor);
   if (!mCompositor) {
     mTextureSources[0] = nullptr;
@@ -1116,17 +1114,17 @@ SyncObjectD3D11::RegisterTexture(ID3D11T
 }
 
 void
 SyncObjectD3D11::FinalizeFrame()
 {
   HRESULT hr;
 
   if (!mD3D11Texture && mD3D11SyncedTextures.size()) {
-    ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
+    RefPtr<ID3D11Device> device = DeviceManagerD3D11::Get()->GetContentDevice();
 
     hr = device->OpenSharedResource(mHandle, __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
 
     if (FAILED(hr) || !mD3D11Texture) {
       gfxCriticalError() << "Failed to D3D11 OpenSharedResource for frame finalization: " << hexa(hr);
 
       if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
         return;
@@ -1159,18 +1157,17 @@ SyncObjectD3D11::FinalizeFrame()
       }
       gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
     }
 
     D3D11_BOX box;
     box.front = box.top = box.left = 0;
     box.back = box.bottom = box.right = 1;
 
-    ID3D11Device* dev = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
-
+    RefPtr<ID3D11Device> dev = DeviceManagerD3D11::Get()->GetContentDevice();
     if (!dev) {
       if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
         return;
       }
       MOZ_CRASH("GFX: Invalid D3D11 content device");
     }
 
     RefPtr<ID3D11DeviceContext> ctx;
--- a/gfx/layers/ipc/LayerAnimationUtils.cpp
+++ b/gfx/layers/ipc/LayerAnimationUtils.cpp
@@ -25,18 +25,17 @@ AnimationUtils::TimingFunctionToComputed
       return Some(result);
     }
     case TimingFunction::TStepFunction: {
       StepFunction sf = aTimingFunction.get_StepFunction();
       nsTimingFunction::Type type = sf.type() == 1 ?
         nsTimingFunction::Type::StepStart :
         nsTimingFunction::Type::StepEnd;
       ComputedTimingFunction result;
-      result.Init(nsTimingFunction(type, sf.steps(),
-                  nsTimingFunction::Keyword::Explicit));
+      result.Init(nsTimingFunction(type, sf.steps()));
       return Some(result);
     }
     default:
       MOZ_ASSERT_UNREACHABLE(
         "Function must be null, bezier or step");
       break;
   }
   return Nothing();
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/LayersMessages.h"  // for Edit, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/SharedBufferManagerChild.h"
+#include "mozilla/layers/PTextureChild.h"
 #include "ShadowLayerUtils.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsTArray.h"                   // for AutoTArray, nsTArray, etc
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "mozilla/ReentrantMonitor.h"
 
 namespace mozilla {
@@ -431,16 +432,17 @@ ShadowLayerForwarder::UseTextures(Compos
 {
   MOZ_ASSERT(aCompositable && aCompositable->IsConnected());
 
   AutoTArray<TimedTexture,4> textures;
 
   for (auto& t : aTextures) {
     MOZ_ASSERT(t.mTextureClient);
     MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
+    MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
     FenceHandle fence = t.mTextureClient->GetAcquireFenceHandle();
     ReadLockDescriptor readLock;
     t.mTextureClient->SerializeReadLock(readLock);
     textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
                                         readLock,
                                         fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()),
                                         t.mTimeStamp, t.mPictureRect,
                                         t.mFrameID, t.mProducerID, t.mInputFrameID));
@@ -466,16 +468,18 @@ ShadowLayerForwarder::UseComponentAlphaT
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aCompositable->IsConnected());
   MOZ_ASSERT(aTextureOnWhite);
   MOZ_ASSERT(aTextureOnBlack);
   MOZ_ASSERT(aCompositable->GetIPDLActor());
   MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
   MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
   MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
+  MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
+  MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
 
   ReadLockDescriptor readLockW;
   ReadLockDescriptor readLockB;
   aTextureOnBlack->SerializeReadLock(readLockB);
   aTextureOnWhite->SerializeReadLock(readLockW);
 
   mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
   mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
@@ -535,16 +539,17 @@ ShadowLayerForwarder::DestroyInTransacti
 void
 ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable,
                                                     TextureClient* aTexture)
 {
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aTexture);
   MOZ_ASSERT(aCompositable->IsConnected());
   MOZ_ASSERT(aTexture->GetIPDLActor());
+  MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
   if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
     // We don't have an actor anymore, don't try to use it!
     return;
   }
 
   mTxn->AddEdit(
     CompositableOperation(
       nullptr, aCompositable->GetIPDLActor(),
--- a/gfx/src/gfxTelemetry.h
+++ b/gfx/src/gfxTelemetry.h
@@ -50,12 +50,18 @@ enum class FeatureStatus
   // This feature was attempted but later determined to be broken.
   Broken
 };
 
 const char* FeatureStatusToString(FeatureStatus aStatus);
 bool IsFeatureStatusFailure(FeatureStatus aStatus);
 bool IsFeatureStatusSuccess(FeatureStatus aStatus);
 
+enum class TelemetryDeviceCode : uint32_t {
+  Content = 0,
+  Image = 1,
+  D2D1 = 2
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif // gfx_src_gfxTelemetry_h__
--- a/gfx/tests/gtest/TestTreeTraversal.cpp
+++ b/gfx/tests/gtest/TestTreeTraversal.cpp
@@ -31,21 +31,21 @@ class TestNodeBase {
     void SetRegion(nsRegion aRegion);
     int GetExpectedTraversalRank();
     int GetActualTraversalRank();
     int GetValue();
     T GetType();
     nsRegion GetRegion();
     virtual bool IsLeaf() = 0;
   private:
-    int mExpectedTraversalRank;
-    int mActualTraversalRank;
-    int mValue;
-    nsRegion mRegion;
-    T mType;
+    MOZ_INIT_OUTSIDE_CTOR int mExpectedTraversalRank;
+    MOZ_INIT_OUTSIDE_CTOR int mActualTraversalRank;
+    MOZ_INIT_OUTSIDE_CTOR int mValue;
+    MOZ_INIT_OUTSIDE_CTOR nsRegion mRegion;
+    MOZ_INIT_OUTSIDE_CTOR T mType;
   protected:
     virtual ~TestNodeBase<T>() {};
 };
 
 template <class T>
 class TestNodeReverse : public TestNodeBase<T> {
   public:
     explicit TestNodeReverse(T aType, int aExpectedTraversalRank = -1);
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/D3D11Checks.cpp
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
+
+#include "D3D11Checks.h"
+#include "gfxConfig.h"
+#include "GfxDriverInfo.h"
+#include "gfxPrefs.h"
+#include "gfxWindowsPlatform.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/gfx/Logging.h"
+#include "nsIGfxInfo.h"
+#include <dxgi.h>
+#include <d3d10_1.h>
+#include <d3d11.h>
+
+namespace mozilla {
+namespace gfx {
+
+using namespace mozilla::widget;
+
+/* static */ bool
+D3D11Checks::DoesRenderTargetViewNeedRecreating(ID3D11Device *aDevice)
+{
+    bool result = false;
+    // CreateTexture2D is known to crash on lower feature levels, see bugs
+    // 1170211 and 1089413.
+    if (aDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
+        return true;
+    }
+
+    RefPtr<ID3D11DeviceContext> deviceContext;
+    aDevice->GetImmediateContext(getter_AddRefs(deviceContext));
+    int backbufferWidth = 32; int backbufferHeight = 32;
+    RefPtr<ID3D11Texture2D> offscreenTexture;
+    RefPtr<IDXGIKeyedMutex> keyedMutex;
+
+    D3D11_TEXTURE2D_DESC offscreenTextureDesc = { 0 };
+    offscreenTextureDesc.Width = backbufferWidth;
+    offscreenTextureDesc.Height = backbufferHeight;
+    offscreenTextureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    offscreenTextureDesc.MipLevels = 0;
+    offscreenTextureDesc.ArraySize = 1;
+    offscreenTextureDesc.SampleDesc.Count = 1;
+    offscreenTextureDesc.SampleDesc.Quality = 0;
+    offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
+    offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+    offscreenTextureDesc.CPUAccessFlags = 0;
+    offscreenTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+
+    HRESULT hr = aDevice->CreateTexture2D(&offscreenTextureDesc, NULL, getter_AddRefs(offscreenTexture));
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingCreateTexture2DFail";
+        return false;
+    }
+
+    hr = offscreenTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(keyedMutex));
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingKeyedMutexFailed";
+        return false;
+    }
+    D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
+    offscreenRTVDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+    offscreenRTVDesc.Texture2D.MipSlice = 0;
+
+    RefPtr<ID3D11RenderTargetView> offscreenRTView;
+    hr = aDevice->CreateRenderTargetView(offscreenTexture, &offscreenRTVDesc, getter_AddRefs(offscreenRTView));
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingCreateRenderTargetViewFailed";
+        return false;
+    }
+
+    // Acquire and clear
+    keyedMutex->AcquireSync(0, INFINITE);
+    FLOAT color1[4] = { 1, 1, 0.5, 1 };
+    deviceContext->ClearRenderTargetView(offscreenRTView, color1);
+    keyedMutex->ReleaseSync(0);
+
+
+    keyedMutex->AcquireSync(0, INFINITE);
+    FLOAT color2[4] = { 1, 1, 0, 1 };
+
+    deviceContext->ClearRenderTargetView(offscreenRTView, color2);
+    D3D11_TEXTURE2D_DESC desc;
+
+    offscreenTexture->GetDesc(&desc);
+    desc.Usage = D3D11_USAGE_STAGING;
+    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+    desc.MiscFlags = 0;
+    desc.BindFlags = 0;
+    ID3D11Texture2D* cpuTexture;
+    hr = aDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingCreateCPUTextureFailed";
+        return false;
+    }
+
+    deviceContext->CopyResource(cpuTexture, offscreenTexture);
+
+    D3D11_MAPPED_SUBRESOURCE mapped;
+    hr = deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingMapFailed " << hexa(hr);
+        return false;
+    }
+    int resultColor = *(int*)mapped.pData;
+    deviceContext->Unmap(cpuTexture, 0);
+    cpuTexture->Release();
+
+    // XXX on some drivers resultColor will not have changed to
+    // match the clear
+    if (resultColor != 0xffffff00) {
+        gfxCriticalNote << "RenderTargetViewNeedsRecreating";
+        result = true;
+    }
+
+    keyedMutex->ReleaseSync(0);
+    return result;
+}
+
+/* static */ bool
+D3D11Checks::DoesDeviceWork()
+{
+  static bool checked = false;
+  static bool result = false;
+
+  if (checked)
+      return result;
+  checked = true;
+
+  if (gfxPrefs::Direct2DForceEnabled() ||
+      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
+  {
+    result = true;
+    return true;
+  }
+
+  if (GetModuleHandleW(L"igd10umd32.dll")) {
+    const wchar_t* checkModules[] = {L"dlumd32.dll",
+                                     L"dlumd11.dll",
+                                     L"dlumd10.dll"};
+    for (int i=0; i<PR_ARRAY_SIZE(checkModules); i+=1) {
+      if (GetModuleHandleW(checkModules[i])) {
+        nsString displayLinkModuleVersionString;
+        gfxWindowsPlatform::GetDLLVersion(checkModules[i],
+                                          displayLinkModuleVersionString);
+        uint64_t displayLinkModuleVersion;
+        if (!ParseDriverVersion(displayLinkModuleVersionString,
+                                &displayLinkModuleVersion)) {
+          gfxCriticalError() << "DisplayLink: could not parse version "
+                             << checkModules[i];
+          return false;
+        }
+        if (displayLinkModuleVersion <= V(8,6,1,36484)) {
+          gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DisplayLink: too old version " << displayLinkModuleVersionString.get();
+          return false;
+        }
+      }
+    }
+  }
+  result = true;
+  return true;
+}
+
+static bool
+TryCreateTexture2D(ID3D11Device *device,
+                   D3D11_TEXTURE2D_DESC* desc,
+                   D3D11_SUBRESOURCE_DATA* data,
+                   RefPtr<ID3D11Texture2D>& texture)
+{
+  // Older Intel driver version (see bug 1221348 for version #s) crash when
+  // creating a texture with shared keyed mutex and data.
+  MOZ_SEH_TRY {
+    return !FAILED(device->CreateTexture2D(desc, data, getter_AddRefs(texture)));
+  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+    // For now we want to aggregrate all the crash signature to a known crash.
+    gfxDevCrash(LogReason::TextureCreation) << "Crash creating texture. See bug 1221348.";
+    return false;
+  }
+}
+
+// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
+// with E_OUTOFMEMORY.
+static bool
+DoesTextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT format, UINT bindflags)
+{
+  // CreateTexture2D is known to crash on lower feature levels, see bugs
+  // 1170211 and 1089413.
+  if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
+    return false;
+  }
+
+  if (gfxPrefs::Direct2DForceEnabled() ||
+      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
+  {
+    return true;
+  }
+
+  if (GetModuleHandleW(L"atidxx32.dll")) {
+    nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+    if (gfxInfo) {
+      nsString vendorID, vendorID2;
+      gfxInfo->GetAdapterVendorID(vendorID);
+      gfxInfo->GetAdapterVendorID2(vendorID2);
+      if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
+        if (!gfxPrefs::LayersAMDSwitchableGfxEnabled()) {
+          return false;
+        }
+        gfxCriticalError(CriticalLog::DefaultOptions(false)) << "PossiblyBrokenSurfaceSharing_UnexpectedAMDGPU";
+      }
+    }
+  }
+
+  RefPtr<ID3D11Texture2D> texture;
+  D3D11_TEXTURE2D_DESC desc;
+  const int texture_size = 32;
+  desc.Width = texture_size;
+  desc.Height = texture_size;
+  desc.MipLevels = 1;
+  desc.ArraySize = 1;
+  desc.Format = format;
+  desc.SampleDesc.Count = 1;
+  desc.SampleDesc.Quality = 0;
+  desc.Usage = D3D11_USAGE_DEFAULT;
+  desc.CPUAccessFlags = 0;
+  desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+  desc.BindFlags = bindflags;
+
+  uint32_t color[texture_size * texture_size];
+  for (size_t i = 0; i < sizeof(color)/sizeof(color[0]); i++) {
+    color[i] = 0xff00ffff;
+  }
+  // XXX If we pass the data directly at texture creation time we
+  //     get a crash on Intel 8.5.10.[18xx-1994] drivers.
+  //     We can work around this issue by doing UpdateSubresource.
+  if (!TryCreateTexture2D(device, &desc, nullptr, texture)) {
+    gfxCriticalNote << "DoesD3D11TextureSharingWork_TryCreateTextureFailure";
+    return false;
+  }
+
+  RefPtr<IDXGIKeyedMutex> sourceSharedMutex;
+  texture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sourceSharedMutex));
+  if (FAILED(sourceSharedMutex->AcquireSync(0, 30*1000))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceMutexTimeout";
+    // only wait for 30 seconds
+    return false;
+  }
+
+  RefPtr<ID3D11DeviceContext> deviceContext;
+  device->GetImmediateContext(getter_AddRefs(deviceContext));
+
+  int stride = texture_size * 4;
+  deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride, stride * texture_size);
+
+  if (FAILED(sourceSharedMutex->ReleaseSync(0))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceReleaseSyncTimeout";
+    return false;
+  }
+
+  HANDLE shareHandle;
+  RefPtr<IDXGIResource> otherResource;
+  if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
+                                     getter_AddRefs(otherResource))))
+  {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetResourceFailure";
+    return false;
+  }
+
+  if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
+    return false;
+  }
+
+  RefPtr<ID3D11Resource> sharedResource;
+  RefPtr<ID3D11Texture2D> sharedTexture;
+  if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
+                                        getter_AddRefs(sharedResource))))
+  {
+    gfxCriticalError(CriticalLog::DefaultOptions(false)) << "OpenSharedResource failed for format " << format;
+    return false;
+  }
+
+  if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
+                                            getter_AddRefs(sharedTexture))))
+  {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
+    return false;
+  }
+
+  // create a staging texture for readback
+  RefPtr<ID3D11Texture2D> cpuTexture;
+  desc.Usage = D3D11_USAGE_STAGING;
+  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+  desc.MiscFlags = 0;
+  desc.BindFlags = 0;
+  if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(cpuTexture)))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_CreateTextureFailure";
+    return false;
+  }
+
+  RefPtr<IDXGIKeyedMutex> sharedMutex;
+  sharedResource->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sharedMutex));
+  if (FAILED(sharedMutex->AcquireSync(0, 30*1000))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_AcquireSyncTimeout";
+    // only wait for 30 seconds
+    return false;
+  }
+
+  // Copy to the cpu texture so that we can readback
+  deviceContext->CopyResource(cpuTexture, sharedTexture);
+
+  D3D11_MAPPED_SUBRESOURCE mapped;
+  int resultColor = 0;
+  if (SUCCEEDED(deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped))) {
+    // read the texture
+    resultColor = *(int*)mapped.pData;
+    deviceContext->Unmap(cpuTexture, 0);
+  } else {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_MapFailed";
+    return false;
+  }
+
+  sharedMutex->ReleaseSync(0);
+
+  // check that the color we put in is the color we get out
+  if (resultColor != color[0]) {
+    // Shared surfaces seem to be broken on dual AMD & Intel HW when using the
+    // AMD GPU
+    gfxCriticalNote << "DoesD3D11TextureSharingWork_ColorMismatch";
+    return false;
+  }
+
+  RefPtr<ID3D11ShaderResourceView> sharedView;
+
+  // This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
+  if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, getter_AddRefs(sharedView)))) {
+    gfxCriticalNote << "CreateShaderResourceView failed for format" << format;
+    return false;
+  }
+
+  return true;
+}
+
+/* static */ bool
+D3D11Checks::DoesTextureSharingWork(ID3D11Device *device)
+{
+  return DoesTextureSharingWorkInternal(device, DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
+}
+
+/* static */ bool
+D3D11Checks::DoesAlphaTextureSharingWork(ID3D11Device *device)
+{
+  return DoesTextureSharingWorkInternal(device, DXGI_FORMAT_R8_UNORM, D3D11_BIND_SHADER_RESOURCE);
+}
+
+/* static */ bool
+D3D11Checks::GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out)
+{
+  RefPtr<IDXGIDevice> dxgiDevice;
+  HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice));
+  if (FAILED(hr)) {
+    return false;
+  }
+
+  RefPtr<IDXGIAdapter> dxgiAdapter;
+  if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
+    return false;
+  }
+
+  return SUCCEEDED(dxgiAdapter->GetDesc(out));
+}
+
+/* static */ void
+D3D11Checks::WarnOnAdapterMismatch(ID3D11Device *device)
+{
+  DXGI_ADAPTER_DESC desc;
+  PodZero(&desc);
+  GetDxgiDesc(device, &desc);
+
+  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+  nsString vendorID;
+  gfxInfo->GetAdapterVendorID(vendorID);
+  nsresult ec;
+  int32_t vendor = vendorID.ToInteger(&ec, 16);
+  if (vendor != desc.VendorId) {
+    gfxCriticalNote << "VendorIDMismatch V " << hexa(vendor) << " " << hexa(desc.VendorId);
+  }
+}
+
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/D3D11Checks.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
+
+#ifndef mozilla_gfx_thebes_D3D11Checks_h
+#define mozilla_gfx_thebes_D3D11Checks_h
+
+struct ID3D11Device;
+struct DXGI_ADAPTER_DESC;
+
+namespace mozilla {
+namespace gfx {
+
+struct D3D11Checks
+{
+  static bool DoesRenderTargetViewNeedRecreating(ID3D11Device* aDevice);
+  static bool DoesDeviceWork();
+  static bool DoesTextureSharingWork(ID3D11Device *device);
+  static bool DoesAlphaTextureSharingWork(ID3D11Device *device);
+  static void WarnOnAdapterMismatch(ID3D11Device* device);
+  static bool GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out);
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // mozilla_gfx_thebes_D3D11Checks_h
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/DeviceManagerD3D11.cpp
@@ -0,0 +1,678 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
+
+#include "DeviceManagerD3D11.h"
+#include "D3D11Checks.h"
+#include "gfxConfig.h"
+#include "GfxDriverInfo.h"
+#include "gfxPrefs.h"
+#include "gfxWindowsPlatform.h"
+#include "mozilla/D3DMessageUtils.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/WindowsVersion.h"
+#include "mozilla/gfx/GraphicsMessages.h"
+#include "mozilla/gfx/Logging.h"
+#include "nsIGfxInfo.h"
+#include "nsWindowsHelpers.h"
+#include <d3d11.h>
+
+namespace mozilla {
+namespace gfx {
+
+using namespace mozilla::widget;
+
+StaticAutoPtr<DeviceManagerD3D11> DeviceManagerD3D11::sInstance;
+
+// We don't have access to the D3D11CreateDevice type in gfxWindowsPlatform.h,
+// since it doesn't include d3d11.h, so we use a static here. It should only
+// be used within InitializeD3D11.
+decltype(D3D11CreateDevice)* sD3D11CreateDeviceFn = nullptr;
+
+/* static */ void
+DeviceManagerD3D11::Init()
+{
+  sInstance = new DeviceManagerD3D11();
+}
+
+/* static */ void
+DeviceManagerD3D11::Shutdown()
+{
+  sInstance = nullptr;
+}
+
+DeviceManagerD3D11::DeviceManagerD3D11()
+ : mDeviceLock("gfxWindowsPlatform.mDeviceLock"),
+   mIsWARP(false),
+   mTextureSharingWorks(false)
+{
+  // Set up the D3D11 feature levels we can ask for.
+  if (IsWin8OrLater()) {
+    mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
+  }
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
+}
+
+static inline bool
+IsWARPStable()
+{
+  // It seems like nvdxgiwrap makes a mess of WARP. See bug 1154703.
+  if (!IsWin8OrLater() || GetModuleHandleA("nvdxgiwrap.dll")) {
+    return false;
+  }
+  return true;
+}
+
+bool
+DeviceManagerD3D11::CanUseD3D11ImageBridge()
+{
+  if (XRE_IsContentProcess()) {
+    if (!gfxPlatform::GetPlatform()->GetParentDevicePrefs().useD3D11ImageBridge()) {
+      return false;
+    }
+  }
+  return !mIsWARP;
+}
+
+void
+DeviceManagerD3D11::CreateDevices()
+{
+  FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
+  MOZ_ASSERT(d3d11.IsEnabled());
+
+  nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll"));
+  sD3D11CreateDeviceFn =
+    (decltype(D3D11CreateDevice)*)GetProcAddress(d3d11Module, "D3D11CreateDevice");
+
+  if (!sD3D11CreateDeviceFn) {
+    // We should just be on Windows Vista or XP in this case.
+    d3d11.SetFailed(FeatureStatus::Unavailable, "Direct3D11 not available on this computer",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_LIB"));
+    return;
+  }
+
+  // Check if a failure was injected for testing.
+  if (gfxPrefs::DeviceFailForTesting()) {
+    d3d11.SetFailed(FeatureStatus::Failed, "Direct3D11 device failure simulated by preference",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_SIM"));
+    return;
+  }
+
+  if (XRE_IsParentProcess()) {
+    if (!gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
+      AttemptD3D11DeviceCreation(d3d11);
+      if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
+        return;
+      }
+
+      // If we failed to get a device, but WARP is allowed and might work,
+      // re-enable D3D11 and switch to WARP.
+      if (!mCompositorDevice && IsWARPStable() && !gfxPrefs::LayersD3D11DisableWARP()) {
+        gfxConfig::Reenable(Feature::D3D11_COMPOSITING, Fallback::USE_D3D11_WARP_COMPOSITOR);
+      }
+    }
+
+    // If that failed, see if we can use WARP.
+    if (gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
+      MOZ_ASSERT(d3d11.IsEnabled());
+      MOZ_ASSERT(!mCompositorDevice);
+      MOZ_ASSERT(IsWARPStable() || gfxPrefs::LayersD3D11ForceWARP());
+
+      AttemptWARPDeviceCreation();
+      if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
+        return;
+      }
+    }
+
+    // If we still have no device by now, exit.
+    if (!mCompositorDevice) {
+      MOZ_ASSERT(!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING));
+      return;
+    }
+
+    // Either device creation function should have returned Available.
+    MOZ_ASSERT(d3d11.IsEnabled());
+  } else {
+    // Child processes do not need a compositor, but they do need to know
+    // whether the parent process is using WARP and whether or not texture
+    // sharing works.
+    mIsWARP = gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR);
+    mTextureSharingWorks =
+      gfxPlatform::GetPlatform()->GetParentDevicePrefs().d3d11TextureSharingWorks();
+  }
+
+  if (CanUseD3D11ImageBridge()) {
+    if (AttemptD3D11ImageBridgeDeviceCreation() == FeatureStatus::CrashedInHandler) {
+      DisableD3D11AfterCrash();
+      return;
+    }
+  }
+
+  if (AttemptD3D11ContentDeviceCreation() == FeatureStatus::CrashedInHandler) {
+    DisableD3D11AfterCrash();
+    return;
+  }
+
+  // We leak these everywhere and we need them our entire runtime anyway, let's
+  // leak it here as well. We keep the pointer to sD3D11CreateDeviceFn around
+  // as well for D2D1 and device resets.
+  d3d11Module.disown();
+}
+
+IDXGIAdapter1*
+DeviceManagerD3D11::GetDXGIAdapter()
+{
+  if (mAdapter) {
+    return mAdapter;
+  }
+
+  nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
+  decltype(CreateDXGIFactory1)* createDXGIFactory1 = (decltype(CreateDXGIFactory1)*)
+    GetProcAddress(dxgiModule, "CreateDXGIFactory1");
+
+  if (!createDXGIFactory1) {
+    return nullptr;
+  }
+
+  // Try to use a DXGI 1.1 adapter in order to share resources
+  // across processes.
+  RefPtr<IDXGIFactory1> factory1;
+  HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
+                                  getter_AddRefs(factory1));
+  if (FAILED(hr) || !factory1) {
+    // This seems to happen with some people running the iZ3D driver.
+    // They won't get acceleration.
+    return nullptr;
+  }
+
+  if (!XRE_IsContentProcess()) {
+    // In the parent process, we pick the first adapter.
+    if (FAILED(factory1->EnumAdapters1(0, getter_AddRefs(mAdapter)))) {
+      return nullptr;
+    }
+  } else {
+    const DxgiAdapterDesc& parent =
+      gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
+
+    // In the child process, we search for the adapter that matches the parent
+    // process. The first adapter can be mismatched on dual-GPU systems.
+    for (UINT index = 0; ; index++) {
+      RefPtr<IDXGIAdapter1> adapter;
+      if (FAILED(factory1->EnumAdapters1(index, getter_AddRefs(adapter)))) {
+        break;
+      }
+
+      DXGI_ADAPTER_DESC desc;
+      if (SUCCEEDED(adapter->GetDesc(&desc)) &&
+          desc.AdapterLuid.HighPart == parent.AdapterLuid.HighPart &&
+          desc.AdapterLuid.LowPart == parent.AdapterLuid.LowPart &&
+          desc.VendorId == parent.VendorId &&
+          desc.DeviceId == parent.DeviceId)
+      {
+        mAdapter = adapter.forget();
+        break;
+      }
+    }
+  }
+
+  if (!mAdapter) {
+    return nullptr;
+  }
+
+  // We leak this module everywhere, we might as well do so here as well.
+  dxgiModule.disown();
+  return mAdapter;
+}
+
+bool
+DeviceManagerD3D11::AttemptD3D11DeviceCreationHelper(
+  IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aOutDevice, HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(
+        aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+        // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
+        // to prevent bug 1092260. IE 11 also uses this flag.
+        D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
+  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+void
+DeviceManagerD3D11::AttemptD3D11DeviceCreation(FeatureState& d3d11)
+{
+  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
+  if (!adapter) {
+    d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI"));
+    return;
+  }
+
+  HRESULT hr;
+  RefPtr<ID3D11Device> device;
+  if (!AttemptD3D11DeviceCreationHelper(adapter, device, hr)) {
+    gfxCriticalError() << "Crash during D3D11 device creation";
+    d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1"));
+    return;
+  }
+
+  if (FAILED(hr) || !device) {
+    gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr);
+    d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2"));
+    return;
+  }
+  if (!D3D11Checks::DoesDeviceWork()) {
+    d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN"));
+    return;
+  }
+
+  {
+    MutexAutoLock lock(mDeviceLock);
+    mCompositorDevice = device;
+  }
+
+  // Only test this when not using WARP since it can fail and cause
+  // GetDeviceRemovedReason to return weird values.
+  mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
+
+  if (!mTextureSharingWorks) {
+    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
+                         FeatureStatus::Broken,
+                         "Texture sharing doesn't work");
+  }
+
+  if (D3D11Checks::DoesRenderTargetViewNeedRecreating(mCompositorDevice)) {
+    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
+                         FeatureStatus::Broken,
+                         "RenderTargetViews need recreating");
+  }
+
+  // It seems like this may only happen when we're using the NVIDIA gpu
+  D3D11Checks::WarnOnAdapterMismatch(mCompositorDevice);
+
+  mCompositorDevice->SetExceptionMode(0);
+  mIsWARP = false;
+}
+
+bool
+DeviceManagerD3D11::AttemptWARPDeviceCreationHelper(
+  ScopedGfxFeatureReporter& aReporterWARP,
+  RefPtr<ID3D11Device>& aOutDevice,
+  HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(
+        nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
+        // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
+        // to prevent bug 1092260. IE 11 also uses this flag.
+        D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
+
+    aReporterWARP.SetSuccessful();
+  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+void
+DeviceManagerD3D11::AttemptWARPDeviceCreation()
+{
+  ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
+  FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
+
+  HRESULT hr;
+  RefPtr<ID3D11Device> device;
+  if (!AttemptWARPDeviceCreationHelper(reporterWARP, device, hr)) {
+    gfxCriticalError() << "Exception occurred initializing WARP D3D11 device!";
+    d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed creating a D3D11 WARP device",
+                     NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE"));
+    return;
+  }
+
+  if (FAILED(hr) || !device) {
+    // This should always succeed... in theory.
+    gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr);
+    d3d11.SetFailed(FeatureStatus::Failed, "Failed to create a D3D11 WARP device",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE2"));
+    return;
+  }
+
+  {
+    MutexAutoLock lock(mDeviceLock);
+    mCompositorDevice = device;
+  }
+
+  // Only test for texture sharing on Windows 8 since it puts the device into
+  // an unusable state if used on Windows 7
+  if (IsWin8OrLater()) {
+    mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
+  }
+  mCompositorDevice->SetExceptionMode(0);
+  mIsWARP = true;
+}
+
+bool
+DeviceManagerD3D11::AttemptD3D11ContentDeviceCreationHelper(
+  IDXGIAdapter1* aAdapter, HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(
+        aAdapter, mIsWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN,
+        nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(mContentDevice), nullptr, nullptr);
+
+  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+FeatureStatus
+DeviceManagerD3D11::AttemptD3D11ContentDeviceCreation()
+{
+  RefPtr<IDXGIAdapter1> adapter;
+  if (!mIsWARP) {
+    adapter = GetDXGIAdapter();
+    if (!adapter) {
+      return FeatureStatus::Unavailable;
+    }
+  }
+
+  HRESULT hr;
+  if (!AttemptD3D11ContentDeviceCreationHelper(adapter, hr)) {
+    gfxCriticalNote << "Recovered from crash while creating a D3D11 content device";
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
+    return FeatureStatus::CrashedInHandler;
+  }
+
+  if (FAILED(hr) || !mContentDevice) {
+    gfxCriticalNote << "Failed to create a D3D11 content device: " << hexa(hr);
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
+    return FeatureStatus::Failed;
+  }
+
+  // InitializeD2D() will abort early if the compositor device did not support
+  // texture sharing. If we're in the content process, we can't rely on the
+  // parent device alone: some systems have dual GPUs that are capable of
+  // binding the parent and child processes to different GPUs. As a safety net,
+  // we re-check texture sharing against the newly created D3D11 content device.
+  // If it fails, we won't use Direct2D.
+  if (XRE_IsContentProcess()) {
+    if (!D3D11Checks::DoesTextureSharingWork(mContentDevice)) {
+      mContentDevice = nullptr;
+      return FeatureStatus::Failed;
+    }
+
+    DebugOnly<bool> ok = ContentAdapterIsParentAdapter(mContentDevice);
+    MOZ_ASSERT(ok);
+  }
+
+  mContentDevice->SetExceptionMode(0);
+
+  RefPtr<ID3D10Multithread> multi;
+  hr = mContentDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
+  if (SUCCEEDED(hr) && multi) {
+    multi->SetMultithreadProtected(TRUE);
+  }
+  return FeatureStatus::Available;
+}
+
+bool
+DeviceManagerD3D11::AttemptD3D11ImageBridgeDeviceCreationHelper(
+  IDXGIAdapter1* aAdapter,
+  HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(GetDXGIAdapter(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+                           D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+                           mFeatureLevels.Elements(), mFeatureLevels.Length(),
+                           D3D11_SDK_VERSION, getter_AddRefs(mImageBridgeDevice), nullptr, nullptr);
+  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+FeatureStatus
+DeviceManagerD3D11::AttemptD3D11ImageBridgeDeviceCreation()
+{
+  HRESULT hr;
+  if (!AttemptD3D11ImageBridgeDeviceCreationHelper(GetDXGIAdapter(), hr)) {
+    gfxCriticalNote << "Recovered from crash while creating a D3D11 image bridge device";
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Image);
+    return FeatureStatus::CrashedInHandler;
+  }
+
+  if (FAILED(hr) || !mImageBridgeDevice) {
+    gfxCriticalNote << "Failed to create a content image bridge device: " << hexa(hr);
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Image);
+    return FeatureStatus::Failed;
+  }
+
+  mImageBridgeDevice->SetExceptionMode(0);
+  if (!D3D11Checks::DoesAlphaTextureSharingWork(mImageBridgeDevice)) {
+    mImageBridgeDevice = nullptr;
+    return FeatureStatus::Failed;
+  }
+
+  if (XRE_IsContentProcess()) {
+    ContentAdapterIsParentAdapter(mImageBridgeDevice);
+  }
+  return FeatureStatus::Available;
+}
+
+bool
+DeviceManagerD3D11::CreateD3D11DecoderDeviceHelper(
+  IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice, HRESULT& aResOut)
+{
+  MOZ_SEH_TRY{
+    aResOut =
+      sD3D11CreateDeviceFn(
+        aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+        D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(aDevice), nullptr, nullptr);
+
+  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::CreateDecoderDevice()
+{
+   if (!sD3D11CreateDeviceFn) {
+    // We should just be on Windows Vista or XP in this case.
+    return nullptr;
+  }
+
+  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
+  if (!adapter) {
+    return nullptr;
+  }
+
+  RefPtr<ID3D11Device> device;
+
+  HRESULT hr;
+  if (!CreateD3D11DecoderDeviceHelper(adapter, device, hr)) {
+    return nullptr;
+  }
+  if (FAILED(hr) || !device || !D3D11Checks::DoesDeviceWork()) {
+    return nullptr;
+  }
+
+  RefPtr<ID3D10Multithread> multi;
+  device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
+
+  multi->SetMultithreadProtected(TRUE);
+  return device;
+}
+
+void
+DeviceManagerD3D11::ResetDevices()
+{
+  MutexAutoLock lock(mDeviceLock);
+
+  mCompositorDevice = nullptr;
+  mContentDevice = nullptr;
+  mImageBridgeDevice = nullptr;
+  Factory::SetDirect3D11Device(nullptr);
+}
+
+bool
+DeviceManagerD3D11::ContentAdapterIsParentAdapter(ID3D11Device* device)
+{
+  DXGI_ADAPTER_DESC desc;
+  if (!D3D11Checks::GetDxgiDesc(device, &desc)) {
+    gfxCriticalNote << "Could not query device DXGI adapter info";
+    return false;
+  }
+
+  const DxgiAdapterDesc& parent =
+    gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
+  if (desc.VendorId != parent.VendorId ||
+      desc.DeviceId != parent.DeviceId ||
+      desc.SubSysId != parent.SubSysId ||
+      desc.AdapterLuid.HighPart != parent.AdapterLuid.HighPart ||
+      desc.AdapterLuid.LowPart != parent.AdapterLuid.LowPart)
+  {
+    gfxCriticalNote << "VendorIDMismatch P " << hexa(parent.VendorId) << " " << hexa(desc.VendorId);
+    return false;
+  }
+
+  return true;
+}
+
+static DeviceResetReason HResultToResetReason(HRESULT hr)
+{
+  switch (hr) {
+  case DXGI_ERROR_DEVICE_HUNG:
+    return DeviceResetReason::HUNG;
+  case DXGI_ERROR_DEVICE_REMOVED:
+    return DeviceResetReason::REMOVED;
+  case DXGI_ERROR_DEVICE_RESET:
+    return DeviceResetReason::RESET;
+  case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+    return DeviceResetReason::DRIVER_ERROR;
+  case DXGI_ERROR_INVALID_CALL:
+    return DeviceResetReason::INVALID_CALL;
+  case E_OUTOFMEMORY:
+    return DeviceResetReason::OUT_OF_MEMORY;
+  default:
+    MOZ_ASSERT(false);
+  }
+  return DeviceResetReason::UNKNOWN;
+}
+
+static inline bool
+DidDeviceReset(RefPtr<ID3D11Device> aDevice, DeviceResetReason* aOutReason)
+{
+  if (!aDevice) {
+    return false;
+  }
+  HRESULT hr = aDevice->GetDeviceRemovedReason();
+  if (hr == S_OK) {
+    return false;
+  }
+
+  *aOutReason = HResultToResetReason(hr);
+  return true;
+}
+
+bool
+DeviceManagerD3D11::GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason)
+{
+  // Note: this can be called off the main thread, so we need to use
+  // our threadsafe getters.
+  if (DidDeviceReset(GetCompositorDevice(), aOutReason) ||
+      DidDeviceReset(GetImageBridgeDevice(), aOutReason) ||
+      DidDeviceReset(GetContentDevice(), aOutReason))
+  {
+    return true;
+  }
+  return false;
+}
+
+void
+DeviceManagerD3D11::DisableD3D11AfterCrash()
+{
+  gfxConfig::Disable(Feature::D3D11_COMPOSITING,
+    FeatureStatus::CrashedInHandler,
+    "Crashed while acquiring a Direct3D11 device",
+    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_CRASH"));
+  ResetDevices();
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetCompositorDevice()
+{
+  MutexAutoLock lock(mDeviceLock);
+  return mCompositorDevice;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetImageBridgeDevice()
+{
+  MutexAutoLock lock(mDeviceLock);
+  return mImageBridgeDevice;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetContentDevice()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  return mContentDevice;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetDeviceForCurrentThread()
+{
+  if (NS_IsMainThread()) {
+    return GetContentDevice();
+  }
+  return GetCompositorDevice();
+}
+
+unsigned
+DeviceManagerD3D11::GetD3D11Version() const
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  if (!mCompositorDevice) {
+    return 0;
+  }
+  return mCompositorDevice->GetFeatureLevel();
+}
+
+bool
+DeviceManagerD3D11::TextureSharingWorks() const
+{
+  return mTextureSharingWorks;
+}
+
+bool
+DeviceManagerD3D11::IsWARP() const
+{
+  return mIsWARP;
+}
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/DeviceManagerD3D11.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
+
+#ifndef mozilla_gfx_thebes_DeviceManagerD3D11_h
+#define mozilla_gfx_thebes_DeviceManagerD3D11_h
+
+#include "gfxPlatform.h"
+#include "gfxTelemetry.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPtr.h"
+#include "nsTArray.h"
+
+#include <windows.h>
+#include <objbase.h>
+
+#include <dxgi.h>
+
+// This header is available in the June 2010 SDK and in the Win8 SDK
+#include <d3dcommon.h>
+// Win 8.0 SDK types we'll need when building using older sdks.
+#if !defined(D3D_FEATURE_LEVEL_11_1) // defined in the 8.0 SDK only
+#define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
+#define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
+#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
+#endif
+
+struct ID3D11Device;
+
+namespace mozilla {
+class ScopedGfxFeatureReporter;
+
+namespace gfx {
+class FeatureState;
+
+class DeviceManagerD3D11 final
+{
+public:
+  static void Init();
+  static void Shutdown();
+
+  DeviceManagerD3D11();
+
+  static DeviceManagerD3D11* Get() {
+    return sInstance;
+  }
+
+  RefPtr<ID3D11Device> GetCompositorDevice();
+  RefPtr<ID3D11Device> GetImageBridgeDevice();
+  RefPtr<ID3D11Device> GetContentDevice();
+  RefPtr<ID3D11Device> GetDeviceForCurrentThread();
+  RefPtr<ID3D11Device> CreateDecoderDevice();
+
+  unsigned GetD3D11Version() const;
+  bool TextureSharingWorks() const;
+  bool IsWARP() const;
+
+  void CreateDevices();
+  void ResetDevices();
+
+  // Call GetDeviceRemovedReason on each device until one returns
+  // a failure.
+  bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason);
+
+private:
+  IDXGIAdapter1 *GetDXGIAdapter();
+
+  bool CanUseD3D11ImageBridge();
+
+  void DisableD3D11AfterCrash();
+
+  void AttemptD3D11DeviceCreation(mozilla::gfx::FeatureState& d3d11);
+  bool AttemptD3D11DeviceCreationHelper(
+      IDXGIAdapter1* aAdapter,
+      RefPtr<ID3D11Device>& aOutDevice,
+      HRESULT& aResOut);
+
+  void AttemptWARPDeviceCreation();
+  bool AttemptWARPDeviceCreationHelper(
+      mozilla::ScopedGfxFeatureReporter& aReporterWARP,
+      RefPtr<ID3D11Device>& aOutDevice,
+      HRESULT& aResOut);
+
+  bool AttemptD3D11ImageBridgeDeviceCreationHelper(
+      IDXGIAdapter1* aAdapter, HRESULT& aResOut);
+  mozilla::gfx::FeatureStatus AttemptD3D11ImageBridgeDeviceCreation();
+
+  mozilla::gfx::FeatureStatus AttemptD3D11ContentDeviceCreation();
+  bool AttemptD3D11ContentDeviceCreationHelper(
+      IDXGIAdapter1* aAdapter, HRESULT& aResOut);
+
+  // Create a D3D11 device to be used for DXVA decoding.
+  bool CreateD3D11DecoderDeviceHelper(
+      IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice,
+      HRESULT& aResOut);
+
+  bool ContentAdapterIsParentAdapter(ID3D11Device* device);
+
+private:
+  static StaticAutoPtr<DeviceManagerD3D11> sInstance;
+
+  mozilla::Mutex mDeviceLock;
+  nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
+  RefPtr<IDXGIAdapter1> mAdapter;
+  RefPtr<ID3D11Device> mCompositorDevice;
+  RefPtr<ID3D11Device> mContentDevice;
+  RefPtr<ID3D11Device> mImageBridgeDevice;
+  mozilla::Atomic<bool> mIsWARP;
+  mozilla::Atomic<bool> mTextureSharingWorks;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // mozilla_gfx_thebes_DeviceManagerD3D11_h
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -21,16 +21,17 @@
 #include "GeckoProfiler.h"
 #include "gfx2DGlue.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/gfx/DrawTargetTiled.h"
 #include <algorithm>
 
 #if XP_WIN
 #include "gfxWindowsPlatform.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 UserDataKey gfxContext::sDontUseAsSourceKey;
 
 
@@ -1237,17 +1238,18 @@ gfxContext::PushNewDT(gfxContentType con
 
   if (!newDT) {
     NS_WARNING("Failed to create DrawTarget of sufficient size.");
     newDT = mDT->CreateSimilarDrawTarget(IntSize(64, 64), format);
 
     if (!newDT) {
       if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()
 #ifdef XP_WIN
-          && !(mDT->GetBackendType() == BackendType::DIRECT2D1_1 && !gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())
+          && !(mDT->GetBackendType() == BackendType::DIRECT2D1_1 &&
+               !DeviceManagerD3D11::Get()->GetContentDevice())
 #endif
           ) {
         // If even this fails.. we're most likely just out of memory!
         NS_ABORT_OOM(BytesPerPixel(format) * 64 * 64);
       }
       newDT = CurrentState().drawTarget;
     }
   }
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -1773,8 +1773,13 @@ gfxFontUtils::IsCffFont(const uint8_t* a
     // this is only called after aFontData has passed basic validation,
     // so we know there is enough data present to allow us to read the version!
     const SFNTHeader *sfntHeader = reinterpret_cast<const SFNTHeader*>(aFontData);
     return (sfntHeader->sfntVersion == TRUETYPE_TAG('O','T','T','O'));
 }
 
 #endif
 
+#undef acceptablePlatform
+#undef isSymbol
+#undef isUVSEncoding
+#undef LOG
+#undef LOG_ENABLED
--- a/gfx/thebes/gfxGlyphExtents.h
+++ b/gfx/thebes/gfxGlyphExtents.h
@@ -10,30 +10,38 @@
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "mozilla/MemoryReporting.h"
 
 class gfxContext;
 struct gfxRect;
 
+namespace mozilla {
+namespace gfx {
+class DrawTarget;
+} // namespace gfx
+} // namespace mozilla
+
 /**
  * This stores glyph bounds information for a particular gfxFont, at
  * a particular appunits-per-dev-pixel ratio (because the compressed glyph
  * width array is stored in appunits).
  * 
  * We store a hashtable from glyph IDs to float bounding rects. For the
  * common case where the glyph has no horizontal left bearing, and no
  * y overflow above the font ascent or below the font descent, and tight
  * bounding boxes are not required, we avoid storing the glyph ID in the hashtable
  * and instead consult an array of 16-bit glyph XMost values (in appunits).
  * This array always has an entry for the font's space glyph --- the width is
  * assumed to be zero.
  */
 class gfxGlyphExtents {
+    typedef mozilla::gfx::DrawTarget DrawTarget;
+
 public:
     explicit gfxGlyphExtents(int32_t aAppUnitsPerDevUnit) :
         mAppUnitsPerDevUnit(aAppUnitsPerDevUnit) {
         MOZ_COUNT_CTOR(gfxGlyphExtents);
     }
     ~gfxGlyphExtents();
 
     enum { INVALID_WIDTH = 0xFFFF };
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -1598,8 +1598,11 @@ gfxPlatformFontList::AddSizeOfExcludingT
 
 void
 gfxPlatformFontList::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
                                             FontListSizes* aSizes) const
 {
     aSizes->mFontListSize += aMallocSizeOf(this);
     AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
 }
+
+#undef LOG
+#undef LOG_ENABLED
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -1427,8 +1427,11 @@ gfxUserFontSet::UserFontCache::Dump()
     printf("userfontcache dump count: %d ========\n", sUserFonts->Count());
     for (auto it = sUserFonts->Iter(); !it.Done(); it.Next()) {
         it.Get()->Dump();
     }
     printf("userfontcache dump ==================\n");
 }
 
 #endif
+
+#undef LOG
+#undef LOG_ENABLED
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -25,17 +25,16 @@
 
 #include "nsIWindowsRegKey.h"
 #include "nsIFile.h"
 #include "plbase64.h"
 #include "nsIXULRuntime.h"
 #include "imgLoader.h"
 
 #include "nsIGfxInfo.h"
-#include "GfxDriverInfo.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "gfxGDIFontList.h"
 #include "gfxGDIFont.h"
 
 #include "mozilla/layers/CompositorThread.h"
 #include "DeviceManagerD3D9.h"
@@ -69,29 +68,25 @@
 
 #include "base/thread.h"
 #include "SurfaceCache.h"
 #include "gfxPrefs.h"
 #include "gfxConfig.h"
 #include "VsyncSource.h"
 #include "DriverCrashGuard.h"
 #include "mozilla/dom/ContentParent.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
+#include "D3D11Checks.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 using namespace mozilla::image;
 
-enum class TelemetryDeviceCode : uint32_t {
-  Content = 0,
-  Image = 1,
-  D2D1 = 2
-};
-
 DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget)
 {
   mDC = nullptr;
   if (aDrawTarget.GetBackendType() == BackendType::CAIRO) {
     cairo_t* ctx = static_cast<cairo_t*>
       (aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
     if (ctx) {
       cairo_surface_t* surf = cairo_get_group_target(ctx);
@@ -332,20 +327,18 @@ public:
   }
 };
 
 NS_IMPL_ISUPPORTS(D3DSharedTexturesReporter, nsIMemoryReporter)
 
 gfxWindowsPlatform::gfxWindowsPlatform()
   : mRenderMode(RENDER_GDI)
   , mDeviceLock("gfxWindowsPlatform.mDeviceLock")
-  , mIsWARP(false)
   , mHasDeviceReset(false)
   , mHasFakeDeviceReset(false)
-  , mCompositorD3D11TextureSharingWorks(false)
   , mHasD3D9DeviceReset(false)
 {
   mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
   mUseClearTypeAlways = UNINITIALIZED_VALUE;
 
   /* 
    * Initialize COM 
    */ 
@@ -353,25 +346,21 @@ gfxWindowsPlatform::gfxWindowsPlatform()
 
   RegisterStrongMemoryReporter(new GfxD2DVramReporter());
   RegisterStrongMemoryReporter(new GPUAdapterReporter());
   RegisterStrongMemoryReporter(new D3DSharedTexturesReporter());
 }
 
 gfxWindowsPlatform::~gfxWindowsPlatform()
 {
+  DeviceManagerD3D11::Shutdown();
   mDeviceManager = nullptr;
-  mD3D11Device = nullptr;
-  mD3D11ContentDevice = nullptr;
-  mD3D11ImageBridgeDevice = nullptr;
 
   mozilla::gfx::Factory::D2DCleanup();
 
-  mAdapter = nullptr;
-
   /* 
    * Uninitialize COM 
    */ 
   CoUninitialize();
 }
 
 static void
 UpdateANGLEConfig()
@@ -390,29 +379,32 @@ gfxWindowsPlatform::InitAcceleration()
   if (IsWin8OrLater()) {
     mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
   }
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
 
+  DeviceManagerD3D11::Init();
+
   InitializeConfig();
   InitializeDevices();
   UpdateANGLEConfig();
   UpdateRenderMode();
 }
 
 bool
 gfxWindowsPlatform::CanUseHardwareVideoDecoding()
 {
-  if (!gfxPrefs::LayersPreferD3D9() && !mCompositorD3D11TextureSharingWorks) {
+  DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
+  if (!gfxPrefs::LayersPreferD3D9() && !dm->TextureSharingWorks()) {
     return false;
   }
-  return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
+  return !dm->IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
 }
 
 bool
 gfxWindowsPlatform::InitDWriteSupport()
 {
   MOZ_ASSERT(!mDWriteFactory && IsVistaOrLater());
 
   mozilla::ScopedGfxFeatureReporter reporter("DWrite");
@@ -448,25 +440,23 @@ gfxWindowsPlatform::HandleDeviceReset()
     return false;
   }
 
   if (!mHasFakeDeviceReset) {
     Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(resetReason));
   }
 
   // Remove devices and adapters.
-  ResetD3D11Devices();
-  mAdapter = nullptr;
+  DeviceManagerD3D11::Get()->ResetDevices();
 
   // Reset local state. Note: we leave feature status variables as-is. They
   // will be recomputed by InitializeDevices().
   mHasDeviceReset = false;
   mHasFakeDeviceReset = false;
   mHasD3D9DeviceReset = false;
-  mCompositorD3D11TextureSharingWorks = false;
   mDeviceResetReason = DeviceResetReason::OK;
 
   imgLoader::NormalLoader()->ClearCache(true);
   imgLoader::NormalLoader()->ClearCache(false);
   imgLoader::PrivateBrowsingLoader()->ClearCache(true);
   imgLoader::PrivateBrowsingLoader()->ClearCache(false);
   gfxAlphaBoxBlur::ShutdownBlurCache();
 
@@ -912,58 +902,23 @@ gfxWindowsPlatform::IsFontFormatSupporte
     if (aFormatFlags != 0) {
         return false;
     }
 
     // no format hint set, need to look at data
     return true;
 }
 
-static DeviceResetReason HResultToResetReason(HRESULT hr)
-{
-  switch (hr) {
-  case DXGI_ERROR_DEVICE_HUNG:
-    return DeviceResetReason::HUNG;
-  case DXGI_ERROR_DEVICE_REMOVED:
-    return DeviceResetReason::REMOVED;
-  case DXGI_ERROR_DEVICE_RESET:
-    return DeviceResetReason::RESET;
-  case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
-    return DeviceResetReason::DRIVER_ERROR;
-  case DXGI_ERROR_INVALID_CALL:
-    return DeviceResetReason::INVALID_CALL;
-  case E_OUTOFMEMORY:
-    return DeviceResetReason::OUT_OF_MEMORY;
-  default:
-    MOZ_ASSERT(false);
-  }
-  return DeviceResetReason::UNKNOWN;
-}
-
 void
 gfxWindowsPlatform::CompositorUpdated()
 {
   ForceDeviceReset(ForcedDeviceResetReason::COMPOSITOR_UPDATED);
   UpdateRenderMode();
 }
 
-bool
-gfxWindowsPlatform::IsDeviceReset(HRESULT hr, DeviceResetReason* aResetReason)
-{
-  if (hr != S_OK) {
-    mDeviceResetReason = HResultToResetReason(hr);
-    mHasDeviceReset = true;
-    if (aResetReason) {
-      *aResetReason = mDeviceResetReason;
-    }
-    return true;
-  }
-  return false;
-}
-
 void
 gfxWindowsPlatform::TestDeviceReset(DeviceResetReason aReason)
 {
   if (mHasDeviceReset) {
     return;
   }
   mHasDeviceReset = true;
   mHasFakeDeviceReset = true;
@@ -978,28 +933,24 @@ gfxWindowsPlatform::DidRenderingDeviceRe
       *aResetReason = mDeviceResetReason;
     }
     return true;
   }
   if (aResetReason) {
     *aResetReason = DeviceResetReason::OK;
   }
 
-  if (mD3D11Device) {
-    HRESULT hr = mD3D11Device->GetDeviceRemovedReason();
-    if (IsDeviceReset(hr, aResetReason)) {
-      return true;
+  if (DeviceManagerD3D11::Get()->GetAnyDeviceRemovedReason(&mDeviceResetReason)) {
+    mHasDeviceReset = true;
+    if (aResetReason) {
+      *aResetReason = mDeviceResetReason;
     }
+    return true;
   }
-  if (mD3D11ContentDevice) {
-    HRESULT hr = mD3D11ContentDevice->GetDeviceRemovedReason();
-    if (IsDeviceReset(hr, aResetReason)) {
-      return true;
-    }
-  }
+
   if (mHasD3D9DeviceReset) {
     return true;
   }
   if (XRE_IsParentProcess() && gfxPrefs::DeviceResetForTesting()) {
     TestDeviceReset((DeviceResetReason)gfxPrefs::DeviceResetForTesting());
     if (aResetReason) {
       *aResetReason = mDeviceResetReason;
     }
@@ -1407,48 +1358,16 @@ gfxWindowsPlatform::GetD3D9DeviceManager
     }
   }
 
   MutexAutoLock lock(mDeviceLock);
   result = mDeviceManager;
   return result.forget();
 }
 
-bool
-gfxWindowsPlatform::GetD3D11Device(RefPtr<ID3D11Device>* aOutDevice)
-{
-  MutexAutoLock lock(mDeviceLock);
-  *aOutDevice = mD3D11Device;
-  return !!mD3D11Device;
-}
-
-ID3D11Device*
-gfxWindowsPlatform::GetD3D11ContentDevice()
-{
-  return mD3D11ContentDevice;
-}
-
-bool
-gfxWindowsPlatform::GetD3D11ImageBridgeDevice(RefPtr<ID3D11Device>* aOutDevice)
-{
-  MutexAutoLock lock(mDeviceLock);
-  *aOutDevice = mD3D11ImageBridgeDevice;
-  return !!mD3D11ImageBridgeDevice;
-}
-
-bool
-gfxWindowsPlatform::GetD3D11DeviceForCurrentThread(RefPtr<ID3D11Device>* aOutDevice)
-{
-  if (NS_IsMainThread()) {
-    *aOutDevice = mD3D11ContentDevice;
-    return !!mD3D11ContentDevice;
-  }
-  return GetD3D11ImageBridgeDevice(aOutDevice);
-}
-
 ReadbackManagerD3D11*
 gfxWindowsPlatform::GetReadbackManager()
 {
   if (!mD3D11ReadbackManager) {
     mD3D11ReadbackManager = new ReadbackManagerD3D11();
   }
 
   return mD3D11ReadbackManager;
@@ -1466,448 +1385,16 @@ gfxWindowsPlatform::IsOptimus()
             knowIsOptimus = 1;
         } else {
             knowIsOptimus = 0;
         }
     }
     return knowIsOptimus;
 }
 
-IDXGIAdapter1*
-gfxWindowsPlatform::GetDXGIAdapter()
-{
-  if (mAdapter) {
-    return mAdapter;
-  }
-
-  nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
-  decltype(CreateDXGIFactory1)* createDXGIFactory1 = (decltype(CreateDXGIFactory1)*)
-    GetProcAddress(dxgiModule, "CreateDXGIFactory1");
-
-  if (!createDXGIFactory1) {
-    return nullptr;
-  }
-
-  // Try to use a DXGI 1.1 adapter in order to share resources
-  // across processes.
-  RefPtr<IDXGIFactory1> factory1;
-  HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
-                                  getter_AddRefs(factory1));
-  if (FAILED(hr) || !factory1) {
-    // This seems to happen with some people running the iZ3D driver.
-    // They won't get acceleration.
-    return nullptr;
-  }
-
-  if (!XRE_IsContentProcess()) {
-    // In the parent process, we pick the first adapter.
-    if (FAILED(factory1->EnumAdapters1(0, getter_AddRefs(mAdapter)))) {
-      return nullptr;
-    }
-  } else {
-    const DxgiAdapterDesc& parent = GetParentDevicePrefs().adapter();
-
-    // In the child process, we search for the adapter that matches the parent
-    // process. The first adapter can be mismatched on dual-GPU systems.
-    for (UINT index = 0; ; index++) {
-      RefPtr<IDXGIAdapter1> adapter;
-      if (FAILED(factory1->EnumAdapters1(index, getter_AddRefs(adapter)))) {
-        break;
-      }
-
-      DXGI_ADAPTER_DESC desc;
-      if (SUCCEEDED(adapter->GetDesc(&desc)) &&
-          desc.AdapterLuid.HighPart == parent.AdapterLuid.HighPart &&
-          desc.AdapterLuid.LowPart == parent.AdapterLuid.LowPart &&
-          desc.VendorId == parent.VendorId &&
-          desc.DeviceId == parent.DeviceId)
-      {
-        mAdapter = adapter.forget();
-        break;
-      }
-    }
-  }
-
-  if (!mAdapter) {
-    return nullptr;
-  }
-
-  // We leak this module everywhere, we might as well do so here as well.
-  dxgiModule.disown();
-  return mAdapter;
-}
-
-bool DoesD3D11DeviceWork()
-{
-  static bool checked = false;
-  static bool result = false;
-
-  if (checked)
-      return result;
-  checked = true;
-
-  if (gfxPrefs::Direct2DForceEnabled() ||
-      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
-  {
-    result = true;
-    return true;
-  }
-
-  if (GetModuleHandleW(L"igd10umd32.dll")) {
-    const wchar_t* checkModules[] = {L"dlumd32.dll",
-                                     L"dlumd11.dll",
-                                     L"dlumd10.dll"};
-    for (int i=0; i<PR_ARRAY_SIZE(checkModules); i+=1) {
-      if (GetModuleHandleW(checkModules[i])) {
-        nsString displayLinkModuleVersionString;
-        gfxWindowsPlatform::GetDLLVersion(checkModules[i],
-                                          displayLinkModuleVersionString);
-        uint64_t displayLinkModuleVersion;
-        if (!ParseDriverVersion(displayLinkModuleVersionString,
-                                &displayLinkModuleVersion)) {
-          gfxCriticalError() << "DisplayLink: could not parse version "
-                             << checkModules[i];
-          return false;
-        }
-        if (displayLinkModuleVersion <= V(8,6,1,36484)) {
-          gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DisplayLink: too old version " << displayLinkModuleVersionString.get();
-          return false;
-        }
-      }
-    }
-  }
-  result = true;
-  return true;
-}
-
-static bool
-GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out)
-{
-  RefPtr<IDXGIDevice> dxgiDevice;
-  HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice));
-  if (FAILED(hr)) {
-    return false;
-  }
-
-  RefPtr<IDXGIAdapter> dxgiAdapter;
-  if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
-    return false;
-  }
-
-  return SUCCEEDED(dxgiAdapter->GetDesc(out));
-}
-
-static void
-CheckForAdapterMismatch(ID3D11Device *device)
-{
-  DXGI_ADAPTER_DESC desc;
-  PodZero(&desc);
-  GetDxgiDesc(device, &desc);
-
-  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-  nsString vendorID;
-  gfxInfo->GetAdapterVendorID(vendorID);
-  nsresult ec;
-  int32_t vendor = vendorID.ToInteger(&ec, 16);
-  if (vendor != desc.VendorId) {
-      gfxCriticalNote << "VendorIDMismatch V " << hexa(vendor) << " " << hexa(desc.VendorId);
-  }
-}
-
-bool DoesRenderTargetViewNeedsRecreating(ID3D11Device *device)
-{
-    bool result = false;
-    // CreateTexture2D is known to crash on lower feature levels, see bugs
-    // 1170211 and 1089413.
-    if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
-        return true;
-    }
-
-    RefPtr<ID3D11DeviceContext> deviceContext;
-    device->GetImmediateContext(getter_AddRefs(deviceContext));
-    int backbufferWidth = 32; int backbufferHeight = 32;
-    RefPtr<ID3D11Texture2D> offscreenTexture;
-    RefPtr<IDXGIKeyedMutex> keyedMutex;
-
-    D3D11_TEXTURE2D_DESC offscreenTextureDesc = { 0 };
-    offscreenTextureDesc.Width = backbufferWidth;
-    offscreenTextureDesc.Height = backbufferHeight;
-    offscreenTextureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-    offscreenTextureDesc.MipLevels = 0;
-    offscreenTextureDesc.ArraySize = 1;
-    offscreenTextureDesc.SampleDesc.Count = 1;
-    offscreenTextureDesc.SampleDesc.Quality = 0;
-    offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
-    offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
-    offscreenTextureDesc.CPUAccessFlags = 0;
-    offscreenTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
-
-    HRESULT hr = device->CreateTexture2D(&offscreenTextureDesc, NULL, getter_AddRefs(offscreenTexture));
-    if (FAILED(hr)) {
-        gfxCriticalNote << "DoesRecreatingCreateTexture2DFail";
-        return false;
-    }
-
-    hr = offscreenTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(keyedMutex));
-    if (FAILED(hr)) {
-        gfxCriticalNote << "DoesRecreatingKeyedMutexFailed";
-        return false;
-    }
-    D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
-    offscreenRTVDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-    offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
-    offscreenRTVDesc.Texture2D.MipSlice = 0;
-
-    RefPtr<ID3D11RenderTargetView> offscreenRTView;
-    hr = device->CreateRenderTargetView(offscreenTexture, &offscreenRTVDesc, getter_AddRefs(offscreenRTView));
-    if (FAILED(hr)) {
-        gfxCriticalNote << "DoesRecreatingCreateRenderTargetViewFailed";
-        return false;
-    }
-
-    // Acquire and clear
-    keyedMutex->AcquireSync(0, INFINITE);
-    FLOAT color1[4] = { 1, 1, 0.5, 1 };
-    deviceContext->ClearRenderTargetView(offscreenRTView, color1);
-    keyedMutex->ReleaseSync(0);
-
-
-    keyedMutex->AcquireSync(0, INFINITE);
-    FLOAT color2[4] = { 1, 1, 0, 1 };
-
-    deviceContext->ClearRenderTargetView(offscreenRTView, color2);
-    D3D11_TEXTURE2D_DESC desc;
-
-    offscreenTexture->GetDesc(&desc);
-    desc.Usage = D3D11_USAGE_STAGING;
-    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
-    desc.MiscFlags = 0;
-    desc.BindFlags = 0;
-    ID3D11Texture2D* cpuTexture;
-    hr = device->CreateTexture2D(&desc, NULL, &cpuTexture);
-    if (FAILED(hr)) {
-        gfxCriticalNote << "DoesRecreatingCreateCPUTextureFailed";
-        return false;
-    }
-
-    deviceContext->CopyResource(cpuTexture, offscreenTexture);
-
-    D3D11_MAPPED_SUBRESOURCE mapped;
-    hr = deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
-    if (FAILED(hr)) {
-        gfxCriticalNote << "DoesRecreatingMapFailed " << hexa(hr);
-        return false;
-    }
-    int resultColor = *(int*)mapped.pData;
-    deviceContext->Unmap(cpuTexture, 0);
-    cpuTexture->Release();
-
-    // XXX on some drivers resultColor will not have changed to
-    // match the clear
-    if (resultColor != 0xffffff00) {
-        gfxCriticalNote << "RenderTargetViewNeedsRecreating";
-        result = true;
-    }
-
-    keyedMutex->ReleaseSync(0);
-
-    // It seems like this may only happen when we're using the NVIDIA gpu
-    CheckForAdapterMismatch(device);
-    return result;
-}
-
-static bool TryCreateTexture2D(ID3D11Device *device,
-                               D3D11_TEXTURE2D_DESC* desc,
-                               D3D11_SUBRESOURCE_DATA* data,
-                               RefPtr<ID3D11Texture2D>& texture)
-{
-  // Older Intel driver version (see bug 1221348 for version #s) crash when
-  // creating a texture with shared keyed mutex and data.
-  MOZ_SEH_TRY {
-    return !FAILED(device->CreateTexture2D(desc, data, getter_AddRefs(texture)));
-  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
-    // For now we want to aggregrate all the crash signature to a known crash.
-    gfxDevCrash(LogReason::TextureCreation) << "Crash creating texture. See bug 1221348.";
-    return false;
-  }
-}
-
-
-// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
-// with E_OUTOFMEMORY.
-bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT format, UINT bindflags)
-{
-  // CreateTexture2D is known to crash on lower feature levels, see bugs
-  // 1170211 and 1089413.
-  if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
-    return false;
-  }
-
-  if (gfxPrefs::Direct2DForceEnabled() ||
-      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
-  {
-    return true;
-  }
-
-  if (GetModuleHandleW(L"atidxx32.dll")) {
-    nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-    if (gfxInfo) {
-      nsString vendorID, vendorID2;
-      gfxInfo->GetAdapterVendorID(vendorID);
-      gfxInfo->GetAdapterVendorID2(vendorID2);
-      if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
-        if (!gfxPrefs::LayersAMDSwitchableGfxEnabled()) {
-          return false;
-        }
-        gfxCriticalError(CriticalLog::DefaultOptions(false)) << "PossiblyBrokenSurfaceSharing_UnexpectedAMDGPU";
-      }
-    }
-  }
-
-  RefPtr<ID3D11Texture2D> texture;
-  D3D11_TEXTURE2D_DESC desc;
-  const int texture_size = 32;
-  desc.Width = texture_size;
-  desc.Height = texture_size;
-  desc.MipLevels = 1;
-  desc.ArraySize = 1;
-  desc.Format = format;
-  desc.SampleDesc.Count = 1;
-  desc.SampleDesc.Quality = 0;
-  desc.Usage = D3D11_USAGE_DEFAULT;
-  desc.CPUAccessFlags = 0;
-  desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
-  desc.BindFlags = bindflags;
-
-  uint32_t color[texture_size * texture_size];
-  for (size_t i = 0; i < sizeof(color)/sizeof(color[0]); i++) {
-    color[i] = 0xff00ffff;
-  }
-  // XXX If we pass the data directly at texture creation time we
-  //     get a crash on Intel 8.5.10.[18xx-1994] drivers.
-  //     We can work around this issue by doing UpdateSubresource.
-  if (!TryCreateTexture2D(device, &desc, nullptr, texture)) {
-    gfxCriticalNote << "DoesD3D11TextureSharingWork_TryCreateTextureFailure";
-    return false;
-  }
-
-  RefPtr<IDXGIKeyedMutex> sourceSharedMutex;
-  texture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sourceSharedMutex));
-  if (FAILED(sourceSharedMutex->AcquireSync(0, 30*1000))) {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceMutexTimeout";
-    // only wait for 30 seconds
-    return false;
-  }
-
-  RefPtr<ID3D11DeviceContext> deviceContext;
-  device->GetImmediateContext(getter_AddRefs(deviceContext));
-
-  int stride = texture_size * 4;
-  deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride, stride * texture_size);
-
-  if (FAILED(sourceSharedMutex->ReleaseSync(0))) {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceReleaseSyncTimeout";
-    return false;
-  }
-
-  HANDLE shareHandle;
-  RefPtr<IDXGIResource> otherResource;
-  if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
-                                     getter_AddRefs(otherResource))))
-  {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetResourceFailure";
-    return false;
-  }
-
-  if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
-    return false;
-  }
-
-  RefPtr<ID3D11Resource> sharedResource;
-  RefPtr<ID3D11Texture2D> sharedTexture;
-  if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
-                                        getter_AddRefs(sharedResource))))
-  {
-    gfxCriticalError(CriticalLog::DefaultOptions(false)) << "OpenSharedResource failed for format " << format;
-    return false;
-  }
-
-  if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
-                                            getter_AddRefs(sharedTexture))))
-  {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
-    return false;
-  }
-
-  // create a staging texture for readback
-  RefPtr<ID3D11Texture2D> cpuTexture;
-  desc.Usage = D3D11_USAGE_STAGING;
-  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
-  desc.MiscFlags = 0;
-  desc.BindFlags = 0;
-  if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(cpuTexture)))) {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_CreateTextureFailure";
-    return false;
-  }
-
-  RefPtr<IDXGIKeyedMutex> sharedMutex;
-  sharedResource->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sharedMutex));
-  if (FAILED(sharedMutex->AcquireSync(0, 30*1000))) {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_AcquireSyncTimeout";
-    // only wait for 30 seconds
-    return false;
-  }
-
-  // Copy to the cpu texture so that we can readback
-  deviceContext->CopyResource(cpuTexture, sharedTexture);
-
-  D3D11_MAPPED_SUBRESOURCE mapped;
-  int resultColor = 0;
-  if (SUCCEEDED(deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped))) {
-    // read the texture
-    resultColor = *(int*)mapped.pData;
-    deviceContext->Unmap(cpuTexture, 0);
-  } else {
-    gfxCriticalError() << "DoesD3D11TextureSharingWork_MapFailed";
-    return false;
-  }
-
-  sharedMutex->ReleaseSync(0);
-
-  // check that the color we put in is the color we get out
-  if (resultColor != color[0]) {
-    // Shared surfaces seem to be broken on dual AMD & Intel HW when using the
-    // AMD GPU
-    gfxCriticalNote << "DoesD3D11TextureSharingWork_ColorMismatch";
-    return false;
-  }
-
-  RefPtr<ID3D11ShaderResourceView> sharedView;
-
-  // This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
-  if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, getter_AddRefs(sharedView)))) {
-    gfxCriticalNote << "CreateShaderResourceView failed for format" << format;
-    return false;
-  }
-
-  return true;
-}
-
-bool DoesD3D11TextureSharingWork(ID3D11Device *device)
-{
-  return DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
-}
-
-bool DoesD3D11AlphaTextureSharingWork(ID3D11Device *device)
-{
-  return DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_R8_UNORM, D3D11_BIND_SHADER_RESOURCE);
-}
-
-
 static inline bool
 IsWARPStable()
 {
   // It seems like nvdxgiwrap makes a mess of WARP. See bug 1154703.
   if (!IsWin8OrLater() || GetModuleHandleA("nvdxgiwrap.dll")) {
     return false;
   }
   return true;
@@ -2057,306 +1544,30 @@ gfxWindowsPlatform::UpdateDeviceInitData
     "Disabled by parent process");
 
 
   InitializeANGLEConfig();
 
   return true;
 }
 
-// We don't have access to the D3D11CreateDevice type in gfxWindowsPlatform.h,
-// since it doesn't include d3d11.h, so we use a static here. It should only
-// be used within InitializeD3D11.
-decltype(D3D11CreateDevice)* sD3D11CreateDeviceFn = nullptr;
-
-bool
-gfxWindowsPlatform::AttemptD3D11DeviceCreationHelper(
-  IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aOutDevice, HRESULT& aResOut)
-{
-  MOZ_SEH_TRY {
-    aResOut =
-      sD3D11CreateDeviceFn(
-        aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
-        // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
-        // to prevent bug 1092260. IE 11 also uses this flag.
-        D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
-        mFeatureLevels.Elements(), mFeatureLevels.Length(),
-        D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
-  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
-    return false;
-  }
-  return true;
-}
-
-void
-gfxWindowsPlatform::AttemptD3D11DeviceCreation(FeatureState& d3d11)
-{
-  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
-  if (!adapter) {
-    d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI"));
-    return;
-  }
-
-  HRESULT hr;
-  RefPtr<ID3D11Device> device;
-  if (!AttemptD3D11DeviceCreationHelper(adapter, device, hr)) {
-    gfxCriticalError() << "Crash during D3D11 device creation";
-    d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1"));
-    return;
-  }
-
-  if (FAILED(hr) || !device) {
-    gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr);
-    d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2"));
-    return;
-  }
-  if (!DoesD3D11DeviceWork()) {
-    d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN"));
-    return;
-  }
-
-  {
-    MutexAutoLock lock(mDeviceLock);
-    mD3D11Device = device;
-  }
-
-  // Only test this when not using WARP since it can fail and cause
-  // GetDeviceRemovedReason to return weird values.
-  mCompositorD3D11TextureSharingWorks = ::DoesD3D11TextureSharingWork(mD3D11Device);
-
-  if (!mCompositorD3D11TextureSharingWorks) {
-    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
-                         FeatureStatus::Broken,
-                         "Texture sharing doesn't work");
-  }
-
-  if (DoesRenderTargetViewNeedsRecreating(mD3D11Device)) {
-    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
-                         FeatureStatus::Broken,
-                         "RenderTargetViews need recreating");
-  }
-
-  mD3D11Device->SetExceptionMode(0);
-  mIsWARP = false;
-}
-
-bool
-gfxWindowsPlatform::AttemptWARPDeviceCreationHelper(
-  ScopedGfxFeatureReporter& aReporterWARP,
-  RefPtr<ID3D11Device>& aOutDevice,
-  HRESULT& aResOut)
-{
-  MOZ_SEH_TRY {
-    aResOut =
-      sD3D11CreateDeviceFn(
-        nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
-        // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
-        // to prevent bug 1092260. IE 11 also uses this flag.
-        D3D11_CREATE_DEVICE_BGRA_SUPPORT,
-        mFeatureLevels.Elements(), mFeatureLevels.Length(),
-        D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
-
-    aReporterWARP.SetSuccessful();
-  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
-    return false;
-  }
-  return true;
-}
-
-void
-gfxWindowsPlatform::AttemptWARPDeviceCreation()
-{
-  ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
-  FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
-
-  HRESULT hr;
-  RefPtr<ID3D11Device> device;
-  if (!AttemptWARPDeviceCreationHelper(reporterWARP, device, hr)) {
-    gfxCriticalError() << "Exception occurred initializing WARP D3D11 device!";
-    d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed creating a D3D11 WARP device",
-                     NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE"));
-    return;
-  }
-
-  if (FAILED(hr) || !device) {
-    // This should always succeed... in theory.
-    gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr);
-    d3d11.SetFailed(FeatureStatus::Failed, "Failed to create a D3D11 WARP device",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE2"));
-    return;
-  }
-
-  {
-    MutexAutoLock lock(mDeviceLock);
-    mD3D11Device = device;
-  }
-
-  // Only test for texture sharing on Windows 8 since it puts the device into
-  // an unusable state if used on Windows 7
-  if (IsWin8OrLater()) {
-    mCompositorD3D11TextureSharingWorks = ::DoesD3D11TextureSharingWork(mD3D11Device);
-  }
-  mD3D11Device->SetExceptionMode(0);
-  mIsWARP = true;
-}
-
-bool
-gfxWindowsPlatform::ContentAdapterIsParentAdapter(ID3D11Device* device)
-{
-  DXGI_ADAPTER_DESC desc;
-  if (!GetDxgiDesc(device, &desc)) {
-    gfxCriticalNote << "Could not query device DXGI adapter info";
-    return false;
-  }
-
-  const DxgiAdapterDesc& parent = GetParentDevicePrefs().adapter();
-  if (desc.VendorId != parent.VendorId ||
-      desc.DeviceId != parent.DeviceId ||
-      desc.SubSysId != parent.SubSysId ||
-      desc.AdapterLuid.HighPart != parent.AdapterLuid.HighPart ||
-      desc.AdapterLuid.LowPart != parent.AdapterLuid.LowPart)
-  {
-    gfxCriticalNote << "VendorIDMismatch P " << hexa(parent.VendorId) << " " << hexa(desc.VendorId);
-    return false;
-  }
-
-  return true;
-}
-
-static void
-RecordContentDeviceFailure(TelemetryDeviceCode aDevice)
+/* static */ void
+gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode aDevice)
 {
   // If the parent process fails to acquire a device, we record this
   // normally as part of the environment. The exceptional case we're
   // looking for here is when the parent process successfully acquires
   // a device, but the content process fails to acquire the same device.
   // This would not normally be displayed in about:support.
   if (!XRE_IsContentProcess()) {
     return;
   }
   Telemetry::Accumulate(Telemetry::GFX_CONTENT_FAILED_TO_ACQUIRE_DEVICE, uint32_t(aDevice));
 }
 
-bool
-gfxWindowsPlatform::AttemptD3D11ContentDeviceCreationHelper(
-  IDXGIAdapter1* aAdapter, HRESULT& aResOut)
-{
-  MOZ_SEH_TRY {
-    aResOut =
-      sD3D11CreateDeviceFn(
-        aAdapter, mIsWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN,
-        nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
-        mFeatureLevels.Elements(), mFeatureLevels.Length(),
-        D3D11_SDK_VERSION, getter_AddRefs(mD3D11ContentDevice), nullptr, nullptr);
-
-  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
-    return false;
-  }
-  return true;
-}
-
-FeatureStatus
-gfxWindowsPlatform::AttemptD3D11ContentDeviceCreation()
-{
-  RefPtr<IDXGIAdapter1> adapter;
-  if (!mIsWARP) {
-    adapter = GetDXGIAdapter();
-    if (!adapter) {
-      return FeatureStatus::Unavailable;
-    }
-  }
-
-  HRESULT hr;
-  if (!AttemptD3D11ContentDeviceCreationHelper(adapter, hr)) {
-    gfxCriticalNote << "Recovered from crash while creating a D3D11 content device";
-    RecordContentDeviceFailure(TelemetryDeviceCode::Content);
-    return FeatureStatus::CrashedInHandler;
-  }
-
-  if (FAILED(hr) || !mD3D11ContentDevice) {
-    gfxCriticalNote << "Failed to create a D3D11 content device: " << hexa(hr);
-    RecordContentDeviceFailure(TelemetryDeviceCode::Content);
-    return FeatureStatus::Failed;
-  }
-
-  // InitializeD2D() will abort early if the compositor device did not support
-  // texture sharing. If we're in the content process, we can't rely on the
-  // parent device alone: some systems have dual GPUs that are capable of
-  // binding the parent and child processes to different GPUs. As a safety net,
-  // we re-check texture sharing against the newly created D3D11 content device.
-  // If it fails, we won't use Direct2D.
-  if (XRE_IsContentProcess()) {
-    if (!DoesD3D11TextureSharingWork(mD3D11ContentDevice)) {
-      mD3D11ContentDevice = nullptr;
-      return FeatureStatus::Failed;
-    }
-
-    DebugOnly<bool> ok = ContentAdapterIsParentAdapter(mD3D11ContentDevice);
-    MOZ_ASSERT(ok);
-  }
-
-  mD3D11ContentDevice->SetExceptionMode(0);
-
-  RefPtr<ID3D10Multithread> multi;
-  hr = mD3D11ContentDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
-  if (SUCCEEDED(hr) && multi) {
-    multi->SetMultithreadProtected(TRUE);
-  }
-  return FeatureStatus::Available;
-}
-
-bool
-gfxWindowsPlatform::AttemptD3D11ImageBridgeDeviceCreationHelper(
-  IDXGIAdapter1* aAdapter,
-  HRESULT& aResOut)
-{
-  MOZ_SEH_TRY {
-    aResOut =
-      sD3D11CreateDeviceFn(GetDXGIAdapter(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
-                           D3D11_CREATE_DEVICE_BGRA_SUPPORT,
-                           mFeatureLevels.Elements(), mFeatureLevels.Length(),
-                           D3D11_SDK_VERSION, getter_AddRefs(mD3D11ImageBridgeDevice), nullptr, nullptr);
-  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
-    return false;
-  }
-  return true;
-}
-
-FeatureStatus
-gfxWindowsPlatform::AttemptD3D11ImageBridgeDeviceCreation()
-{
-  HRESULT hr;
-  if (!AttemptD3D11ImageBridgeDeviceCreationHelper(GetDXGIAdapter(), hr)) {
-    gfxCriticalNote << "Recovered from crash while creating a D3D11 image bridge device";
-    RecordContentDeviceFailure(TelemetryDeviceCode::Image);
-    return FeatureStatus::CrashedInHandler;
-  }
-
-  if (FAILED(hr) || !mD3D11ImageBridgeDevice) {
-    gfxCriticalNote << "Failed to create a content image bridge device: " << hexa(hr);
-    RecordContentDeviceFailure(TelemetryDeviceCode::Image);
-    return FeatureStatus::Failed;
-  }
-
-  mD3D11ImageBridgeDevice->SetExceptionMode(0);
-  if (!DoesD3D11AlphaTextureSharingWork(mD3D11ImageBridgeDevice)) {
-    mD3D11ImageBridgeDevice = nullptr;
-    return FeatureStatus::Failed;
-  }
-
-  if (XRE_IsContentProcess()) {
-    ContentAdapterIsParentAdapter(mD3D11ImageBridgeDevice);
-  }
-  return FeatureStatus::Available;
-}
-
 void
 gfxWindowsPlatform::InitializeDevices()
 {
   // Ask the parent process for an updated list of which devices to create.
   UpdateDeviceInitData();
 
   // If acceleration is disabled, we refuse to initialize anything.
   if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
@@ -2393,140 +1604,31 @@ gfxWindowsPlatform::InitializeDevices()
     // forced, we'll let them have it, as unsupported configuration.
     if (gfxPrefs::DirectWriteFontRenderingForceEnabled() && !mDWriteFactory) {
       gfxCriticalNote << "Attempting DWrite without D2D support";
       InitDWriteSupport();
     }
   }
 }
 
-bool
-gfxWindowsPlatform::CanUseD3D11ImageBridge()
-{
-  if (XRE_IsContentProcess()) {
-    if (!GetParentDevicePrefs().useD3D11ImageBridge()) {
-      return false;
-    }
-  }
-  return !mIsWARP;
-}
-
 void
 gfxWindowsPlatform::InitializeD3D11()
 {
   // This function attempts to initialize our D3D11 devices, if the hardware
   // is not blacklisted for D3D11 layers. This first attempt will try to create
   // a hardware accelerated device. If this creation fails or the hardware is
   // blacklisted, then this function will abort if WARP is disabled, causing us
   // to fallback to D3D9 or Basic layers. If WARP is not disabled it will use
   // a WARP device which should always be available on Windows 7 and higher.
-
-  // Check if D3D11 is supported on this hardware.
   FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
   if (!d3d11.IsEnabled()) {
     return;
   }
 
-  // Check if D3D11 is available on this system.
-  nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll"));
-  sD3D11CreateDeviceFn =
-    (decltype(D3D11CreateDevice)*)GetProcAddress(d3d11Module, "D3D11CreateDevice");
-  if (!sD3D11CreateDeviceFn) {
-    // We should just be on Windows Vista or XP in this case.
-    d3d11.SetFailed(FeatureStatus::Unavailable, "Direct3D11 not available on this computer",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_LIB"));
-    return;
-  }
-
-  // Check if a failure was injected for testing.
-  if (gfxPrefs::DeviceFailForTesting()) {
-    d3d11.SetFailed(FeatureStatus::Failed, "Direct3D11 device failure simulated by preference",
-                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_SIM"));
-    return;
-  }
-
-  if (XRE_IsParentProcess()) {
-    if (!gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
-      AttemptD3D11DeviceCreation(d3d11);
-      if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
-        return;
-      }
-
-      // If we failed to get a device, but WARP is allowed and might work,
-      // re-enable D3D11 and switch to WARP.
-      if (!mD3D11Device && IsWARPStable() && !gfxPrefs::LayersD3D11DisableWARP()) {
-        gfxConfig::Reenable(Feature::D3D11_COMPOSITING, Fallback::USE_D3D11_WARP_COMPOSITOR);
-      }
-    }
-
-    // If that failed, see if we can use WARP.
-    if (gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
-      MOZ_ASSERT(d3d11.IsEnabled());
-      MOZ_ASSERT(!mD3D11Device);
-      MOZ_ASSERT(IsWARPStable() || gfxPrefs::LayersD3D11ForceWARP());
-
-      AttemptWARPDeviceCreation();
-      if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
-        return;
-      }
-    }
-
-    // If we still have no device by now, exit.
-    if (!mD3D11Device) {
-      MOZ_ASSERT(!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING));
-      return;
-    }
-
-    // Either device creation function should have returned Available.
-    MOZ_ASSERT(d3d11.IsEnabled());
-  } else {
-    // Child processes do not need a compositor, but they do need to know
-    // whether the parent process is using WARP and whether or not texture
-    // sharing works.
-    mIsWARP = gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR);
-    mCompositorD3D11TextureSharingWorks = GetParentDevicePrefs().d3d11TextureSharingWorks();
-  }
-
-  if (CanUseD3D11ImageBridge()) {
-    if (AttemptD3D11ImageBridgeDeviceCreation() == FeatureStatus::CrashedInHandler) {
-      DisableD3D11AfterCrash();
-      return;
-    }
-  }
-
-  if (AttemptD3D11ContentDeviceCreation() == FeatureStatus::CrashedInHandler) {
-    DisableD3D11AfterCrash();
-    return;
-  }
-
-  // We leak these everywhere and we need them our entire runtime anyway, let's
-  // leak it here as well. We keep the pointer to sD3D11CreateDeviceFn around
-  // as well for D2D1 and device resets.
-  d3d11Module.disown();
-}
-
-void
-gfxWindowsPlatform::DisableD3D11AfterCrash()
-{
-  gfxConfig::Disable(Feature::D3D11_COMPOSITING,
-    FeatureStatus::CrashedInHandler,
-    "Crashed while acquiring a Direct3D11 device",
-    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_CRASH"));
-  ResetD3D11Devices();
-}
-
-void
-gfxWindowsPlatform::ResetD3D11Devices()
-{
-  MutexAutoLock lock(mDeviceLock);
-
-  mD3D11Device = nullptr;
-  mD3D11ContentDevice = nullptr;
-  mD3D11ImageBridgeDevice = nullptr;
-  Factory::SetDirect3D11Device(nullptr);
+  DeviceManagerD3D11::Get()->CreateDevices();
 }
 
 void
 gfxWindowsPlatform::InitializeD2DConfig()
 {
   FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D);
 
   if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
@@ -2558,116 +1660,68 @@ gfxWindowsPlatform::InitializeD2DConfig(
 
 void
 gfxWindowsPlatform::InitializeD2D()
 {
   ScopedGfxFeatureReporter d2d1_1("D2D1.1");
 
   FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D);
 
+  DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
+
   // We don't know this value ahead of time, but the user can force-override
   // it, so we use Disable instead of SetFailed.
-  if (mIsWARP) {
+  if (dm->IsWARP()) {
     d2d1.Disable(FeatureStatus::Blocked, "Direct2D is not compatible with Direct3D11 WARP",
                  NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_WARP_BLOCK"));
   }
 
   // If we pass all the initial checks, we can proceed to runtime decisions.
   if (!d2d1.IsEnabled()) {
     return;
   }
 
   if (!Factory::SupportsD2D1()) {
     d2d1.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a Direct2D 1.1 factory",
                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_FACTORY"));
     return;
   }
 
-  if (!mD3D11ContentDevice) {
+  if (!dm->GetContentDevice()) {
     d2d1.SetFailed(FeatureStatus::Failed, "Failed to acquire a Direct3D 11 content device",
                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DEVICE"));
     return;
   }
 
-  if (!mCompositorD3D11TextureSharingWorks) {
+  if (!dm->TextureSharingWorks()) {
     d2d1.SetFailed(FeatureStatus::Failed, "Direct3D11 device does not support texture sharing",
                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_TXT_SHARING"));
     return;
   }
 
   // Using Direct2D depends on DWrite support.
   if (!mDWriteFactory && !InitDWriteSupport()) {
     d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support",
                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE"));
     return;
   }
 
   // Verify that Direct2D device creation succeeded.
-  if (!Factory::SetDirect3D11Device(mD3D11ContentDevice)) {
+  RefPtr<ID3D11Device> contentDevice = dm->GetContentDevice();
+  if (!Factory::SetDirect3D11Device(contentDevice)) {
     d2d1.SetFailed(FeatureStatus::Failed, "Failed to create a Direct2D device",
                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_CREATE_FAILED"));
     return;
   }
 
   MOZ_ASSERT(d2d1.IsEnabled());
   d2d1_1.SetSuccessful();
 }
 
 bool
-gfxWindowsPlatform::CreateD3D11DecoderDeviceHelper(
-  IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice, HRESULT& aResOut)
-{
-  MOZ_SEH_TRY{
-    aResOut =
-      sD3D11CreateDeviceFn(
-        aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
-        D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
-        mFeatureLevels.Elements(), mFeatureLevels.Length(),
-        D3D11_SDK_VERSION, getter_AddRefs(aDevice), nullptr, nullptr);
-
-  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
-    return false;
-  }
-  return true;
-}
-
-already_AddRefed<ID3D11Device>
-gfxWindowsPlatform::CreateD3D11DecoderDevice()
-{
-   if (!sD3D11CreateDeviceFn) {
-    // We should just be on Windows Vista or XP in this case.
-    return nullptr;
-  }
-
-  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
-
-  if (!adapter) {
-    return nullptr;
-  }
-
-  RefPtr<ID3D11Device> device;
-
-  HRESULT hr;
-  if (!CreateD3D11DecoderDeviceHelper(adapter, device, hr)) {
-    return nullptr;
-  }
-
-  if (FAILED(hr) || !device || !DoesD3D11DeviceWork()) {
-    return nullptr;
-  }
-
-  RefPtr<ID3D10Multithread> multi;
-  device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
-
-  multi->SetMultithreadProtected(TRUE);
-
-  return device.forget();
-}
-
-bool
 gfxWindowsPlatform::DwmCompositionEnabled()
 {
   if (!IsVistaOrLater()) {
     return false;
   }
 
   MOZ_ASSERT(WinUtils::dwmIsCompositionEnabledPtr);
   BOOL dwmEnabled = false;
@@ -2956,65 +2010,58 @@ gfxWindowsPlatform::GetAcceleratedCompos
   if (gfxConfig::IsEnabled(Feature::OPENGL_COMPOSITING) && gfxPrefs::LayersPreferOpenGL()) {
     aBackends.AppendElement(LayersBackend::LAYERS_OPENGL);
   }
 
   if (gfxConfig::IsEnabled(Feature::D3D9_COMPOSITING) && gfxPrefs::LayersPreferD3D9()) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D9);
   }
 
-  if (mD3D11Device) {
+  if (DeviceManagerD3D11::Get()->GetCompositorDevice()) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D11);
   } else {
     NS_WARNING("Direct3D 11-accelerated layers are not supported on this system.");
   }
 
   if (gfxConfig::IsEnabled(Feature::D3D9_COMPOSITING) && !gfxPrefs::LayersPreferD3D9()) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D9);
   }
 }
 
-unsigned
-gfxWindowsPlatform::GetD3D11Version()
-{
-  RefPtr<ID3D11Device> device;
-  if (!GetD3D11Device(&device)) {
-    return 0;
-  }
-  return device->GetFeatureLevel();
-}
-
 void
 gfxWindowsPlatform::GetDeviceInitData(DeviceInitData* aOut)
 {
   // Check for device resets before giving back new graphics information.
   UpdateRenderMode();
 
   gfxPlatform::GetDeviceInitData(aOut);
 
   // IPDL initializes each field to false for us so we can early return.
   if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     return;
   }
 
+  DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
+
   aOut->useD3D11() = true;
-  aOut->useD3D11ImageBridge() = !!mD3D11ImageBridgeDevice;
-  aOut->d3d11TextureSharingWorks() = mCompositorD3D11TextureSharingWorks;
-  aOut->useD3D11WARP() = mIsWARP;
+  aOut->useD3D11ImageBridge() = !!dm->GetImageBridgeDevice();
+  aOut->d3d11TextureSharingWorks() = dm->TextureSharingWorks();
+  aOut->useD3D11WARP() = dm->IsWARP();
   aOut->useD2D1() = gfxConfig::IsEnabled(Feature::DIRECT2D);