Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 30 Jan 2013 08:05:31 -0500
changeset 130216 5f9775715519260793af64eff6dfc56cbb356982
parent 130144 677e87c11252bbb74d28060f7829db4373acc8a8 (current diff)
parent 130215 dd6cfdf29d037aa46a63c0440488041eb5469c8c (diff)
child 130228 2cc710018b14894f99f28ca3c95d708cbd620bbd
child 130231 6a2236d7b359ef486974101024f10aafcf8c29ed
child 130242 a1adb678b5dbfe91c10f1363d93ee2b8048d4bcb
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone21.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 the last PGO-green inbound changeset to m-c.
content/media/test/test_reset_src.html
content/svg/content/src/nsSVGMarkerElement.cpp
content/svg/content/src/nsSVGMarkerElement.h
dom/interfaces/svg/nsIDOMSVGFitToViewBox.idl
dom/interfaces/svg/nsIDOMSVGTests.idl
dom/webidl/XULElement.webidl
storage/src/TelemetryVFS.cpp
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -9,16 +9,23 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
 
+#ifdef MOZ_WIDGET_GONK
+XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
+  Cu.import("resource://gre/modules/systemlibs.js");
+  return libcutils;
+});
+#endif
+
 // Once Bug 731746 - Allow chrome JS object to implement nsIDOMEventTarget
 // is resolved this helper could be removed.
 var SettingsListener = {
   _callbacks: {},
 
   init: function sl_init() {
     if ('mozSettings' in navigator && navigator.mozSettings) {
       navigator.mozSettings.onsettingchange = this.onchange.bind(this);
@@ -169,47 +176,43 @@ Components.utils.import('resource://gre/
   lock.set('deviceinfo.platform_build_id', appInfo.platformBuildID, null, null);
 
   let update_channel = Services.prefs.getCharPref('app.update.channel');
   lock.set('deviceinfo.update_channel', update_channel, null, null);
 
   // Get the hardware info and firmware revision from device properties.
   let hardware_info = null;
   let firmware_revision = null;
-  try {
-    let cutils = ctypes.open('libcutils.so');
-    let cbuf = ctypes.char.array(128)();
-    let c_property_get = cutils.declare('property_get', ctypes.default_abi,
-                                        ctypes.int,       // return value: length
-                                        ctypes.char.ptr,  // key
-                                        ctypes.char.ptr,  // value
-                                        ctypes.char.ptr); // default
-    let property_get = function (key, defaultValue) {
-      if (defaultValue === undefined) {
-        defaultValue = null;
-      }
-      c_property_get(key, cbuf, defaultValue);
-      return cbuf.readString();
-    }
-    hardware_info = property_get('ro.hardware');
-    firmware_revision = property_get('ro.firmware_revision');
-    cutils.close();
-  } catch(e) {
-    // Error.
-  }
+#ifdef MOZ_WIDGET_GONK
+    hardware_info = libcutils.property_get('ro.hardware');
+    firmware_revision = libcutils.property_get('ro.firmware_revision');
+#endif
   lock.set('deviceinfo.hardware', hardware_info, null, null);
   lock.set('deviceinfo.firmware_revision', firmware_revision, null, null);
 })();
 
 // =================== Debugger ====================
 SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) {
   Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value);
   // This preference is consulted during startup
   Services.prefs.savePrefFile(null);
   value ? RemoteDebugger.start() : RemoteDebugger.stop();
+
+#ifdef MOZ_WIDGET_GONK
+  // Configure adb.
+  try {
+    let current = libcutils.property_get("persist.sys.usb.config");
+    let prefix = current.replace(/,adb/, "");
+    libcutils.property_set("persist.sys.usb.config",
+                           prefix + (value ? ",adb" : ""));
+    current = libcutils.property_get("persist.sys.usb.config");
+  } catch(e) {
+    dump("Error configuring adb: " + e);
+  }
+#endif
 });
 
 SettingsListener.observe('debug.log-animations.enabled', false, function(value) {
   Services.prefs.setBoolPref('layers.offmainthreadcomposition.log-animations', value);
 });
 
 // =================== Privacy ====================
 SettingsListener.observe('privacy.donottrackheader.enabled', false, function(value) {
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -47,16 +47,24 @@ tabbrowser {
   max-width: 0.1px;
   min-width: 0.1px;
   opacity: 0 !important;
   transition: min-width 200ms ease-out,
               max-width 250ms ease-out,
               opacity 50ms ease-out 180ms /* hide the tab for the last 20ms of the max-width transition */;
 }
 
+.tabbrowser-tabs[dontresize] > .tabbrowser-tab[fadein]:not([pinned]) {
+  /* controlled in tabbrowser.xml */
+}
+
+.tabbrowser-tabs[dontanimate] > .tabbrowser-tab {
+  transition: none !important;
+}
+
 .tab-throbber:not([fadein]):not([pinned]),
 .tab-label:not([fadein]):not([pinned]),
 .tab-icon-image:not([fadein]):not([pinned]),
 .tab-close-button:not([fadein]):not([pinned]) {
   display: none;
 }
 
 .tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1260,17 +1260,17 @@ var gBrowserInit = {
     IndexedDBPromptHelper.init();
     gFormSubmitObserver.init();
     SocialUI.init();
     AddonManager.addAddonListener(AddonsMgrListener);
     WebrtcIndicator.init();
 
     gBrowser.addEventListener("pageshow", function(event) {
       // Filter out events that are not about the document load we are interested in
-      if (content && event.target == content.document)
+      if (event.target == content.document)
         setTimeout(pageShowEventHandlers, 0, event);
     }, true);
 
     // Ensure login manager is up and running.
     Services.logins;
 
     if (mustLoadSidebar) {
       let sidebar = document.getElementById("sidebar");
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -42,21 +42,22 @@ tabpanels {
 }
 
 .tab-throbber:not([busy]),
 .tab-throbber[busy] + .tab-icon-image {
   display: none;
 }
 
 .closing-tabs-spacer {
+  min-width: 0;
   pointer-events: none;
 }
 
 .tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
-  transition: width .15s ease-out;
+  transition: min-width 150ms ease-out;
 }
 
 /**
  * Optimization for tabs that are restored lazily. We can save a good amount of
  * memory that to-be-restored tabs would otherwise consume simply by setting
  * their browsers to 'display: none' as that will prevent them from having to
  * create a presentation and the like.
  */
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1579,17 +1579,16 @@
             if (this.tabContainer._tabAnimationLoggingEnabled) {
               aTab._recordingHandle = window.QueryInterface(Ci.nsIInterfaceRequestor)
                                             .getInterface(Ci.nsIDOMWindowUtils)
                                             .startFrameTimeRecording();
             }
             aTab._animStartTime = Date.now();
 
             this._blurTab(aTab);
-            aTab.style.maxWidth = ""; // ensure that fade-out transition happens
             aTab.removeAttribute("fadein");
 
             setTimeout(function (tab, tabbrowser) {
               if (tab.parentNode &&
                   window.getComputedStyle(tab).maxWidth == "0.1px") {
                 NS_ASSERT(false, "Giving up waiting for the tab closing animation to finish (bug 608589)");
                 tabbrowser._endRemoveTab(tab);
               }
@@ -1776,20 +1775,16 @@
               this.tabs[i]._tPos = i;
 
             if (!this._windowIsClosing) {
               if (wasPinned)
                 this.tabContainer._positionPinnedTabs();
 
               // update tab close buttons state
               this.tabContainer.adjustTabstrip();
-
-              setTimeout(function(tabs) {
-                tabs._lastTabClosedByMouse = false;
-              }, 0, this.tabContainer);
             }
 
             // update first-tab/last-tab/beforeselected/afterselected attributes
             this.selectedTab._selected = true;
 
             // Removing the panel requires fixing up selectedPanel immediately
             // (see below), which would be hindered by the potentially expensive
             // browser removal. So we remove the browser and the panel in two
@@ -2824,20 +2819,23 @@
     </implementation>
 
     <handlers>
       <handler event="underflow" phase="capturing"><![CDATA[
         if (event.detail == 0)
           return; // Ignore vertical events
 
         var tabs = document.getBindingParent(this);
-        tabs.removeAttribute("overflow");
-
-        if (tabs._lastTabClosedByMouse)
-          tabs._expandSpacerBy(this._scrollButtonDown.clientWidth);
+
+        if (tabs.hasAttribute("dontresize") || tabs.hasAttribute("using-closing-tabs-spacer")) {
+          tabs.mTabstrip._scrollButtonUp.style.visibility = "hidden";
+          tabs.mTabstrip._scrollButtonDown.style.visibility = "hidden";
+        } else {
+          tabs.removeAttribute("overflow");
+        }
 
         tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
                                               tabs.tabbrowser);
 
         tabs._positionPinnedTabs();
       ]]></handler>
       <handler event="overflow"><![CDATA[
         if (event.detail == 0)
@@ -2872,18 +2870,17 @@
         <children includes="tab"/>
 # This is to ensure anything extensions put here will go before the newtab
 # button, necessary due to the previous hack.
         <children/>
         <xul:toolbarbutton class="tabs-newtab-button"
                            command="cmd_newNavigatorTab"
                            onclick="checkForMiddleClick(this, event);"
                            tooltiptext="&newTabButton.tooltip;"/>
-        <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"
-                    style="width: 0;"/>
+        <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"/>
       </xul:arrowscrollbox>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
           this.mCloseButtons = Services.prefs.getIntPref("browser.tabs.closeButtons");
@@ -3070,107 +3067,98 @@
           } catch (e) {}
         ]]></body>
       </method>
 
       <field name="_closingTabsSpacer">
         document.getAnonymousElementByAttribute(this, "anonid", "closing-tabs-spacer");
       </field>
 
-      <field name="_tabDefaultMaxWidth">NaN</field>
-      <field name="_lastTabClosedByMouse">false</field>
-      <field name="_hasTabTempMaxWidth">false</field>
+      <field name="_delayResizingRule" readonly="true"><![CDATA[
+        const href = "chrome://browser/content/browser.css";
+        const selector = ".tabbrowser-tabs[dontresize] > .tabbrowser-tab[fadein]:not([pinned])";
+
+        // XXX: document.styleSheets is not iterable (see bug 738196)
+        for (let sheet of Array.slice(document.styleSheets))
+          if (sheet.href == href)
+            for (let rule of Array.slice(sheet.cssRules))
+              if (rule.selectorText == selector) { rule; break; }
+      ]]></field>
 
       <!-- Try to keep the active tab's close button under the mouse cursor -->
       <method name="_lockTabSizing">
         <parameter name="aTab"/>
         <body><![CDATA[
           var tabs = this.tabbrowser.visibleTabs;
           if (!tabs.length)
             return;
 
           var isEndTab = (aTab._tPos > tabs[tabs.length-1]._tPos);
           var tabWidth = aTab.getBoundingClientRect().width;
 
-          if (!this._tabDefaultMaxWidth)
-            this._tabDefaultMaxWidth =
-              parseFloat(window.getComputedStyle(aTab).maxWidth);
-          this._lastTabClosedByMouse = true;
-
-          if (this.getAttribute("overflow") == "true") {
-            // Don't need to do anything if we're in overflow mode and aren't scrolled
-            // all the way to the right, or if we're closing the last tab.
-            if (isEndTab || !this.mTabstrip._scrollButtonDown.disabled)
-              return;
-
-            // If the tab has an owner that will become the active tab, the owner will
-            // be to the left of it, so we actually want the left tab to slide over.
-            // This can't be done as easily in non-overflow mode, so we don't bother.
-            if (aTab.owner)
-              return;
-
-            this._expandSpacerBy(tabWidth);
-          } else { // non-overflow mode
-            // Locking is neither in effect nor needed, so let tabs expand normally.
-            if (isEndTab && !this._hasTabTempMaxWidth)
-              return;
-
-            let numPinned = this.tabbrowser._numPinnedTabs;
-            // Force tabs to stay the same width, unless we're closing the last tab,
-            // which case we need to let them expand just enough so that the overall
-            // tabbar width is the same.
-            if (isEndTab) {
-              let numNormalTabs = tabs.length - numPinned;
-              tabWidth = tabWidth * (numNormalTabs + 1) / numNormalTabs;
-              if (tabWidth > this._tabDefaultMaxWidth)
-                tabWidth = this._tabDefaultMaxWidth;
+          // Locking is neither in effect nor needed, so let tabs expand normally.
+          if (isEndTab && !this.hasAttribute("dontresize"))
+            return;
+
+          // Let spacer grow to the maximum and lock it, then let tabs expand normally
+          if (isEndTab) {
+            let spacer = this._closingTabsSpacer;
+            spacer.style.MozBoxFlex = 1;
+            spacer.style.minWidth = getComputedStyle(spacer).width;
+            spacer.style.MozBoxFlex = "";
+
+            this.setAttribute("dontanimate", "true");
+            this.removeAttribute("dontresize");
+            this.clientTop;
+            this.removeAttribute("dontanimate");
+            return;
+          }
+
+          if (!this.hasAttribute("dontresize")) {
+            this._delayResizingRule.style.setProperty("max-width", tabWidth + "px", "important");
+            this.setAttribute("dontanimate", "true");
+            this.setAttribute("dontresize", "true");
+            this.clientTop; // flush styles to skip animation; see bug 649247
+            this.removeAttribute("dontanimate");
+          }
+
+          if (!this.mTabstrip._scrollButtonUp.disabled) {
+            let spacer = this._closingTabsSpacer;
+            let width = parseFloat(spacer.style.minWidth) || 0;
+            width += tabWidth;
+
+            if (!this.mTabstrip._scrollButtonDown.disabled) {
+              let scrollbox = this.mTabstrip._scrollbox;
+              width -= scrollbox.scrollLeftMax - scrollbox.scrollLeft;
             }
-            tabWidth += "px";
-            for (let i = numPinned; i < tabs.length; i++) {
-              let tab = tabs[i];
-              tab.style.setProperty("max-width", tabWidth, "important");
-              if (!isEndTab) { // keep tabs the same width
-                tab.style.transition = "none";
-                tab.clientTop; // flush styles to skip animation; see bug 649247
-                tab.style.transition = "";
-              }
+
+            if (width >= 0) {
+              spacer.style.minWidth = width + "px";
+              this.setAttribute("using-closing-tabs-spacer", "true");
             }
-            this._hasTabTempMaxWidth = true;
-            this.tabbrowser.addEventListener("mousemove", this, false);
-            window.addEventListener("mouseout", this, false);
           }
-        ]]></body>
-      </method>
-
-      <method name="_expandSpacerBy">
-        <parameter name="pixels"/>
-        <body><![CDATA[
-          let spacer = this._closingTabsSpacer;
-          spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
-          this.setAttribute("using-closing-tabs-spacer", "true");
+
           this.tabbrowser.addEventListener("mousemove", this, false);
           window.addEventListener("mouseout", this, false);
         ]]></body>
       </method>
 
       <method name="_unlockTabSizing">
         <body><![CDATA[
           this.tabbrowser.removeEventListener("mousemove", this, false);
           window.removeEventListener("mouseout", this, false);
 
-          if (this._hasTabTempMaxWidth) {
-            this._hasTabTempMaxWidth = false;
-            let tabs = this.tabbrowser.visibleTabs;
-            for (let i = 0; i < tabs.length; i++)
-              tabs[i].style.maxWidth = "";
-          }
-
-          if (this.hasAttribute("using-closing-tabs-spacer")) {
-            this.removeAttribute("using-closing-tabs-spacer");
-            this._closingTabsSpacer.style.width = 0;
+          this._closingTabsSpacer.style.minWidth = "";
+          this.removeAttribute("using-closing-tabs-spacer");
+          this.removeAttribute("dontresize");
+
+          if (this.hasAttribute("overflow") && this.mTabstrip._scrollbox.scrollWidth <= this.mTabstrip._scrollbox.clientWidth) {
+            this.mTabstrip._scrollButtonUp.style.visibility = "";
+            this.mTabstrip._scrollButtonDown.style.visibility = "";
+            this.removeAttribute("overflow");
           }
         ]]></body>
       </method>
 
       <field name="_lastNumPinned">0</field>
       <method name="_positionPinnedTabs">
         <body><![CDATA[
           var numPinned = this.tabbrowser._numPinnedTabs;
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -455,17 +455,16 @@ PlacesController.prototype = {
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT:
           nodeData["folder"] = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR:
           nodeData["separator"] = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT:
-        case Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT:
           nodeData["link"] = true;
           uri = NetUtil.newURI(node.uri);
           if (PlacesUtils.nodeIsBookmark(node)) {
             nodeData["bookmark"] = true;
             PlacesUtils.nodeIsTagQuery(node.parent)
 
             var parentNode = node.parent;
             if (parentNode) {
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -421,15 +421,17 @@ identity.loggedIn.signOut.accessKey = O
 # LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message, getUserMedia.sharingCamera.message, getUserMedia.sharingMicrophone.message, getUserMedia.sharingCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
 # LOCALIZATION NOTE (getUserMedia.shareSelectedDevices.label):
 # Semi-colon list of plural forms. See:
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # The number of devices can be either one or two.
 getUserMedia.shareCamera.message = Would you like to share your camera with %S?
 getUserMedia.shareMicrophone.message = Would you like to share your microphone with %S?
 getUserMedia.shareCameraAndMicrophone.message = Would you like to share your camera and microphone with %S?
+getUserMedia.noVideo.label = No Video
+getUserMedia.noAudio.label = No Audio
 getUserMedia.shareSelectedDevices.label = Share Selected Device;Share Selected Devices
 getUserMedia.shareSelectedDevices.accesskey = S
 getUserMedia.denyRequest.label = Don't Share
 getUserMedia.denyRequest.accesskey = D
 getUserMedia.sharingCamera.message = You are currently sharing your camera with %S.
 getUserMedia.sharingMicrophone.message = You are currently sharing your microphone with %S.
 getUserMedia.sharingCameraAndMicrophone.message = You are currently sharing your camera and microphone with %S.
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -113,45 +113,64 @@ function prompt(aBrowser, aCallID, aAudi
                                                 [ host ]);
 
   function listDevices(menupopup, devices) {
     while (menupopup.lastChild)
       menupopup.removeChild(menupopup.lastChild);
 
     let deviceIndex = 0;
     for (let device of devices) {
-      let menuitem = chromeDoc.createElement("menuitem");
-      menuitem.setAttribute("value", deviceIndex);
-      menuitem.setAttribute("label", device.name);
-      menuitem.setAttribute("tooltiptext", device.name);
-      menupopup.appendChild(menuitem);
+      addDeviceToList(menupopup, device.name, deviceIndex);
       deviceIndex++;
     }
   }
 
+  function addDeviceToList(menupopup, deviceName, deviceIndex) {
+    let menuitem = chromeDoc.createElement("menuitem");
+    menuitem.setAttribute("value", deviceIndex);
+    menuitem.setAttribute("label", deviceName);
+    menuitem.setAttribute("tooltiptext", deviceName);
+    menupopup.appendChild(menuitem);
+  }
+
   chromeDoc.getElementById("webRTC-selectCamera").hidden = !videoDevices.length;
   chromeDoc.getElementById("webRTC-selectMicrophone").hidden = !audioDevices.length;
-  listDevices(chromeDoc.getElementById("webRTC-selectCamera-menupopup"), videoDevices);
-  listDevices(chromeDoc.getElementById("webRTC-selectMicrophone-menupopup"), audioDevices);
+
+  let camMenupopup = chromeDoc.getElementById("webRTC-selectCamera-menupopup");
+  let micMenupopup = chromeDoc.getElementById("webRTC-selectMicrophone-menupopup");
+  listDevices(camMenupopup, videoDevices);
+  listDevices(micMenupopup, audioDevices);
+  if (requestType == "CameraAndMicrophone") {
+    addDeviceToList(camMenupopup, stringBundle.getString("getUserMedia.noVideo.label"), "-1");
+    addDeviceToList(micMenupopup, stringBundle.getString("getUserMedia.noAudio.label"), "-1");
+  }
 
   let mainAction = {
     label: PluralForm.get(requestType == "CameraAndMicrophone" ? 2 : 1,
                           stringBundle.getString("getUserMedia.shareSelectedDevices.label")),
     accessKey: stringBundle.getString("getUserMedia.shareSelectedDevices.accesskey"),
     callback: function () {
       let allowedDevices = Cc["@mozilla.org/supports-array;1"]
                              .createInstance(Ci.nsISupportsArray);
       if (videoDevices.length) {
         let videoDeviceIndex = chromeDoc.getElementById("webRTC-selectCamera-menulist").value;
-        allowedDevices.AppendElement(videoDevices[videoDeviceIndex]);
+        if (videoDeviceIndex != "-1")
+          allowedDevices.AppendElement(videoDevices[videoDeviceIndex]);
       }
       if (audioDevices.length) {
         let audioDeviceIndex = chromeDoc.getElementById("webRTC-selectMicrophone-menulist").value;
-        allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
+        if (audioDeviceIndex != "-1")
+          allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
       }
+
+      if (allowedDevices.Count() == 0) {
+        Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
+        return;
+      }
+
       Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
 
       // Show browser-specific indicator for the active camera/mic access.
       let message = stringBundle.getFormattedString("getUserMedia.sharing" + requestType + ".message",
                                                     [ host ]);
       let mainAction = null;
       let secondaryActions = null;
       let options = {
--- a/configure.in
+++ b/configure.in
@@ -1431,16 +1431,17 @@ if test "$GNU_CC"; then
            *)
         _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wcast-align"
            ;;
        esac
     fi
 
     _DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
     _USE_CPP_INCLUDE_FLAG=1
+    ASFLAGS="$ASFLAGS $_DEFINES_CFLAGS"
 
 elif test "$SOLARIS_SUNPRO_CC"; then
     DSO_CFLAGS=''
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
@@ -6175,17 +6176,17 @@ dnl (unless in case of cross compiling, 
 dnl is not yet sufficient).
 if test "$OS_ARCH" = "WINNT"; then
     REQ_NSIS_MAJOR_VER=2
     MIN_NSIS_MINOR_VER=46
     MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensisu-2.46 makensis)
     if test -n "$MAKENSISU" -a "$MAKENSISU" != ":"; then
       AC_MSG_RESULT([yes])
       changequote(,)
-      MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
+      MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\).*\-Unicode$/\1/g'`
       changequote([,])
       if test ! "$MAKENSISU_VER" = ""; then
           MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
           MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
       fi
       AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
       if test "$MAKENSISU_VER" = "" || \
          test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -29,16 +29,17 @@
 class imgIRequest;
 class nsAString;
 class nsBindingManager;
 class nsCSSStyleSheet;
 class nsDOMNavigationTiming;
 class nsEventStates;
 class nsFrameLoader;
 class nsHTMLCSSStyleSheet;
+class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsIAtom;
 class nsIBFCacheEntry;
 class nsIBoxObject;
 class nsIChannel;
 class nsIContent;
 class nsIContentSink;
 class nsIDocShell;
@@ -1969,16 +1970,18 @@ public:
                 float aRotationAngle, float aForce);
   already_AddRefed<nsIDOMTouchList> CreateTouchList();
   already_AddRefed<nsIDOMTouchList>
     CreateTouchList(nsIDOMTouch* aTouch,
                     const mozilla::dom::Sequence<nsRefPtr<nsIDOMTouch> >& aTouches);
   already_AddRefed<nsIDOMTouchList>
     CreateTouchList(const mozilla::dom::Sequence<nsRefPtr<nsIDOMTouch> >& aTouches);
 
+  nsHTMLDocument* AsHTMLDocument();
+
 private:
   uint64_t mWarnedAbout;
 
 protected:
   ~nsIDocument();
   nsPropertyTable* GetExtraPropertyTable(uint16_t aCategory);
 
   // Never ever call this. Only call GetWindow!
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -383,17 +383,16 @@ protected:
   /**
    * WrapNode is called from WrapObject to actually wrap this node, WrapObject
    * does some additional checks and fix-up that's common to all nodes. WrapNode
    * should just call the DOM binding's Wrap function.
    */
   virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
                              bool *aTriedToWrap)
   {
-    MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapNode");
     *aTriedToWrap = false;
     return nullptr;
   }
 
 public:
   nsIDocument* GetParentObject() const
   {
     // Make sure that we get the owner document of the content node, in case
@@ -1546,19 +1545,19 @@ public:
                         mozilla::ErrorResult& aError)
   {
     return ReplaceOrInsertBefore(true, &aNode, &aChild, aError);
   }
   nsINode* RemoveChild(nsINode& aChild, mozilla::ErrorResult& aError);
   already_AddRefed<nsINode> CloneNode(bool aDeep, mozilla::ErrorResult& aError);
   bool IsEqualNode(nsINode* aNode);
   bool IsSupported(const nsAString& aFeature, const nsAString& aVersion);
-  void GetNamespaceURI(nsAString& aNamespaceURI, mozilla::ErrorResult& aError) const
+  void GetNamespaceURI(nsAString& aNamespaceURI) const
   {
-    aError = mNodeInfo->GetNamespaceURI(aNamespaceURI);
+    mNodeInfo->GetNamespaceURI(aNamespaceURI);
   }
 #ifdef MOZILLA_INTERNAL_API
   void GetPrefix(nsAString& aPrefix)
   {
     mNodeInfo->GetPrefix(aPrefix);
   }
 #endif
   void GetLocalName(nsAString& aLocalName)
@@ -1996,19 +1995,18 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, N
   } \
   NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aResult) __VA_ARGS__ \
   { \
     *aResult = nsINode::IsSupported(aFeature, aVersion); \
     return NS_OK; \
   } \
   NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) __VA_ARGS__ \
   { \
-    mozilla::ErrorResult rv; \
-    nsINode::GetNamespaceURI(aNamespaceURI, rv); \
-    return rv.ErrorCode(); \
+    nsINode::GetNamespaceURI(aNamespaceURI); \
+    return NS_OK; \
   } \
   NS_IMETHOD GetPrefix(nsAString& aPrefix) __VA_ARGS__ \
   { \
     nsINode::GetPrefix(aPrefix); \
     return NS_OK; \
   } \
   NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ \
   { \
--- a/content/base/public/nsINodeInfo.h
+++ b/content/base/public/nsINodeInfo.h
@@ -127,17 +127,17 @@ public:
   nsIAtom* GetPrefixAtom() const
   {
     return mInner.mPrefix;
   }
 
   /*
    * Get the namespace URI for a node, if the node has a namespace URI.
    */
-  virtual nsresult GetNamespaceURI(nsAString& aNameSpaceURI) const = 0;
+  virtual void GetNamespaceURI(nsAString& aNameSpaceURI) const = 0;
 
   /*
    * Get the namespace ID for a node if the node has a namespace, if not this
    * returns kNameSpaceID_None.
    */
   int32_t NamespaceID() const
   {
     return mInner.mNamespaceID;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1845,16 +1845,22 @@ nsDocument::Init()
   mScriptLoader = new nsScriptLoader(this);
 
   mImageTracker.Init();
   mPlugins.Init();
 
   return NS_OK;
 }
 
+nsHTMLDocument*
+nsIDocument::AsHTMLDocument()
+{
+  return IsHTML() ? static_cast<nsHTMLDocument*>(this) : nullptr;
+}
+
 void
 nsIDocument::DeleteAllProperties()
 {
   for (uint32_t i = 0; i < GetPropertyTableCount(); ++i) {
     PropertyTable(i)->DeleteAllProperties();
   }
 }
 
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -203,29 +203,30 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeIn
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
 NS_INTERFACE_TABLE_HEAD(nsNodeInfo)
   NS_INTERFACE_TABLE1(nsNodeInfo, nsINodeInfo)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsNodeInfo)
 NS_INTERFACE_MAP_END
 
 // nsINodeInfo
 
-nsresult
+void
 nsNodeInfo::GetNamespaceURI(nsAString& aNameSpaceURI) const
 {
-  nsresult rv = NS_OK;
-
   if (mInner.mNamespaceID > 0) {
-    rv = nsContentUtils::NameSpaceManager()->GetNameSpaceURI(mInner.mNamespaceID,
-                                                             aNameSpaceURI);
+    nsresult rv =
+      nsContentUtils::NameSpaceManager()->GetNameSpaceURI(mInner.mNamespaceID,
+                                                          aNameSpaceURI);
+    // How can we possibly end up with a bogus namespace ID here?
+    if (NS_FAILED(rv)) {
+      MOZ_CRASH();
+    }
   } else {
     SetDOMStringToNull(aNameSpaceURI);
   }
-
-  return rv;
 }
 
 
 bool
 nsNodeInfo::NamespaceEquals(const nsAString& aNamespaceURI) const
 {
   int32_t nsid =
     nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
--- a/content/base/src/nsNodeInfo.h
+++ b/content/base/src/nsNodeInfo.h
@@ -24,17 +24,17 @@ class nsFixedSizeAllocator;
 
 class nsNodeInfo : public nsINodeInfo
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(nsNodeInfo)
 
   // nsINodeInfo
-  virtual nsresult GetNamespaceURI(nsAString& aNameSpaceURI) const;
+  virtual void GetNamespaceURI(nsAString& aNameSpaceURI) const;
   virtual bool NamespaceEquals(const nsAString& aNamespaceURI) const;
 
   // nsNodeInfo
   // Create objects with Create
 public:
   /*
    * aName and aOwnerManager may not be null.
    */
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -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 "base/basictypes.h"
 #include "CanvasRenderingContext2D.h"
 
-#include "nsXULElement.h"
+#include "nsIDOMXULElement.h"
 
 #include "prenv.h"
 
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
@@ -3229,17 +3229,17 @@ CanvasRenderingContext2D::DrawWindow(nsI
 
   // note that x and y are coordinates in the document that
   // we're drawing; x and y are drawn to 0,0 in current user
   // space.
   RedrawUser(gfxRect(0, 0, w, h));
 }
 
 void
-CanvasRenderingContext2D::AsyncDrawXULElement(nsXULElement& elem,
+CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
                                               double x, double y,
                                               double w, double h,
                                               const nsAString& bgColor,
                                               uint32_t flags,
                                               ErrorResult& error)
 {
   // We can't allow web apps to call this until we fix at least the
   // following potential security issues:
@@ -3250,17 +3250,17 @@ CanvasRenderingContext2D::AsyncDrawXULEl
   if (!nsContentUtils::IsCallerChrome()) {
     // not permitted to use DrawWindow
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
     error.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
 #if 0
-  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(&elem);
+  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(elem);
   if (!loaderOwner) {
     error.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
   if (!frameloader) {
     error.Throw(NS_ERROR_FAILURE);
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -19,17 +19,17 @@
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
     {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
 #define NS_CANVASPATTERNAZURE_PRIVATE_IID \
     {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
 
-class nsXULElement;
+class nsIDOMXULElement;
 
 namespace mozilla {
 namespace gfx {
 struct Rect;
 class SourceSurface;
 }
 
 namespace dom {
@@ -433,17 +433,17 @@ public:
     if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
       CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
     }
   }
 
   void DrawWindow(nsIDOMWindow* window, double x, double y, double w, double h,
                   const nsAString& bgColor, uint32_t flags,
                   mozilla::ErrorResult& error);
-  void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
+  void AsyncDrawXULElement(nsIDOMXULElement* elem, double x, double y, double w,
                            double h, const nsAString& bgColor, uint32_t flags,
                            mozilla::ErrorResult& error);
 
   nsresult Redraw();
 
   // nsICanvasRenderingContextInternal
   NS_IMETHOD SetDimensions(int32_t width, int32_t height);
   NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height);
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -63,17 +63,16 @@ CPPSRCS += \
 	WebGLShaderPrecisionFormat.cpp \
 	WebGLTexelConversions.cpp \
 	WebGLTexture.cpp \
 	WebGLUniformLocation.cpp \
 	$(NULL)
 
 LOCAL_INCLUDES += \
 	-I$(topsrcdir)/js/xpconnect/wrappers \
-	-I$(topsrcdir)/content/xul/content/src \
 	$(NULL)
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
 
 endif
 
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -115,17 +115,16 @@ public:
   void NotifyOwnerDocumentActivityChanged();
 
   // Called by the video decoder object, on the main thread,
   // when it has read the metadata containing video dimensions,
   // etc.
   virtual void MetadataLoaded(int aChannels,
                               int aRate,
                               bool aHasAudio,
-                              bool aHasVideo,
                               const MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
 
   // Called by the video decoder object, on the main thread,
   // when it has read the first frame of the video
   // aResourceFullyLoaded should be true if the resource has been
   // fully loaded and the caller will call ResourceLoaded next.
   virtual void FirstFrameLoaded(bool aResourceFullyLoaded) MOZ_FINAL MOZ_OVERRIDE;
 
@@ -472,22 +471,16 @@ protected:
 
   /**
    * Asynchronously awaits a stable state, and then causes SelectResource()
    * to be run on the main thread's event loop.
    */
   void QueueSelectResourceTask();
 
   /**
-   * When loading a new source on an existing media element, make sure to reset
-   * everything that is accessible using the media element API.
-   */
-  void ResetState();
-
-  /**
    * The resource-fetch algorithm step of the load algorithm.
    */
   nsresult LoadResource();
 
   /**
    * Selects the next <source> child from which to load a resource. Called
    * during the resource selection algorithm. Stores the return value in
    * mSourceLoadCandidate before returning.
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -118,17 +118,17 @@ nsHTMLAudioElement::MozSetup(uint32_t aC
   mAudioStream = AudioStream::AllocateStream();
   nsresult rv = mAudioStream->Init(aChannels, aRate, mAudioChannelType);
   if (NS_FAILED(rv)) {
     mAudioStream->Shutdown();
     mAudioStream = nullptr;
     return rv;
   }
 
-  MetadataLoaded(aChannels, aRate, true, false, nullptr);
+  MetadataLoaded(aChannels, aRate, true, nullptr);
   mAudioStream->SetVolume(mVolume);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32_t* aRetVal)
 {
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -728,30 +728,20 @@ NS_IMETHODIMP nsHTMLMediaElement::Load()
 {
   if (mIsRunningLoadMethod)
     return NS_OK;
   SetPlayedOrSeeked(false);
   mIsRunningLoadMethod = true;
   AbortExistingLoads();
   SetPlaybackRate(mDefaultPlaybackRate);
   QueueSelectResourceTask();
-  ResetState();
   mIsRunningLoadMethod = false;
   return NS_OK;
 }
 
-void nsHTMLMediaElement::ResetState()
-{
-  mMediaSize = nsIntSize(-1, -1);
-  VideoFrameContainer* container = GetVideoFrameContainer();
-  if (container) {
-    container->Reset();
-  }
-}
-
 static bool HasSourceChildren(nsIContent *aElement)
 {
   for (nsIContent* child = aElement->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->IsHTML(nsGkAtoms::source))
     {
       return true;
@@ -2602,37 +2592,29 @@ void nsHTMLMediaElement::ProcessMediaFra
     SetCurrentTime(start);
     mFragmentStart = start;
   }
 }
 
 void nsHTMLMediaElement::MetadataLoaded(int aChannels,
                                         int aRate,
                                         bool aHasAudio,
-                                        bool aHasVideo,
                                         const MetadataTags* aTags)
 {
   mChannels = aChannels;
   mRate = aRate;
   mHasAudio = aHasAudio;
   mTags = aTags;
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
   DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
   DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
   if (mDecoder && mDecoder->IsTransportSeekable() && mDecoder->IsMediaSeekable()) {
     ProcessMediaFragmentURI();
     mDecoder->SetFragmentEndTime(mFragmentEnd);
   }
-
-  // If this element had a video track, but consists only of an audio track now,
-  // delete the VideoFrameContainer. This happens when the src is changed to an
-  // audio only file.
-  if (!aHasVideo) {
-    mVideoFrameContainer = nullptr;
-  }
 }
 
 void nsHTMLMediaElement::FirstFrameLoaded(bool aResourceFullyLoaded)
 {
   ChangeReadyState(aResourceFullyLoaded ?
     nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA :
     nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
   ChangeDelayLoadStatus(false);
@@ -2966,24 +2948,16 @@ void nsHTMLMediaElement::NotifyAutoplayD
       GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
     }
     DispatchAsyncEvent(NS_LITERAL_STRING("play"));
   }
 }
 
 VideoFrameContainer* nsHTMLMediaElement::GetVideoFrameContainer()
 {
-  // If we have loaded the metadata, and the size of the video is still
-  // (-1, -1), the media has no video. Don't go a create a video frame
-  // container.
-  if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
-      mMediaSize == nsIntSize(-1, -1)) {
-    return nullptr;
-  }
-
   if (mVideoFrameContainer)
     return mVideoFrameContainer;
 
   // If we have a print surface, this is just a static image so
   // no image container is required
   if (mPrintSurface)
     return nullptr;
 
--- a/content/media/AbstractMediaDecoder.h
+++ b/content/media/AbstractMediaDecoder.h
@@ -76,18 +76,18 @@ public:
   virtual mozilla::layers::ImageContainer* GetImageContainer() = 0;
 
   // Return true if the media layer supports seeking.
   virtual bool IsTransportSeekable() = 0;
 
   // Return true if the transport layer supports seeking.
   virtual bool IsMediaSeekable() = 0;
 
-  virtual void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags) = 0;
-  virtual void QueueMetadata(int64_t aTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags) = 0;
+  virtual void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) = 0;
+  virtual void QueueMetadata(int64_t aTime, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) = 0;
 
   // Set the media end time in microseconds
   virtual void SetMediaEndTime(int64_t aTime) = 0;
 
   // Make the decoder state machine update the playback position. Called by
   // the reader on the decoder thread (Assertions for this checked by
   // mDecoderStateMachine). This must be called with the decode monitor
   // held.
@@ -114,35 +114,33 @@ public:
   };
 };
 
 class AudioMetadataEventRunner : public nsRunnable
 {
   private:
     nsRefPtr<AbstractMediaDecoder> mDecoder;
   public:
-    AudioMetadataEventRunner(AbstractMediaDecoder* aDecoder, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags)
+    AudioMetadataEventRunner(AbstractMediaDecoder* aDecoder, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags)
       : mDecoder(aDecoder),
         mChannels(aChannels),
         mRate(aRate),
         mHasAudio(aHasAudio),
-        mHasVideo(aHasVideo),
         mTags(aTags)
   {}
 
   NS_IMETHOD Run()
   {
-    mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio, mHasVideo, mTags);
+    mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio, mTags);
     return NS_OK;
   }
 
   int mChannels;
   int mRate;
   bool mHasAudio;
-  bool mHasVideo;
   MetadataTags* mTags;
 };
 
 
 }
 
 #endif
 
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -183,24 +183,28 @@ MediaDecoder::DecodedStreamData::~Decode
 
 void MediaDecoder::DestroyDecodedStream()
 {
   MOZ_ASSERT(NS_IsMainThread());
   GetReentrantMonitor().AssertCurrentThreadIn();
 
   // All streams are having their SourceMediaStream disconnected, so they
   // need to be explicitly blocked again.
-  for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
+  for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
     OutputStreamData& os = mOutputStreams[i];
     // During cycle collection, nsDOMMediaStream can be destroyed and send
     // its Destroy message before this decoder is destroyed. So we have to
     // be careful not to send any messages after the Destroy().
-    if (!os.mStream->IsDestroyed()) {
-      os.mStream->ChangeExplicitBlockerCount(1);
+    if (os.mStream->IsDestroyed()) {
+      // Probably the DOM MediaStream was GCed. Clean up.
+      os.mPort->Destroy();
+      mOutputStreams.RemoveElementAt(i);
+      continue;
     }
+    os.mStream->ChangeExplicitBlockerCount(1);
     // Explicitly remove all existing ports. This is not strictly necessary but it's
     // good form.
     os.mPort->Destroy();
     os.mPort = nullptr;
   }
 
   mDecodedStream = nullptr;
 }
@@ -215,18 +219,25 @@ void MediaDecoder::RecreateDecodedStream
   DestroyDecodedStream();
 
   mDecodedStream = new DecodedStreamData(this, aStartTimeUSecs,
     MediaStreamGraph::GetInstance()->CreateSourceStream(nullptr));
 
   // Note that the delay between removing ports in DestroyDecodedStream
   // and adding new ones won't cause a glitch since all graph operations
   // between main-thread stable states take effect atomically.
-  for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
-    ConnectDecodedStreamToOutputStream(&mOutputStreams[i]);
+  for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
+    OutputStreamData& os = mOutputStreams[i];
+    if (os.mStream->IsDestroyed()) {
+      // Probably the DOM MediaStream was GCed. Clean up.
+      // No need to destroy the port; all ports have been destroyed here.
+      mOutputStreams.RemoveElementAt(i);
+      continue;
+    }
+    ConnectDecodedStreamToOutputStream(&os);
   }
 
   mDecodedStream->mHaveBlockedForPlayState = mPlayState != PLAY_STATE_PLAYING;
   if (mDecodedStream->mHaveBlockedForPlayState) {
     mDecodedStream->mStream->ChangeExplicitBlockerCount(1);
   }
 }
 
@@ -239,17 +250,17 @@ void MediaDecoder::NotifyDecodedStreamMa
       nsCOMPtr<nsIRunnable> event =
         NS_NewRunnableMethod(this, &MediaDecoder::PlaybackEnded);
       NS_DispatchToCurrentThread(event);
     }
   }
 }
 
 void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream,
-                                       bool aFinishWhenEnded)
+                                   bool aFinishWhenEnded)
 {
   MOZ_ASSERT(NS_IsMainThread());
   LOG(PR_LOG_DEBUG, ("MediaDecoder::AddOutputStream this=%p aStream=%p!",
                      this, aStream));
 
   {
     ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
     if (!mDecodedStream) {
@@ -636,36 +647,35 @@ void MediaDecoder::AudioAvailable(float*
   }
   mOwner->NotifyAudioAvailable(frameBuffer.forget(), aFrameBufferLength, aTime);
 }
 
 void MediaDecoder::QueueMetadata(int64_t aPublishTime,
                                  int aChannels,
                                  int aRate,
                                  bool aHasAudio,
-                                 bool aHasVideo,
                                  MetadataTags* aTags)
 {
   NS_ASSERTION(mDecoderStateMachine->OnDecodeThread(),
                "Should be on decode thread.");
   GetReentrantMonitor().AssertCurrentThreadIn();
-  mDecoderStateMachine->QueueMetadata(aPublishTime, aChannels, aRate, aHasAudio, aHasVideo, aTags);
+  mDecoderStateMachine->QueueMetadata(aPublishTime, aChannels, aRate, aHasAudio, aTags);
 }
 
 bool
 MediaDecoder::IsDataCachedToEndOfResource()
 {
   NS_ASSERTION(!mShuttingDown, "Don't call during shutdown!");
   GetReentrantMonitor().AssertCurrentThreadIn();
 
   return (mResource &&
           mResource->IsDataCachedToEndOfResource(mDecoderPosition));
 }
 
-void MediaDecoder::MetadataLoaded(int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags)
+void MediaDecoder::MetadataLoaded(int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mShuttingDown) {
     return;
   }
 
   {
     ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
@@ -677,17 +687,17 @@ void MediaDecoder::MetadataLoaded(int aC
   if (mDuration == -1) {
     SetInfinite(true);
   }
 
   if (mOwner) {
     // Make sure the element and the frame (if any) are told about
     // our new size.
     Invalidate();
-    mOwner->MetadataLoaded(aChannels, aRate, aHasAudio, aHasVideo, aTags);
+    mOwner->MetadataLoaded(aChannels, aRate, aHasAudio, aTags);
   }
 
   if (!mCalledResourceLoaded) {
     StartProgress();
   } else if (mOwner) {
     // Resource was loaded during metadata loading, when progress
     // events are being ignored. Fire the final progress event.
     mOwner->DispatchAsyncEvent(NS_LITERAL_STRING("progress"));
@@ -806,22 +816,27 @@ void MediaDecoder::PlaybackEnded()
     if (mDecodedStream && !mDecodedStream->mStream->IsFinished()) {
       // Wait for it to finish before firing PlaybackEnded()
       mTriggerPlaybackEndedWhenSourceStreamFinishes = true;
       return;
     }
 
     for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
       OutputStreamData& os = mOutputStreams[i];
+      if (os.mStream->IsDestroyed()) {
+        // Probably the DOM MediaStream was GCed. Clean up.
+        os.mPort->Destroy();
+        mOutputStreams.RemoveElementAt(i);
+        continue;
+      }
       if (os.mFinishWhenEnded) {
         // Shouldn't really be needed since mDecodedStream should already have
         // finished, but doesn't hurt.
         os.mStream->Finish();
         os.mPort->Destroy();
-        os.mPort = nullptr;
         // Not really needed but it keeps the invariant that a stream not
         // connected to mDecodedStream is explicity blocked.
         os.mStream->ChangeExplicitBlockerCount(1);
         mOutputStreams.RemoveElementAt(i);
       }
     }
   }
 
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -653,17 +653,16 @@ public:
 
   // Send a new set of metadata to the state machine, to be dispatched to the
   // main thread to be presented when the |currentTime| of the media is greater
   // or equal to aPublishTime.
   void QueueMetadata(int64_t aPublishTime,
                      int aChannels,
                      int aRate,
                      bool aHasAudio,
-                     bool aHasVideo,
                      MetadataTags* aTags);
 
   /******
    * The following methods must only be called on the main
    * thread.
    ******/
 
   // Change to a new play state. This updates the mState variable and
@@ -672,17 +671,17 @@ public:
   void ChangeState(PlayState aState);
 
   // May be called by the reader to notify this decoder that the metadata from
   // the media file has been read. Call on the decode thread only.
   void OnReadMetadataCompleted() MOZ_OVERRIDE { }
 
   // Called when the metadata from the media file has been loaded by the
   // state machine. Call on the main thread only.
-  void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags);
+  void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags);
 
   // Called when the first frame has been loaded.
   // Call on the main thread only.
   void FirstFrameLoaded();
 
   // Returns true if the resource has been loaded. Must be in monitor.
   // Call from any thread.
   virtual bool IsDataCachedToEndOfResource();
--- a/content/media/MediaDecoderOwner.h
+++ b/content/media/MediaDecoderOwner.h
@@ -51,17 +51,16 @@ public:
                                     float aTime) = 0;
 
   // Called by the video decoder object, on the main thread,
   // when it has read the metadata containing video dimensions,
   // etc.
   virtual void MetadataLoaded(int aChannels,
                               int aRate,
                               bool aHasAudio,
-                              bool aHasVideo,
                               const MetadataTags* aTags) = 0;
 
   // Called by the video decoder object, on the main thread,
   // when it has read the first frame of the video
   // aResourceFullyLoaded should be true if the resource has been
   // fully loaded and the caller will call ResourceLoaded next.
   virtual void FirstFrameLoaded(bool aResourceFullyLoaded) = 0;
 
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -501,17 +501,18 @@ void MediaDecoderStateMachine::DecodeThr
   
   mReader->OnDecodeThreadFinish();
 }
 
 void MediaDecoderStateMachine::SendStreamAudio(AudioData* aAudio,
                                                DecodedStreamData* aStream,
                                                AudioSegment* aOutput)
 {
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
+  NS_ASSERTION(OnDecodeThread() ||
+               OnStateMachineThread(), "Should be on decode thread or state machine thread");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (aAudio->mTime <= aStream->mLastAudioPacketTime) {
     // ignore packet that we've already processed
     return;
   }
   aStream->mLastAudioPacketTime = aAudio->mTime;
   aStream->mLastAudioPacketEndTime = aAudio->GetEnd();
@@ -1205,25 +1206,24 @@ uint32_t MediaDecoderStateMachine::PlayS
   WriteSilence(mAudioStream, frames);
   // Dispatch events to the DOM for the audio just written.
   mEventManager.QueueWrittenAudioData(nullptr, frames * aChannels,
                                       (aFrameOffset + frames) * aChannels);
   return frames;
 }
 
 uint32_t MediaDecoderStateMachine::PlayFromAudioQueue(uint64_t aFrameOffset,
-                                                          uint32_t aChannels)
+                                                      uint32_t aChannels)
 {
   NS_ASSERTION(OnAudioThread(), "Only call on audio thread.");
   NS_ASSERTION(!mAudioStream->IsPaused(), "Don't play when paused");
   nsAutoPtr<AudioData> audio(mReader->AudioQueue().PopFront());
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     NS_WARN_IF_FALSE(IsPlaying(), "Should be playing");
-    NS_ASSERTION(!mAudioCaptured, "Audio cannot be captured here!");
     // Awaken the decode loop if it's waiting for space to free up in the
     // audio queue.
     mDecoder->GetReentrantMonitor().NotifyAll();
   }
   int64_t offset = -1;
   uint32_t frames = 0;
   if (!PR_GetEnv("MOZ_QUIET")) {
     LOG(PR_LOG_DEBUG, ("%p Decoder playing %d frames of data to stream for AudioData at %lld",
@@ -1856,17 +1856,16 @@ nsresult MediaDecoderStateMachine::Decod
     mDecoder->RequestFrameBufferLength(frameBufferLength);
   }
 
   nsCOMPtr<nsIRunnable> metadataLoadedEvent =
     new AudioMetadataEventRunner(mDecoder,
                                  mInfo.mAudioChannels,
                                  mInfo.mAudioRate,
                                  HasAudio(),
-                                 HasVideo(),
                                  tags);
   NS_DispatchToMainThread(metadataLoadedEvent, NS_DISPATCH_NORMAL);
 
   if (mState == DECODER_STATE_DECODING_METADATA) {
     LOG(PR_LOG_DEBUG, ("%p Changed state from DECODING_METADATA to DECODING", mDecoder.get()));
     StartDecoding();
   }
 
@@ -2782,22 +2781,17 @@ void MediaDecoderStateMachine::SetPreser
 }
 
 bool MediaDecoderStateMachine::IsShutdown()
 {
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   return GetState() == DECODER_STATE_SHUTDOWN;
 }
 
-void MediaDecoderStateMachine::QueueMetadata(int64_t aPublishTime,
-                                             int aChannels,
-                                             int aRate,
-                                             bool aHasAudio,
-                                             bool aHasVideo,
-                                             MetadataTags* aTags)
+void MediaDecoderStateMachine::QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags)
 {
   NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   TimedMetadata* metadata = new TimedMetadata;
   metadata->mPublishTime = aPublishTime;
   metadata->mChannels = aChannels;
   metadata->mRate = aRate;
   metadata->mHasAudio = aHasAudio;
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -314,17 +314,17 @@ public:
   void FinishStreamData();
   bool HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs);
   bool HaveEnoughDecodedVideo();
 
   // Returns true if the state machine has shutdown or is in the process of
   // shutting down. The decoder monitor must be held while calling this.
   bool IsShutdown();
 
-  void QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, bool aHasVideo, MetadataTags* aTags);
+  void QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags);
 
 protected:
   virtual uint32_t GetAmpleVideoFrames() { return mAmpleVideoFrames; }
 
 private:
   class WakeDecoderRunnable : public nsRunnable {
   public:
     WakeDecoderRunnable(MediaDecoderStateMachine* aSM)
--- a/content/media/MediaMetadataManager.h
+++ b/content/media/MediaMetadataManager.h
@@ -23,18 +23,16 @@ namespace mozilla {
       // the main threads.
       nsAutoPtr<MetadataTags> mTags;
       // The sample rate of this media.
       int mRate;
       // The number of channel of this media.
       int mChannels;
       // True if this media has an audio track.
       bool mHasAudio;
-      // True if this media has a video track.
-      bool mHasVideo;
   };
 
   // This class encapsulate the logic to give the metadata from the reader to
   // the content, at the right time.
   class MediaMetadataManager
   {
     public:
       ~MediaMetadataManager() {
@@ -50,17 +48,16 @@ namespace mozilla {
       void DispatchMetadataIfNeeded(AbstractMediaDecoder* aDecoder, double aCurrentTime) {
         TimedMetadata* metadata = mMetadataQueue.getFirst();
         while (metadata && aCurrentTime >= static_cast<double>(metadata->mPublishTime) / USECS_PER_S) {
           nsCOMPtr<nsIRunnable> metadataUpdatedEvent =
             new mozilla::AudioMetadataEventRunner(aDecoder,
                                                   metadata->mChannels,
                                                   metadata->mRate,
                                                   metadata->mHasAudio,
-                                                  metadata->mHasVideo,
                                                   metadata->mTags.forget());
           NS_DispatchToMainThread(metadataUpdatedEvent, NS_DISPATCH_NORMAL);
           mMetadataQueue.popFirst();
           metadata = mMetadataQueue.getFirst();
         }
       }
     protected:
       LinkedList<TimedMetadata> mMetadataQueue;
--- a/content/media/VideoFrameContainer.cpp
+++ b/content/media/VideoFrameContainer.cpp
@@ -62,34 +62,25 @@ void VideoFrameContainer::SetCurrentFram
   if (oldFrameSize != newFrameSize) {
     mImageSizeChanged = true;
     mNeedInvalidation = true;
   }
 
   mPaintTarget = aTargetTime;
 }
 
-void VideoFrameContainer::Reset()
-{
-  ClearCurrentFrame(true);
-  Invalidate();
-  mPaintDelay = TimeDuration();
-  mImageContainer->ResetPaintCount();
-}
-
-void VideoFrameContainer::ClearCurrentFrame(bool aResetSize)
+void VideoFrameContainer::ClearCurrentFrame()
 {
   MutexAutoLock lock(mMutex);
 
   // See comment in SetCurrentFrame for the reasoning behind
   // using a kungFuDeathGrip here.
   nsRefPtr<Image> kungFuDeathGrip;
   kungFuDeathGrip = mImageContainer->LockCurrentImage();
   mImageContainer->UnlockCurrentImage();
-  mImageSizeChanged = aResetSize;
 
   mImageContainer->SetCurrentImage(nullptr);
 
   // We removed the current image so we will have to invalidate once
   // again to setup the ImageContainer <-> Compositor pair.
   mNeedInvalidation = true;
 }
 
--- a/content/media/VideoFrameContainer.h
+++ b/content/media/VideoFrameContainer.h
@@ -41,19 +41,17 @@ public:
 
   VideoFrameContainer(nsHTMLMediaElement* aElement,
                       already_AddRefed<ImageContainer> aContainer);
   ~VideoFrameContainer();
 
   // Call on any thread
   void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage,
                        TimeStamp aTargetTime);
-  void ClearCurrentFrame(bool aResetSize = false);
-  // Reset the VideoFrameContainer
-  void Reset();
+  void ClearCurrentFrame();
   // Time in seconds by which the last painted video frame was late by.
   // E.g. if the last painted frame should have been painted at time t,
   // but was actually painted at t+n, this returns n in seconds. Threadsafe.
   double GetFrameDelay();
   // Call on main thread
   void Invalidate();
   ImageContainer* GetImageContainer();
   void ForgetElement() { mElement = nullptr; }
--- a/content/media/ogg/OggReader.cpp
+++ b/content/media/ogg/OggReader.cpp
@@ -727,17 +727,16 @@ bool OggReader::ReadOggChain()
   if (chained) {
     SetChained(true);
     {
       ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       mDecoder->QueueMetadata((mDecodedAudioFrames * USECS_PER_S) / rate,
                                channels,
                                rate,
                                HasAudio(),
-                               HasVideo(),
                                tags);
     }
     return true;
   }
 
   return false;
 }
 
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -128,17 +128,17 @@ MOCHITEST_FILES = \
 		test_bug463162.xhtml \
 		test_decoder_disable.html \
 		test_media_selection.html \
 		test_playback.html \
 		test_seekLies.html \
 		test_media_sniffer.html \
 		contentType.sjs \
 		test_streams_srcObject.html \
-		test_reset_src.html \
+		test_streams_gc.html \
 		$(filter disabled-for-intermittent-failures--bug-608634, test_error_in_video_document.html) \
 		$(NULL)
 
 # Disabled on Windows for frequent intermittent failures
 ifneq ($(OS_ARCH), WINNT)
 MOCHITEST_FILES += \
 		test_streams_element_capture.html \
 		test_streams_element_capture_reset.html \
deleted file mode 100644
--- a/content/media/test/test_reset_src.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=804875
--->
-
-<head>
-  <title>Test for bug 804875</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="manifest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank"
-href="https://bugzilla.mozilla.org/show_bug.cgi?id=804875">Mozilla Bug 804875</a>
-
-<video style="border: 4px solid red" controls></video>
-<canvas></canvas>
-
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-function onLoadedMetadata_Audio(e) {
-  var t = e.target;
-  is(t.videoHeight, 0, "Audio should a zero for videoHeight.");
-  is(t.videoWidth, 0, "Audio should a zero for videoWidth.");
-  is(t.mozPaintedFrames, 0, "Audio should a zero for mozPaintedFrames.");
-  is(t.mozFrameDelay, 0, "Audio should a zero for mozFrameDelay.");
-  var c = document.getElementsByTagName("canvas")[0].getContext("2d");
-  try {
-    c.drawImage(t, 0, 0, t.videoHeight, t.videoWidth);
-  } catch (e) {
-    ok(true, "Trying to draw to a canvas should throw, since we don't have a frame anymore");
-    SimpleTest.finish();
-    return;
-  }
-  ok(false, "We should not succeed to draw a video frame on the canvas.");
-}
-
-function onTimeUpdate_Video(e) {
-  var t = e.target;
-  if (t.currentTime < t.duration / 4) {
-    return;
-  }
-  t.removeEventListener("timeupdate", onTimeUpdate_Video);
-  ok(t.mozPaintedFrames > 0, "mozPaintedFrames should be positive, is " + t.mozPaintedFrames + ".");
-  ok(t.mozFrameDelay >= 0, "mozFrameDelay should be positive, is " + t.mozFrameDelay + ".");
-
-  var source = getPlayableAudio(gPlayTests);
-  if (!source) {
-    todo("No audio file available.")
-    SimpleTest.finish();
-  } else {
-    t.removeEventListener("loadedmetadata", onLoadedMetadata_Video);
-    t.addEventListener("loadedmetadata", onLoadedMetadata_Audio);
-    t.src = source.name;
-  }
-}
-
-function onLoadedMetadata_Video(e) {
-  var t = e.target;
-  ok(t.videoHeight != 0, "We should have a videoHeight.");
-  ok(t.videoWidth != 0, "We should have a videoWidth.");
-  t.addEventListener("timeupdate", onTimeUpdate_Video);
-  t.play();
-}
-
-var v = document.getElementsByTagName("video")[0];
-var source = getPlayableVideo(gPlayTests);
-if (!source) {
-  todo("No video file available.");
-} else {
-  v.addEventListener("loadedmetadata", onLoadedMetadata_Video);
-  v.src = source.name;
-  dump(source.name);
-  SimpleTest.waitForExplicitFinish();
-}
-</script>
-</pre>
-</body>
-</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_streams_gc.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test garbage collection of captured stream (bug 806754)</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body onload="doTest()">
+<audio id="a"></audio>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var a = document.getElementById('a');
+a.src = getPlayableAudio(gSmallTests).name;
+
+function forceGC() {
+  SpecialPowers.gc();
+  SpecialPowers.forceGC();
+  SpecialPowers.forceCC();
+}
+
+function doTest() {
+  a.mozCaptureStreamUntilEnded();
+
+  a.addEventListener("seeked", function() {
+    a.play();
+
+    a.addEventListener("play", function() {
+      a.addEventListener("ended", function() {
+        ok(true, "GC completed OK");
+        SimpleTest.finish();
+      }, false);
+    }, false);
+  }, false);
+
+  a.currentTime = a.duration;
+  
+  setTimeout(forceGC, 0);
+}
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/webrtc/MediaEngine.h
+++ b/content/media/webrtc/MediaEngine.h
@@ -84,16 +84,21 @@ public:
                           SourceMediaStream *aSource,
                           TrackID aId,
                           StreamTime aDesiredTime,
                           TrackTicks &aLastEndTime) = 0;
 
   /* Stop the device and release the corresponding MediaStream */
   virtual nsresult Stop(SourceMediaStream *aSource, TrackID aID) = 0;
 
+  /* Change device configuration.  */
+  virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
+                          bool aAgcOn, uint32_t aAGC,
+                          bool aNoiseOn, uint32_t aNoise) = 0;
+
   /* Return false if device is currently allocated or started */
   bool IsAvailable() {
     if (mState == kAllocated || mState == kStarted) {
       return false;
     } else {
       return true;
     }
   }
--- a/content/media/webrtc/MediaEngineDefault.h
+++ b/content/media/webrtc/MediaEngineDefault.h
@@ -39,16 +39,19 @@ public:
   virtual void GetUUID(nsAString&);
 
   virtual const MediaEngineVideoOptions *GetOptions();
   virtual nsresult Allocate();
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop(SourceMediaStream*, TrackID);
   virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
+  virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
+                          bool aAgcOn, uint32_t aAGC,
+                          bool aNoiseOn, uint32_t aNoise) { return NS_OK; };
   virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
   virtual void NotifyPull(MediaStreamGraph* aGraph,
                           SourceMediaStream *aSource,
                           TrackID aId,
                           StreamTime aDesiredTime,
                           TrackTicks &aLastEndTime) {}
 
   NS_DECL_ISUPPORTS
@@ -81,16 +84,19 @@ public:
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
 
   virtual nsresult Allocate();
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop(SourceMediaStream*, TrackID);
   virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
+  virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
+                          bool aAgcOn, uint32_t aAGC,
+                          bool aNoiseOn, uint32_t aNoise) { return NS_OK; };
   virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
   virtual void NotifyPull(MediaStreamGraph* aGraph,
                           SourceMediaStream *aSource,
                           TrackID aId,
                           StreamTime aDesiredTime,
                           TrackTicks &aLastEndTime) {}
 
   NS_DECL_ISUPPORTS
--- a/content/media/webrtc/MediaEngineWebRTC.h
+++ b/content/media/webrtc/MediaEngineWebRTC.h
@@ -30,16 +30,17 @@
 // Audio Engine
 #include "voice_engine/include/voe_base.h"
 #include "voice_engine/include/voe_codec.h"
 #include "voice_engine/include/voe_hardware.h"
 #include "voice_engine/include/voe_network.h"
 #include "voice_engine/include/voe_audio_processing.h"
 #include "voice_engine/include/voe_volume_control.h"
 #include "voice_engine/include/voe_external_media.h"
+#include "voice_engine/include/voe_audio_processing.h"
 
 // Video Engine
 #include "video_engine/include/vie_base.h"
 #include "video_engine/include/vie_codec.h"
 #include "video_engine/include/vie_render.h"
 #include "video_engine/include/vie_capture.h"
 #include "video_engine/include/vie_file.h"
 
@@ -85,16 +86,19 @@ public:
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
   virtual const MediaEngineVideoOptions *GetOptions();
   virtual nsresult Allocate();
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop(SourceMediaStream*, TrackID);
   virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
+  virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
+                          bool aAgcOn, uint32_t aAGC,
+                          bool aNoiseOn, uint32_t aNoise) { return NS_OK; };
   virtual void NotifyPull(MediaStreamGraph* aGraph,
                           SourceMediaStream *aSource,
                           TrackID aId,
                           StreamTime aDesiredTime,
                           TrackTicks &aLastEndTime);
 
   NS_DECL_ISUPPORTS
 
@@ -172,16 +176,20 @@ class MediaEngineWebRTCAudioSource : pub
 public:
   MediaEngineWebRTCAudioSource(webrtc::VoiceEngine* aVoiceEnginePtr, int aIndex,
     const char* name, const char* uuid)
     : mVoiceEngine(aVoiceEnginePtr)
     , mMonitor("WebRTCMic.Monitor")
     , mCapIndex(aIndex)
     , mChannel(-1)
     , mInitDone(false)
+    , mEchoOn(false), mAgcOn(false), mNoiseOn(false)
+    , mEchoCancel(webrtc::kEcDefault)
+    , mAGC(webrtc::kAgcDefault)
+    , mNoiseSuppress(webrtc::kNsDefault)
     , mNullTransport(nullptr) {
     MOZ_ASSERT(aVoiceEnginePtr);
     mState = kReleased;
     mDeviceName.Assign(NS_ConvertUTF8toUTF16(name));
     mDeviceUUID.Assign(NS_ConvertUTF8toUTF16(uuid));
     Init();
   }
   ~MediaEngineWebRTCAudioSource() { Shutdown(); }
@@ -189,16 +197,20 @@ public:
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
 
   virtual nsresult Allocate();
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop(SourceMediaStream*, TrackID);
   virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
+  virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
+                          bool aAgcOn, uint32_t aAGC,
+                          bool aNoiseOn, uint32_t aNoise);
+
   virtual void NotifyPull(MediaStreamGraph* aGraph,
                           SourceMediaStream *aSource,
                           TrackID aId,
                           StreamTime aDesiredTime,
                           TrackTicks &aLastEndTime);
 
   // VoEMediaProcess.
   void Process(const int channel, const webrtc::ProcessingTypes type,
@@ -213,31 +225,37 @@ private:
 
   void Init();
   void Shutdown();
 
   webrtc::VoiceEngine* mVoiceEngine;
   webrtc::VoEBase* mVoEBase;
   webrtc::VoEExternalMedia* mVoERender;
   webrtc::VoENetwork*  mVoENetwork;
+  webrtc::VoEAudioProcessing *mVoEProcessing;
 
   // mMonitor protects mSources[] access/changes, and transitions of mState
   // from kStarted to kStopped (which are combined with EndTrack()).
   // mSources[] is accessed from webrtc threads.
   mozilla::ReentrantMonitor mMonitor;
   nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW
 
   int mCapIndex;
   int mChannel;
   TrackID mTrackID;
   bool mInitDone;
 
   nsString mDeviceName;
   nsString mDeviceUUID;
 
+  bool mEchoOn, mAgcOn, mNoiseOn;
+  webrtc::EcModes  mEchoCancel;
+  webrtc::AgcModes mAGC;
+  webrtc::NsModes  mNoiseSuppress;
+
   NullTransport *mNullTransport;
 };
 
 class MediaEngineWebRTC : public MediaEngine
 {
 public:
   MediaEngineWebRTC()
   : mMutex("mozilla::MediaEngineWebRTC")
--- a/content/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -42,16 +42,70 @@ MediaEngineWebRTCAudioSource::GetUUID(ns
   if (mInitDone) {
     aUUID.Assign(mDeviceUUID);
   }
 
   return;
 }
 
 nsresult
+MediaEngineWebRTCAudioSource::Config(bool aEchoOn, uint32_t aEcho,
+                                     bool aAgcOn, uint32_t aAGC,
+                                     bool aNoiseOn, uint32_t aNoise)
+{
+  LOG(("Audio config: aec: %d, agc: %d, noise: %d",
+       aEchoOn ? aEcho : -1,
+       aAgcOn ? aAGC : -1,
+       aNoiseOn ? aNoise : -1));
+
+  bool update_agc = (mAgcOn == aAgcOn);
+  bool update_noise = (mNoiseOn == aNoiseOn);
+  mAgcOn = aAgcOn;
+  mNoiseOn = aNoiseOn;
+
+  if ((webrtc::AgcModes) aAGC != webrtc::kAgcUnchanged) {
+    if (mAGC != (webrtc::AgcModes) aAGC) {
+      update_agc = true;
+      mAGC = (webrtc::AgcModes) aAGC;
+    }
+  }
+  if ((webrtc::NsModes) aNoise != webrtc::kNsUnchanged) {
+    if (mNoiseSuppress != (webrtc::NsModes) aNoise) {
+      update_noise = true;
+      mNoiseSuppress = (webrtc::NsModes) aNoise;
+    }
+  }
+
+  if (mInitDone) {
+    int error;
+#if 0
+    // Until we can support feeding our full output audio from the browser
+    // through the MediaStream, this won't work.  Or we need to move AEC to
+    // below audio input and output, perhaps invoked from here.
+    mEchoOn = aEchoOn;
+    if ((webrtc::EcModes) aEcho != webrtc::kEcUnchanged)
+      mEchoCancel = (webrtc::EcModes) aEcho;
+    mVoEProcessing->SetEcStatus(mEchoOn, aEcho);
+#else
+    (void) aEcho; (void) aEchoOn; // suppress warnings
+#endif
+
+    if (update_agc &&
+      0 != (error = mVoEProcessing->SetAgcStatus(mAgcOn, (webrtc::AgcModes) aAGC))) {
+      LOG(("%s Error setting AGC Status: %d ",__FUNCTION__, error));
+    }
+    if (update_noise &&
+      0 != (error = mVoEProcessing->SetNsStatus(mNoiseOn, (webrtc::NsModes) aNoise))) {
+      LOG(("%s Error setting NoiseSuppression Status: %d ",__FUNCTION__, error));
+    }
+  }
+  return NS_OK;
+}
+
+nsresult
 MediaEngineWebRTCAudioSource::Allocate()
 {
   if (mState == kReleased && mInitDone) {
     webrtc::VoEHardware* ptrVoEHw = webrtc::VoEHardware::GetInterface(mVoiceEngine);
     int res = ptrVoEHw->SetRecordingDevice(mCapIndex);
     ptrVoEHw->Release();
     if (res) {
       return NS_ERROR_FAILURE;
@@ -101,16 +155,21 @@ MediaEngineWebRTCAudioSource::Start(Sour
   LOG(("Initial audio"));
   mTrackID = aID;
 
   if (mState == kStarted) {
     return NS_OK;
   }
   mState = kStarted;
 
+  // Configure audio processing in webrtc code
+  Config(mEchoOn, webrtc::kEcUnchanged,
+         mAgcOn, webrtc::kAgcUnchanged,
+         mNoiseOn, webrtc::kNsUnchanged);
+
   if (mVoEBase->StartReceive(mChannel)) {
     return NS_ERROR_FAILURE;
   }
   if (mVoEBase->StartSend(mChannel)) {
     return NS_ERROR_FAILURE;
   }
 
   // Attach external media processor, so this::Process will be called.
@@ -187,16 +246,21 @@ MediaEngineWebRTCAudioSource::Init()
   if (!mVoERender) {
     return;
   }
   mVoENetwork = webrtc::VoENetwork::GetInterface(mVoiceEngine);
   if (!mVoENetwork) {
     return;
   }
 
+  mVoEProcessing = webrtc::VoEAudioProcessing::GetInterface(mVoiceEngine);
+  if (!mVoEProcessing) {
+    return;
+  }
+
   mChannel = mVoEBase->CreateChannel();
   if (mChannel < 0) {
     return;
   }
   mNullTransport = new NullTransport();
   if (mVoENetwork->RegisterExternalTransport(mChannel, *mNullTransport)) {
     return;
   }
--- a/content/svg/content/src/DOMSVGTests.cpp
+++ b/content/svg/content/src/DOMSVGTests.cpp
@@ -8,86 +8,54 @@
 #include "nsSVGFeatures.h"
 #include "mozilla/dom/SVGSwitchElement.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsStyleUtil.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
-NS_IMPL_ISUPPORTS1(DOMSVGTests, nsIDOMSVGTests)
+NS_IMPL_ISUPPORTS0(DOMSVGTests)
 
 nsIAtom** DOMSVGTests::sStringListNames[3] =
 {
   &nsGkAtoms::requiredFeatures,
   &nsGkAtoms::requiredExtensions,
   &nsGkAtoms::systemLanguage,
 };
 
 DOMSVGTests::DOMSVGTests()
 {
   mStringListAttributes[LANGUAGE].SetIsCommaSeparated(true);
 }
 
-/* readonly attribute nsIDOMSVGStringList requiredFeatures; */
-NS_IMETHODIMP
-DOMSVGTests::GetRequiredFeatures(nsIDOMSVGStringList * *aRequiredFeatures)
-{
-  *aRequiredFeatures = RequiredFeatures().get();
-  return NS_OK;
-}
-
 already_AddRefed<nsIDOMSVGStringList>
 DOMSVGTests::RequiredFeatures()
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
   return DOMSVGStringList::GetDOMWrapper(
            &mStringListAttributes[FEATURES], element, true, FEATURES).get();
 }
 
-/* readonly attribute nsIDOMSVGStringList requiredExtensions; */
-NS_IMETHODIMP
-DOMSVGTests::GetRequiredExtensions(nsIDOMSVGStringList * *aRequiredExtensions)
-{
-  *aRequiredExtensions = RequiredExtensions().get();
-  return NS_OK;
-}
-
 already_AddRefed<nsIDOMSVGStringList>
 DOMSVGTests::RequiredExtensions()
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
   return DOMSVGStringList::GetDOMWrapper(
            &mStringListAttributes[EXTENSIONS], element, true, EXTENSIONS).get();
 }
 
-/* readonly attribute nsIDOMSVGStringList systemLanguage; */
-NS_IMETHODIMP
-DOMSVGTests::GetSystemLanguage(nsIDOMSVGStringList * *aSystemLanguage)
-{
-  *aSystemLanguage = SystemLanguage().get();
-  return NS_OK;
-}
-
 already_AddRefed<nsIDOMSVGStringList>
 DOMSVGTests::SystemLanguage()
 {
   nsCOMPtr<nsSVGElement> element = do_QueryInterface(this);
   return DOMSVGStringList::GetDOMWrapper(
            &mStringListAttributes[LANGUAGE], element, true, LANGUAGE).get();
 }
 
-/* boolean hasExtension (in DOMString extension); */
-NS_IMETHODIMP
-DOMSVGTests::HasExtension(const nsAString & extension, bool *_retval)
-{
-  *_retval = HasExtension(extension);
-  return NS_OK;
-}
-
 bool
 DOMSVGTests::HasExtension(const nsAString& aExtension)
 {
   return nsSVGFeatures::HasExtension(aExtension);
 }
 
 bool
 DOMSVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
--- a/content/svg/content/src/DOMSVGTests.h
+++ b/content/svg/content/src/DOMSVGTests.h
@@ -1,34 +1,38 @@
 /* -*- 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/. */
 
 #ifndef MOZILLA_DOMSVGTESTS_H__
 #define MOZILLA_DOMSVGTESTS_H__
 
-#include "nsIDOMSVGTests.h"
 #include "nsStringFwd.h"
 #include "SVGStringList.h"
 #include "nsCOMPtr.h"
 
 class nsAttrValue;
 class nsIAtom;
+class nsIDOMSVGStringList;
 class nsString;
 
 namespace mozilla {
 class DOMSVGStringList;
 }
 
-class DOMSVGTests : public nsIDOMSVGTests
+#define MOZILLA_DOMSVGTESTS_IID \
+   { 0x92370da8, 0xda28, 0x4895, \
+     {0x9b, 0x1b, 0xe0, 0x06, 0x0d, 0xb7, 0x3f, 0xc3 } }
+
+class DOMSVGTests : public nsISupports
 {
 public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGTESTS_IID)
   NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMSVGTESTS
 
   DOMSVGTests();
   virtual ~DOMSVGTests() {}
 
   friend class mozilla::DOMSVGStringList;
   typedef mozilla::SVGStringList SVGStringList;
 
   /**
@@ -92,9 +96,11 @@ public:
   bool HasExtension(const nsAString& aExtension);
 
 private:
   enum { FEATURES, EXTENSIONS, LANGUAGE };
   SVGStringList mStringListAttributes[3];
   static nsIAtom** sStringListNames[3];
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGTests, MOZILLA_DOMSVGTESTS_IID)
+
 #endif // MOZILLA_DOMSVGTESTS_H__
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -44,17 +44,16 @@ CPPSRCS		= \
 		nsSVGElementFactory.cpp \
 		nsSVGEnum.cpp \
 		nsSVGFeatures.cpp \
 		nsSVGFilterElement.cpp \
 		nsSVGFilters.cpp \
 		nsSVGInteger.cpp \
 		nsSVGIntegerPair.cpp \
 		nsSVGLength2.cpp \
-		nsSVGMarkerElement.cpp \
 		nsSVGNumber2.cpp \
 		nsSVGNumberPair.cpp \
 		nsSVGPathDataParser.cpp \
 		nsSVGPathGeometryElement.cpp \
 		nsSVGPolyElement.cpp \
 		nsSVGString.cpp \
 		nsSVGRect.cpp \
 		nsSVGUnknownElement.cpp \
@@ -89,16 +88,17 @@ CPPSRCS		= \
 		SVGGraphicsElement.cpp \
 		SVGImageElement.cpp \
 		SVGIntegerPairSMILType.cpp \
 		SVGLength.cpp \
 		SVGLengthList.cpp \
 		SVGLengthListSMILType.cpp \
 		SVGLineElement.cpp \
 		SVGLocatableElement.cpp \
+		SVGMarkerElement.cpp \
 		SVGMaskElement.cpp \
 		SVGMatrix.cpp \
 		SVGMetadataElement.cpp \
 		SVGMotionSMILType.cpp \
 		SVGMotionSMILAttr.cpp \
 		SVGMotionSMILAnimationFunction.cpp \
 		SVGMotionSMILPathUtils.cpp \
 		SVGMPathElement.cpp \
@@ -172,16 +172,17 @@ EXPORTS_mozilla/dom = \
 	SVGEllipseElement.h \
 	SVGForeignObjectElement.h \
 	SVGGElement.h \
 	SVGGradientElement.h \
 	SVGGraphicsElement.h \
 	SVGImageElement.h \
 	SVGLineElement.h \
 	SVGLocatableElement.h \
+	SVGMarkerElement.h \
 	SVGMaskElement.h \
 	SVGMatrix.h \
 	SVGMetadataElement.h \
 	SVGMPathElement.h \
 	SVGPathElement.h \
 	SVGPatternElement.h \
 	SVGPolygonElement.h \
 	SVGPolylineElement.h \
--- a/content/svg/content/src/SVGAnimatedAngle.cpp
+++ b/content/svg/content/src/SVGAnimatedAngle.cpp
@@ -25,21 +25,17 @@ JSObject*
 SVGAnimatedAngle::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
 {
   return SVGAnimatedAngleBinding::Wrap(aCx, aScope, this, aTriedToWrap);
 }
 
 already_AddRefed<SVGAngle>
 SVGAnimatedAngle::BaseVal()
 {
-  nsRefPtr<SVGAngle> angle;
-  mVal->ToDOMBaseVal(getter_AddRefs(angle), mSVGElement);
-  return angle.forget();
+  return mVal->ToDOMBaseVal(mSVGElement);
 }
 
 already_AddRefed<SVGAngle>
 SVGAnimatedAngle::AnimVal()
 {
-  nsRefPtr<SVGAngle> angle;
-  mVal->ToDOMAnimVal(getter_AddRefs(angle), mSVGElement);
-  return angle.forget();
+  return mVal->ToDOMAnimVal(mSVGElement);
 }
 
--- a/content/svg/content/src/SVGAnimatedAngle.h
+++ b/content/svg/content/src/SVGAnimatedAngle.h
@@ -24,22 +24,16 @@ public:
 
   SVGAnimatedAngle(nsSVGAngle* aVal, nsSVGElement *aSVGElement)
     : mVal(aVal), mSVGElement(aSVGElement)
   {
     SetIsDOMBinding();
   }
   ~SVGAnimatedAngle();
 
-  NS_IMETHOD GetBaseVal(nsISupports **aBaseVal)
-    { *aBaseVal = BaseVal().get(); return NS_OK; }
-
-  NS_IMETHOD GetAnimVal(nsISupports **aAnimVal)
-    { *aAnimVal = AnimVal().get(); return NS_OK; }
-
   // WebIDL
   nsSVGElement* GetParentObject() { return mSVGElement; }
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap);
   already_AddRefed<SVGAngle> BaseVal();
   already_AddRefed<SVGAngle> AnimVal();
 
 protected:
   nsSVGAngle* mVal; // kept alive because it belongs to content
--- a/content/svg/content/src/SVGAnimationElement.cpp
+++ b/content/svg/content/src/SVGAnimationElement.cpp
@@ -18,17 +18,17 @@ namespace dom {
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGAnimationElement, SVGAnimationElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGAnimationElement, SVGAnimationElementBase)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAnimationElement)
   NS_INTERFACE_MAP_ENTRY(nsISMILAnimationElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMElementTimeControl)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
+  NS_INTERFACE_MAP_ENTRY(DOMSVGTests)
 NS_INTERFACE_MAP_END_INHERITING(SVGAnimationElementBase)
 
 // Cycle collection magic -- based on nsSVGUseElement
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGAnimationElement,
                                                 SVGAnimationElementBase)
   tmp->mHrefTarget.Unlink();
   tmp->mTimedElement.Unlink();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/svg/content/src/SVGGraphicsElement.cpp
+++ b/content/svg/content/src/SVGGraphicsElement.cpp
@@ -11,17 +11,17 @@ namespace dom {
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGGraphicsElement, SVGGraphicsElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGGraphicsElement, SVGGraphicsElementBase)
 
 NS_INTERFACE_MAP_BEGIN(SVGGraphicsElement)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
+  NS_INTERFACE_MAP_ENTRY(DOMSVGTests)
 NS_INTERFACE_MAP_END_INHERITING(SVGGraphicsElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGGraphicsElement::SVGGraphicsElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGGraphicsElementBase(aNodeInfo)
 {
rename from content/svg/content/src/nsSVGMarkerElement.cpp
rename to content/svg/content/src/SVGMarkerElement.cpp
--- a/content/svg/content/src/nsSVGMarkerElement.cpp
+++ b/content/svg/content/src/SVGMarkerElement.cpp
@@ -4,79 +4,88 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Util.h"
 
 #include "nsGkAtoms.h"
 #include "nsCOMPtr.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsError.h"
-#include "nsSVGMarkerElement.h"
+#include "mozilla/dom/SVGAngle.h"
+#include "mozilla/dom/SVGAnimatedAngle.h"
+#include "mozilla/dom/SVGAnimatedLength.h"
+#include "mozilla/dom/SVGMarkerElement.h"
+#include "mozilla/dom/SVGMarkerElementBinding.h"
 #include "gfxMatrix.h"
 #include "nsContentUtils.h" // NS_ENSURE_FINITE
 #include "SVGContentUtils.h"
-#include "SVGAngle.h"
+
+NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Marker)
+
+DOMCI_NODE_DATA(SVGMarkerElement, mozilla::dom::SVGMarkerElement)
+
+namespace mozilla {
+namespace dom {
 
-using namespace mozilla;
-using namespace mozilla::dom;
+JSObject*
+SVGMarkerElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return SVGMarkerElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
 
-nsSVGElement::LengthInfo nsSVGMarkerElement::sLengthInfo[4] =
+nsSVGElement::LengthInfo SVGMarkerElement::sLengthInfo[4] =
 {
   { &nsGkAtoms::refX, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
   { &nsGkAtoms::refY, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
   { &nsGkAtoms::markerWidth, 3, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
   { &nsGkAtoms::markerHeight, 3, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
 };
 
-nsSVGEnumMapping nsSVGMarkerElement::sUnitsMap[] = {
+nsSVGEnumMapping SVGMarkerElement::sUnitsMap[] = {
   {&nsGkAtoms::strokeWidth, nsIDOMSVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH},
   {&nsGkAtoms::userSpaceOnUse, nsIDOMSVGMarkerElement::SVG_MARKERUNITS_USERSPACEONUSE},
   {nullptr, 0}
 };
 
-nsSVGElement::EnumInfo nsSVGMarkerElement::sEnumInfo[1] =
+nsSVGElement::EnumInfo SVGMarkerElement::sEnumInfo[1] =
 {
   { &nsGkAtoms::markerUnits,
     sUnitsMap,
     nsIDOMSVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH
   }
 };
 
-nsSVGElement::AngleInfo nsSVGMarkerElement::sAngleInfo[1] =
+nsSVGElement::AngleInfo SVGMarkerElement::sAngleInfo[1] =
 {
   { &nsGkAtoms::orient, 0, SVG_ANGLETYPE_UNSPECIFIED }
 };
 
-NS_IMPL_NS_NEW_SVG_ELEMENT(Marker)
-
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGOrientType::DOMAnimatedEnum, mSVGElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGOrientType::DOMAnimatedEnum)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGOrientType::DOMAnimatedEnum)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGOrientType::DOMAnimatedEnum)
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedEnumeration)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedEnumeration)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF_INHERITED(nsSVGMarkerElement,nsSVGMarkerElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGMarkerElement,nsSVGMarkerElementBase)
+NS_IMPL_ADDREF_INHERITED(SVGMarkerElement,SVGMarkerElementBase)
+NS_IMPL_RELEASE_INHERITED(SVGMarkerElement,SVGMarkerElementBase)
 
-DOMCI_NODE_DATA(SVGMarkerElement, nsSVGMarkerElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGMarkerElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGMarkerElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGFitToViewBox,
+NS_INTERFACE_TABLE_HEAD(SVGMarkerElement)
+  NS_NODE_INTERFACE_TABLE4(SVGMarkerElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement,
                            nsIDOMSVGMarkerElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMarkerElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGMarkerElementBase)
+NS_INTERFACE_MAP_END_INHERITING(SVGMarkerElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsresult
 nsSVGOrientType::SetBaseValue(uint16_t aValue,
                               nsSVGElement *aSVGElement)
 {
@@ -88,277 +97,333 @@ nsSVGOrientType::SetBaseValue(uint16_t a
       (aValue ==nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_AUTO ?
         NS_LITERAL_STRING("auto") : NS_LITERAL_STRING("0")),
       true);
     return NS_OK;
   }
   return NS_ERROR_DOM_SYNTAX_ERR;
 }
 
-nsresult
-nsSVGOrientType::ToDOMAnimatedEnum(nsIDOMSVGAnimatedEnumeration **aResult,
-                                   nsSVGElement *aSVGElement)
+already_AddRefed<nsIDOMSVGAnimatedEnumeration>
+nsSVGOrientType::ToDOMAnimatedEnum(nsSVGElement *aSVGElement)
 {
-  *aResult = new DOMAnimatedEnum(this, aSVGElement);
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*aResult);
-  return NS_OK;
+  nsCOMPtr<nsIDOMSVGAnimatedEnumeration> toReturn =
+    new DOMAnimatedEnum(this, aSVGElement);
+  return toReturn.forget();
 }
 
-nsSVGMarkerElement::nsSVGMarkerElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsSVGMarkerElementBase(aNodeInfo), mCoordCtx(nullptr)
+SVGMarkerElement::SVGMarkerElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : SVGMarkerElementBase(aNodeInfo), mCoordCtx(nullptr)
 {
+  SetIsDOMBinding();
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGMarkerElement)
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGMarkerElement)
 
 //----------------------------------------------------------------------
-// nsIDOMSVGFitToViewBox methods
 
-/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
-  NS_IMETHODIMP nsSVGMarkerElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
+already_AddRefed<nsIDOMSVGAnimatedRect>
+SVGMarkerElement::ViewBox()
 {
-  return mViewBox.ToDOMAnimatedRect(aViewBox, this);
+  nsCOMPtr<nsIDOMSVGAnimatedRect> rect;
+  mViewBox.ToDOMAnimatedRect(getter_AddRefs(rect), this);
+  return rect.forget();
 }
 
-/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
-NS_IMETHODIMP
-nsSVGMarkerElement::GetPreserveAspectRatio(nsISupports
-                                           **aPreserveAspectRatio)
+already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
+SVGMarkerElement::PreserveAspectRatio()
 {
   nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
   mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
-  ratio.forget(aPreserveAspectRatio);
-  return NS_OK;
+  return ratio.forget();
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGMarkerElement methods
 
 /* readonly attribute nsIDOMSVGAnimatedLength refX; */
-NS_IMETHODIMP nsSVGMarkerElement::GetRefX(nsIDOMSVGAnimatedLength * *aRefX)
+NS_IMETHODIMP SVGMarkerElement::GetRefX(nsIDOMSVGAnimatedLength * *aRefX)
 {
-  return mLengthAttributes[REFX].ToDOMAnimatedLength(aRefX, this);
+  *aRefX = RefX().get();
+  return NS_OK;
+}
+
+already_AddRefed<SVGAnimatedLength>
+SVGMarkerElement::RefX()
+{
+  return mLengthAttributes[REFX].ToDOMAnimatedLength(this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedLength refY; */
-NS_IMETHODIMP nsSVGMarkerElement::GetRefY(nsIDOMSVGAnimatedLength * *aRefY)
+NS_IMETHODIMP SVGMarkerElement::GetRefY(nsIDOMSVGAnimatedLength * *aRefY)
 {
-  return mLengthAttributes[REFY].ToDOMAnimatedLength(aRefY, this);
+  *aRefY = RefY().get();
+  return NS_OK;
+}
+
+already_AddRefed<SVGAnimatedLength>
+SVGMarkerElement::RefY()
+{
+  return mLengthAttributes[REFY].ToDOMAnimatedLength(this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedEnumeration markerUnits; */
-NS_IMETHODIMP nsSVGMarkerElement::GetMarkerUnits(nsIDOMSVGAnimatedEnumeration * *aMarkerUnits)
+NS_IMETHODIMP SVGMarkerElement::GetMarkerUnits(nsIDOMSVGAnimatedEnumeration * *aMarkerUnits)
 {
-  return mEnumAttributes[MARKERUNITS].ToDOMAnimatedEnum(aMarkerUnits, this);
+  *aMarkerUnits = MarkerUnits().get();
+  return NS_OK;
+}
+
+already_AddRefed<nsIDOMSVGAnimatedEnumeration>
+SVGMarkerElement::MarkerUnits()
+{
+  return mEnumAttributes[MARKERUNITS].ToDOMAnimatedEnum(this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedLength markerWidth; */
-NS_IMETHODIMP nsSVGMarkerElement::GetMarkerWidth(nsIDOMSVGAnimatedLength * *aMarkerWidth)
+NS_IMETHODIMP SVGMarkerElement::GetMarkerWidth(nsIDOMSVGAnimatedLength * *aMarkerWidth)
 {
-  return mLengthAttributes[MARKERWIDTH].ToDOMAnimatedLength(aMarkerWidth, this);
+  *aMarkerWidth = MarkerWidth().get();
+  return NS_OK;
+}
+
+already_AddRefed<SVGAnimatedLength>
+SVGMarkerElement::MarkerWidth()
+{
+  return mLengthAttributes[MARKERWIDTH].ToDOMAnimatedLength(this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedLength markerHeight; */
-NS_IMETHODIMP nsSVGMarkerElement::GetMarkerHeight(nsIDOMSVGAnimatedLength * *aMarkerHeight)
+NS_IMETHODIMP SVGMarkerElement::GetMarkerHeight(nsIDOMSVGAnimatedLength * *aMarkerHeight)
 {
-  return mLengthAttributes[MARKERHEIGHT].ToDOMAnimatedLength(aMarkerHeight, this);
+  *aMarkerHeight = MarkerHeight().get();
+  return NS_OK;
+}
+
+already_AddRefed<SVGAnimatedLength>
+SVGMarkerElement::MarkerHeight()
+{
+  return mLengthAttributes[MARKERHEIGHT].ToDOMAnimatedLength(this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedEnumeration orientType; */
-NS_IMETHODIMP nsSVGMarkerElement::GetOrientType(nsIDOMSVGAnimatedEnumeration * *aOrientType)
+NS_IMETHODIMP SVGMarkerElement::GetOrientType(nsIDOMSVGAnimatedEnumeration * *aOrientType)
 {
-  return mOrientType.ToDOMAnimatedEnum(aOrientType, this);
+  *aOrientType = OrientType().get();
+  return NS_OK;
+}
+
+already_AddRefed<nsIDOMSVGAnimatedEnumeration>
+SVGMarkerElement::OrientType()
+{
+  return mOrientType.ToDOMAnimatedEnum(this);
 }
 
 /* readonly attribute SVGAnimatedAngle orientAngle; */
-NS_IMETHODIMP nsSVGMarkerElement::GetOrientAngle(nsISupports * *aOrientAngle)
+NS_IMETHODIMP SVGMarkerElement::GetOrientAngle(nsISupports * *aOrientAngle)
 {
-  return mAngleAttributes[ORIENT].ToDOMAnimatedAngle(aOrientAngle, this);
+  *aOrientAngle = OrientAngle().get();
+  return NS_OK;
+}
+
+already_AddRefed<SVGAnimatedAngle>
+SVGMarkerElement::OrientAngle()
+{
+  return mAngleAttributes[ORIENT].ToDOMAnimatedAngle(this);
 }
 
 /* void setOrientToAuto (); */
-NS_IMETHODIMP nsSVGMarkerElement::SetOrientToAuto()
+NS_IMETHODIMP SVGMarkerElement::SetOrientToAuto()
 {
   SetAttr(kNameSpaceID_None, nsGkAtoms::orient, nullptr,
           NS_LITERAL_STRING("auto"), true);
   return NS_OK;
 }
 
 /* void setOrientToAngle (in SVGAngle angle); */
-NS_IMETHODIMP nsSVGMarkerElement::SetOrientToAngle(nsISupports *aAngle)
+NS_IMETHODIMP SVGMarkerElement::SetOrientToAngle(nsISupports *aAngle)
 {
   nsCOMPtr<dom::SVGAngle> angle = do_QueryInterface(aAngle);
   if (!angle)
     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
 
-  float f = angle->Value();
-  NS_ENSURE_FINITE(f, NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+  ErrorResult rv;
+  SetOrientToAngle(*angle, rv);
+  return rv.ErrorCode();
+}
+
+void
+SVGMarkerElement::SetOrientToAngle(SVGAngle& angle, ErrorResult& rv)
+{
+  float f = angle.Value();
+  if (!NS_finite(f)) {
+    rv.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return;
+  }
   mAngleAttributes[ORIENT].SetBaseValue(f, this, true);
-
-  return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 NS_IMETHODIMP_(bool)
-nsSVGMarkerElement::IsAttributeMapped(const nsIAtom* name) const
+SVGMarkerElement::IsAttributeMapped(const nsIAtom* name) const
 {
   static const MappedAttributeEntry* const map[] = {
     sFEFloodMap,
     sFiltersMap,
     sFontSpecificationMap,
     sGradientStopMap,
     sLightingEffectsMap,
     sMarkersMap,
     sTextContentElementsMap,
-    sViewportsMap
+    sViewportsMap,
+    sColorMap,
+    sFillStrokeMap,
+    sGraphicsMap
   };
 
   return FindAttributeDependence(name, map) ||
-    nsSVGMarkerElementBase::IsAttributeMapped(name);
+    SVGMarkerElementBase::IsAttributeMapped(name);
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 bool
-nsSVGMarkerElement::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                            nsAString &aResult) const
+SVGMarkerElement::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
+                          nsAString &aResult) const
 {
   if (aNameSpaceID == kNameSpaceID_None &&
       aName == nsGkAtoms::orient &&
       mOrientType.GetBaseValue() == SVG_MARKER_ORIENT_AUTO) {
     aResult.AssignLiteral("auto");
     return true;
   }
-  return nsSVGMarkerElementBase::GetAttr(aNameSpaceID, aName, aResult);
+  return SVGMarkerElementBase::GetAttr(aNameSpaceID, aName, aResult);
 }
 
 bool
-nsSVGMarkerElement::ParseAttribute(int32_t aNameSpaceID, nsIAtom* aName,
-                                   const nsAString& aValue,
-                                   nsAttrValue& aResult)
+SVGMarkerElement::ParseAttribute(int32_t aNameSpaceID, nsIAtom* aName,
+                                 const nsAString& aValue,
+                                 nsAttrValue& aResult)
 {
   if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::orient) {
     if (aValue.EqualsLiteral("auto")) {
       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO);
       aResult.SetTo(aValue);
       return true;
     }
     mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
   }
-  return nsSVGMarkerElementBase::ParseAttribute(aNameSpaceID, aName,
-                                                aValue, aResult);
+  return SVGMarkerElementBase::ParseAttribute(aNameSpaceID, aName,
+                                              aValue, aResult);
 }
 
 nsresult
-nsSVGMarkerElement::UnsetAttr(int32_t aNamespaceID, nsIAtom* aName,
-                              bool aNotify)
+SVGMarkerElement::UnsetAttr(int32_t aNamespaceID, nsIAtom* aName,
+                            bool aNotify)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aName == nsGkAtoms::orient) {
       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
     }
   }
 
   return nsSVGElement::UnsetAttr(aNamespaceID, aName, aNotify);
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 void
-nsSVGMarkerElement::SetParentCoordCtxProvider(SVGSVGElement *aContext)
+SVGMarkerElement::SetParentCoordCtxProvider(SVGSVGElement *aContext)
 {
   mCoordCtx = aContext;
   mViewBoxToViewportTransform = nullptr;
 }
 
 /* virtual */ bool
-nsSVGMarkerElement::HasValidDimensions() const
+SVGMarkerElement::HasValidDimensions() const
 {
   return (!mLengthAttributes[MARKERWIDTH].IsExplicitlySet() ||
            mLengthAttributes[MARKERWIDTH].GetAnimValInSpecifiedUnits() > 0) &&
          (!mLengthAttributes[MARKERHEIGHT].IsExplicitlySet() || 
            mLengthAttributes[MARKERHEIGHT].GetAnimValInSpecifiedUnits() > 0);
 }
 
 nsSVGElement::LengthAttributesInfo
-nsSVGMarkerElement::GetLengthInfo()
+SVGMarkerElement::GetLengthInfo()
 {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
 
 nsSVGElement::AngleAttributesInfo
-nsSVGMarkerElement::GetAngleInfo()
+SVGMarkerElement::GetAngleInfo()
 {
   return AngleAttributesInfo(mAngleAttributes, sAngleInfo,
                              ArrayLength(sAngleInfo));
 }
 
 nsSVGElement::EnumAttributesInfo
-nsSVGMarkerElement::GetEnumInfo()
+SVGMarkerElement::GetEnumInfo()
 {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
                             ArrayLength(sEnumInfo));
 }
 
 nsSVGViewBox *
-nsSVGMarkerElement::GetViewBox()
+SVGMarkerElement::GetViewBox()
 {
   return &mViewBox;
 }
 
 SVGAnimatedPreserveAspectRatio *
-nsSVGMarkerElement::GetPreserveAspectRatio()
+SVGMarkerElement::GetPreserveAspectRatio()
 {
   return &mPreserveAspectRatio;
 }
 
 //----------------------------------------------------------------------
 // public helpers
 
 gfxMatrix
-nsSVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
-                                       float aX, float aY, float aAutoAngle)
+SVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
+                                     float aX, float aY, float aAutoAngle)
 {
   gfxFloat scale = mEnumAttributes[MARKERUNITS].GetAnimValue() ==
                      SVG_MARKERUNITS_STROKEWIDTH ? aStrokeWidth : 1.0;
 
   gfxFloat angle = mOrientType.GetAnimValue() == SVG_MARKER_ORIENT_AUTO ?
                     aAutoAngle :
                     mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0;
 
   return gfxMatrix(cos(angle) * scale,   sin(angle) * scale,
                    -sin(angle) * scale,  cos(angle) * scale,
                    aX,                    aY);
 }
 
 nsSVGViewBoxRect
-nsSVGMarkerElement::GetViewBoxRect()
+SVGMarkerElement::GetViewBoxRect()
 {
   if (mViewBox.IsExplicitlySet()) {
     return mViewBox.GetAnimValue();
   }
   return nsSVGViewBoxRect(
            0, 0,
            mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
            mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx));
 }
 
 gfxMatrix
-nsSVGMarkerElement::GetViewBoxTransform()
+SVGMarkerElement::GetViewBoxTransform()
 {
   if (!mViewBoxToViewportTransform) {
     float viewportWidth =
       mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx);
     float viewportHeight = 
       mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx);
    
     nsSVGViewBoxRect viewbox = GetViewBoxRect();
@@ -381,9 +446,10 @@ nsSVGMarkerElement::GetViewBoxTransform(
     gfxMatrix TM = viewBoxTM * gfxMatrix().Translate(gfxPoint(-ref.x, -ref.y));
 
     mViewBoxToViewportTransform = new gfxMatrix(TM);
   }
 
   return *mViewBoxToViewportTransform;
 }
 
-
+} // namespace dom
+} // namespace mozilla
rename from content/svg/content/src/nsSVGMarkerElement.h
rename to content/svg/content/src/SVGMarkerElement.h
--- a/content/svg/content/src/nsSVGMarkerElement.h
+++ b/content/svg/content/src/SVGMarkerElement.h
@@ -1,27 +1,34 @@
 /* -*- 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/. */
 
-#ifndef __NS_SVGMARKERELEMENT_H__
-#define __NS_SVGMARKERELEMENT_H__
+#ifndef mozilla_dom_SVGMarkerElement_h
+#define mozilla_dom_SVGMarkerElement_h
 
 #include "gfxMatrix.h"
-#include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGMarkerElement.h"
 #include "nsSVGAngle.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
-#include "SVGGraphicsElement.h"
+#include "nsSVGElement.h"
 #include "mozilla/Attributes.h"
 
+class nsSVGMarkerFrame;
+
+nsresult NS_NewSVGMarkerElement(nsIContent **aResult,
+                                already_AddRefed<nsINodeInfo> aNodeInfo);
+
+namespace mozilla {
+namespace dom {
+
 class nsSVGOrientType
 {
 public:
   nsSVGOrientType()
    : mAnimVal(nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_ANGLE),
      mBaseVal(nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_ANGLE) {}
 
   nsresult SetBaseValue(uint16_t aValue,
@@ -35,18 +42,18 @@ public:
   void SetAnimValue(uint16_t aValue)
     { mAnimVal = uint8_t(aValue); }
 
   uint16_t GetBaseValue() const
     { return mBaseVal; }
   uint16_t GetAnimValue() const
     { return mAnimVal; }
 
-  nsresult ToDOMAnimatedEnum(nsIDOMSVGAnimatedEnumeration **aResult,
-                             nsSVGElement* aSVGElement);
+  already_AddRefed<nsIDOMSVGAnimatedEnumeration>
+    ToDOMAnimatedEnum(nsSVGElement* aSVGElement);
 
 private:
   nsSVGEnumValue mAnimVal;
   nsSVGEnumValue mBaseVal;
 
   struct DOMAnimatedEnum MOZ_FINAL : public nsIDOMSVGAnimatedEnumeration
   {
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -63,37 +70,34 @@ private:
       { *aResult = mVal->GetBaseValue(); return NS_OK; }
     NS_IMETHOD SetBaseVal(uint16_t aValue)
       { return mVal->SetBaseValue(aValue, mSVGElement); }
     NS_IMETHOD GetAnimVal(uint16_t* aResult)
       { *aResult = mVal->GetAnimValue(); return NS_OK; }
   };
 };
 
-typedef mozilla::dom::SVGGraphicsElement nsSVGMarkerElementBase;
+typedef nsSVGElement SVGMarkerElementBase;
 
-class nsSVGMarkerElement : public nsSVGMarkerElementBase,
-                           public nsIDOMSVGMarkerElement,
-                           public nsIDOMSVGFitToViewBox
+class SVGMarkerElement : public SVGMarkerElementBase,
+                         public nsIDOMSVGMarkerElement
 {
-  friend class nsSVGMarkerFrame;
+  friend class ::nsSVGMarkerFrame;
 
 protected:
-  friend nsresult NS_NewSVGMarkerElement(nsIContent **aResult,
-                                         already_AddRefed<nsINodeInfo> aNodeInfo);
-  nsSVGMarkerElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  friend nsresult (::NS_NewSVGMarkerElement(nsIContent **aResult,
+                                            already_AddRefed<nsINodeInfo> aNodeInfo));
+  SVGMarkerElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
 
 public:
-  typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
-
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGMARKERELEMENT
-  NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
   // xxx I wish we could use virtual inheritance
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
@@ -114,23 +118,37 @@ public:
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   nsSVGOrientType* GetOrientType() { return &mOrientType; }
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  // WebIDL
+  already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox();
+  already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
+  already_AddRefed<SVGAnimatedLength> RefX();
+  already_AddRefed<SVGAnimatedLength> RefY();
+  already_AddRefed<nsIDOMSVGAnimatedEnumeration> MarkerUnits();
+  already_AddRefed<SVGAnimatedLength> MarkerWidth();
+  already_AddRefed<SVGAnimatedLength> MarkerHeight();
+  already_AddRefed<nsIDOMSVGAnimatedEnumeration> OrientType();
+  already_AddRefed<SVGAnimatedAngle> OrientAngle();
+  // We can use the XPIDL SetOrientToAuto
+  void SetOrientToAngle(SVGAngle& angle, ErrorResult& rv);
+
 protected:
 
   virtual bool ParseAttribute(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
 
-  void SetParentCoordCtxProvider(mozilla::dom::SVGSVGElement *aContext);
+  void SetParentCoordCtxProvider(SVGSVGElement *aContext);
 
   virtual LengthAttributesInfo GetLengthInfo();
   virtual AngleAttributesInfo GetAngleInfo();
   virtual EnumAttributesInfo GetEnumInfo();
   virtual nsSVGViewBox *GetViewBox();
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
 
   enum { REFX, REFY, MARKERWIDTH, MARKERHEIGHT };
@@ -147,13 +165,16 @@ protected:
   static AngleInfo sAngleInfo[1];
 
   nsSVGViewBox             mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
   // derived properties (from 'orient') handled separately
   nsSVGOrientType                        mOrientType;
 
-  mozilla::dom::SVGSVGElement                       *mCoordCtx;
+  SVGSVGElement                         *mCoordCtx;
   nsAutoPtr<gfxMatrix>                   mViewBoxToViewportTransform;
 };
 
-#endif
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_SVGMarkerElement_h
--- a/content/svg/content/src/SVGPatternElement.cpp
+++ b/content/svg/content/src/SVGPatternElement.cpp
@@ -55,19 +55,19 @@ nsSVGElement::StringInfo SVGPatternEleme
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGPatternElement,SVGPatternElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGPatternElement,SVGPatternElementBase)
 
 NS_INTERFACE_TABLE_HEAD(SVGPatternElement)
-  NS_NODE_INTERFACE_TABLE7(SVGPatternElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE6(SVGPatternElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement,
-                           nsIDOMSVGFitToViewBox, nsIDOMSVGURIReference,
+                           nsIDOMSVGURIReference,
                            nsIDOMSVGPatternElement, nsIDOMSVGUnitTypes)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPatternElement)
 NS_INTERFACE_MAP_END_INHERITING(SVGPatternElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGPatternElement::SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo)
@@ -77,41 +77,25 @@ SVGPatternElement::SVGPatternElement(alr
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode method
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGPatternElement)
 
 //----------------------------------------------------------------------
-// nsIDOMSVGFitToViewBox methods
-
-/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
-NS_IMETHODIMP SVGPatternElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
-{
-  *aViewBox = ViewBox().get();
-  return NS_OK;
-}
 
 already_AddRefed<nsIDOMSVGAnimatedRect>
 SVGPatternElement::ViewBox()
 {
   nsCOMPtr<nsIDOMSVGAnimatedRect> rect;
   mViewBox.ToDOMAnimatedRect(getter_AddRefs(rect), this);
   return rect.forget();
 }
 
-/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
-NS_IMETHODIMP
-SVGPatternElement::GetPreserveAspectRatio(nsISupports **aPreserveAspectRatio)
-{
-  *aPreserveAspectRatio = PreserveAspectRatio().get();
-  return NS_OK;
-}
-
 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
 SVGPatternElement::PreserveAspectRatio()
 {
   nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
   mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
   return ratio.forget();
 }
 
--- a/content/svg/content/src/SVGPatternElement.h
+++ b/content/svg/content/src/SVGPatternElement.h
@@ -1,17 +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/. */
 
 #ifndef mozilla_dom_SVGPatternElement_h
 #define mozilla_dom_SVGPatternElement_h
 
-#include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGPatternElement.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 #include "nsSVGElement.h"
 #include "nsSVGViewBox.h"
@@ -28,17 +27,16 @@ class DOMSVGAnimatedTransformList;
 
 namespace dom {
 
 typedef nsSVGElement SVGPatternElementBase;
 
 class SVGPatternElement MOZ_FINAL : public SVGPatternElementBase,
                                     public nsIDOMSVGPatternElement,
                                     public nsIDOMSVGURIReference,
-                                    public nsIDOMSVGFitToViewBox,
                                     public nsIDOMSVGUnitTypes
 {
   friend class ::nsSVGPatternFrame;
 
 protected:
   friend nsresult (::NS_NewSVGPatternElement(nsIContent **aResult,
                                              already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo);
@@ -51,19 +49,16 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // Pattern Element
   NS_DECL_NSIDOMSVGPATTERNELEMENT
 
   // URI Reference
   NS_DECL_NSIDOMSVGURIREFERENCE
 
-  // FitToViewbox
-  NS_DECL_NSIDOMSVGFITTOVIEWBOX
-
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@@ -112,17 +107,17 @@ protected:
 
   nsAutoPtr<mozilla::SVGAnimatedTransformList> mPatternTransform;
 
   // nsIDOMSVGURIReference properties
   enum { HREF };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 
-  // nsIDOMSVGFitToViewbox properties
+  // SVGFitToViewbox properties
   nsSVGViewBox mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_SVGPatternElement_h
--- a/content/svg/content/src/SVGSVGElement.cpp
+++ b/content/svg/content/src/SVGSVGElement.cpp
@@ -141,20 +141,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     tmp->mTimedDocumentRoot->Traverse(&cb);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(SVGSVGElement,SVGSVGElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGSVGElement,SVGSVGElementBase)
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGSVGElement)
-  NS_NODE_INTERFACE_TABLE5(SVGSVGElement, nsIDOMNode, nsIDOMElement,
+  NS_NODE_INTERFACE_TABLE4(SVGSVGElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement,
-                           nsIDOMSVGSVGElement,
-                           nsIDOMSVGFitToViewBox)
+                           nsIDOMSVGSVGElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSVGElement)
 NS_INTERFACE_MAP_END_INHERITING(SVGSVGElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGSVGElement::SVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                                  FromParser aFromParser)
@@ -670,43 +669,25 @@ SVGSVGElement::GetElementById(const nsAS
   nsIContent* element = QuerySelector(selector, rv);
   if (!rv.Failed() && element) {
     return element->AsElement();
   }
   return nullptr;
 }
 
 //----------------------------------------------------------------------
-// nsIDOMSVGFitToViewBox methods
-
-/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
-NS_IMETHODIMP
-SVGSVGElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
-{
-  *aViewBox = ViewBox().get();
-  return NS_OK;
-}
 
 already_AddRefed<nsIDOMSVGAnimatedRect>
 SVGSVGElement::ViewBox()
 {
   nsCOMPtr<nsIDOMSVGAnimatedRect> rect;
   mViewBox.ToDOMAnimatedRect(getter_AddRefs(rect), this);
   return rect.forget();
 }
 
-/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
-NS_IMETHODIMP
-SVGSVGElement::GetPreserveAspectRatio(nsISupports
-                                      **aPreserveAspectRatio)
-{
-  *aPreserveAspectRatio = PreserveAspectRatio().get();
-  return NS_OK;
-}
-
 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
 SVGSVGElement::PreserveAspectRatio()
 {
   nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
   mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
   return ratio.forget();
 }
 
--- a/content/svg/content/src/SVGSVGElement.h
+++ b/content/svg/content/src/SVGSVGElement.h
@@ -2,17 +2,16 @@
 /* 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_dom_SVGSVGElement_h
 #define mozilla_dom_SVGSVGElement_h
 
 #include "mozilla/dom/FromParser.h"
-#include "nsIDOMSVGFitToViewBox.h"
 #include "nsISVGPoint.h"
 #include "nsIDOMSVGSVGElement.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "SVGGraphicsElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGPreserveAspectRatio.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
@@ -75,18 +74,17 @@ public:
   }
   float width;
   float height;
 };
 
 typedef SVGGraphicsElement SVGSVGElementBase;
 
 class SVGSVGElement MOZ_FINAL : public SVGSVGElementBase,
-                                public nsIDOMSVGSVGElement,
-                                public nsIDOMSVGFitToViewBox
+                                public nsIDOMSVGSVGElement
 {
   friend class ::nsSVGOuterSVGFrame;
   friend class ::nsSVGInnerSVGFrame;
   friend class ::nsSVGImageFrame;
   friend class mozilla::SVGFragmentIdentifier;
 
   SVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                 FromParser aFromParser);
@@ -96,17 +94,16 @@ class SVGSVGElement MOZ_FINAL : public S
                                          already_AddRefed<nsINodeInfo> aNodeInfo,
                                          mozilla::dom::FromParser aFromParser));
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGSVGElement, SVGSVGElementBase)
   NS_DECL_NSIDOMSVGSVGELEMENT
-  NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
   // xxx I wish we could use virtual inheritance
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_FORWARD_NSIDOMSVGELEMENT(SVGSVGElementBase::)
 
   /**
    * For use by zoom controls to allow currentScale, currentTranslate.x and
--- a/content/svg/content/src/SVGSymbolElement.cpp
+++ b/content/svg/content/src/SVGSymbolElement.cpp
@@ -21,19 +21,19 @@ SVGSymbolElement::WrapNode(JSContext *aC
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGSymbolElement,SVGSymbolElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGSymbolElement,SVGSymbolElementBase)
 
 NS_INTERFACE_TABLE_HEAD(SVGSymbolElement)
-  NS_NODE_INTERFACE_TABLE6(SVGSymbolElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGFitToViewBox,
-                           nsIDOMSVGSymbolElement, nsIDOMSVGTests)
+  NS_NODE_INTERFACE_TABLE5(SVGSymbolElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement,
+                           nsIDOMSVGSymbolElement, DOMSVGTests)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSymbolElement)
 NS_INTERFACE_MAP_END_INHERITING(SVGSymbolElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGSymbolElement::SVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGSymbolElementBase(aNodeInfo)
@@ -43,42 +43,25 @@ SVGSymbolElement::SVGSymbolElement(alrea
 
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGSymbolElement)
 
 //----------------------------------------------------------------------
-// nsIDOMSVGFitToViewBox methods
-
-/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
-NS_IMETHODIMP SVGSymbolElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
-{
-  *aViewBox = ViewBox().get();
-  return NS_OK;
-}
 
 already_AddRefed<nsIDOMSVGAnimatedRect>
 SVGSymbolElement::ViewBox()
 {
   nsCOMPtr<nsIDOMSVGAnimatedRect> rect;
   mViewBox.ToDOMAnimatedRect(getter_AddRefs(rect), this);
   return rect.forget();
 }
 
-/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
-NS_IMETHODIMP
-SVGSymbolElement::GetPreserveAspectRatio(nsISupports
-                                         **aPreserveAspectRatio)
-{
-  *aPreserveAspectRatio = PreserveAspectRatio().get();
-  return NS_OK;
-}
-
 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
 SVGSymbolElement::PreserveAspectRatio()
 {
   nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
   mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
   return ratio.forget();
 }
 
--- a/content/svg/content/src/SVGSymbolElement.h
+++ b/content/svg/content/src/SVGSymbolElement.h
@@ -6,44 +6,41 @@
 #ifndef mozilla_dom_SVGSymbolElement_h
 #define mozilla_dom_SVGSymbolElement_h
 
 #include "nsIDOMSVGSymbolElement.h"
 #include "DOMSVGTests.h"
 #include "nsSVGElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
-#include "nsIDOMSVGFitToViewBox.h"
 #include "nsGkAtoms.h"
 
 nsresult NS_NewSVGSymbolElement(nsIContent **aResult,
                                 already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 typedef nsSVGElement SVGSymbolElementBase;
 
 class SVGSymbolElement MOZ_FINAL : public SVGSymbolElementBase,
                                    public nsIDOMSVGSymbolElement,
-                                   public DOMSVGTests,
-                                   public nsIDOMSVGFitToViewBox
+                                   public DOMSVGTests
 {
 protected:
   friend nsresult (::NS_NewSVGSymbolElement(nsIContent **aResult,
                                             already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSYMBOLELEMENT
-  NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
   // xxx I wish we could use virtual inheritance
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
--- a/content/svg/content/src/SVGViewElement.cpp
+++ b/content/svg/content/src/SVGViewElement.cpp
@@ -41,19 +41,18 @@ nsSVGElement::EnumInfo SVGViewElement::s
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGViewElement,SVGViewElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGViewElement,SVGViewElementBase)
 
 NS_INTERFACE_TABLE_HEAD(SVGViewElement)
-  NS_NODE_INTERFACE_TABLE5(SVGViewElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGViewElement,
-                           nsIDOMSVGFitToViewBox)
+  NS_NODE_INTERFACE_TABLE4(SVGViewElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement, nsIDOMSVGViewElement)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGViewElement)
 NS_INTERFACE_MAP_END_INHERITING(SVGViewElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGViewElement::SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGViewElementBase(aNodeInfo)
@@ -73,43 +72,25 @@ SVGViewElement::SetZoomAndPan(uint16_t a
     mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
     return;
   }
 
   rv.Throw(NS_ERROR_RANGE_ERR);
 }
 
 //----------------------------------------------------------------------
-// nsIDOMSVGFitToViewBox methods
-
-/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
-NS_IMETHODIMP
-SVGViewElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
-{
-  *aViewBox = ViewBox().get();
-  return NS_OK;
-}
 
 already_AddRefed<nsIDOMSVGAnimatedRect>
 SVGViewElement::ViewBox()
 {
   nsCOMPtr<nsIDOMSVGAnimatedRect> box;
   mViewBox.ToDOMAnimatedRect(getter_AddRefs(box), this);
   return box.forget();
 }
 
-/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
-NS_IMETHODIMP
-SVGViewElement::GetPreserveAspectRatio(nsISupports
-                                       **aPreserveAspectRatio)
-{
-  *aPreserveAspectRatio = PreserveAspectRatio().get();
-  return NS_OK;
-}
-
 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
 SVGViewElement::PreserveAspectRatio()
 {
   nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
   mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
   return ratio.forget();
 }
 
--- a/content/svg/content/src/SVGViewElement.h
+++ b/content/svg/content/src/SVGViewElement.h
@@ -2,17 +2,16 @@
 /* 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_dom_SVGViewElement_h
 #define mozilla_dom_SVGViewElement_h
 
 #include "nsIDOMSVGViewElement.h"
-#include "nsIDOMSVGFitToViewBox.h"
 #include "nsSVGElement.h"
 #include "nsSVGEnum.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "SVGStringList.h"
 
 static const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0;
 static const unsigned short SVG_ZOOMANDPAN_DISABLE = 1;
@@ -27,34 +26,32 @@ nsresult NS_NewSVGViewElement(nsIContent
 
 namespace mozilla {
 class SVGFragmentIdentifier;
 
 namespace dom {
 class SVGSVGElement;
 
 class SVGViewElement : public SVGViewElementBase,
-                       public nsIDOMSVGViewElement,
-                       public nsIDOMSVGFitToViewBox
+                       public nsIDOMSVGViewElement
 {
 protected:
   friend class mozilla::SVGFragmentIdentifier;
   friend class SVGSVGElement;
   friend class ::nsSVGOuterSVGFrame;
   SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   friend nsresult (::NS_NewSVGViewElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGVIEWELEMENT
-  NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_FORWARD_NSIDOMSVGELEMENT(SVGViewElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/crashtests/831561.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <script>
+      var clipPath = document.createElementNS("http://www.w3.org/2000/svg",
+                                              "clipPath");
+      clipPath["hasExtension"].apply(clipPath,[]);
+    </script>
+  </body>
+</html>
--- a/content/svg/content/src/crashtests/crashtests.list
+++ b/content/svg/content/src/crashtests/crashtests.list
@@ -56,8 +56,9 @@ load 601251-1.html
 load 601406-1.svg
 load 603145-1.svg
 load 613899-1.svg
 load 613899-2.svg
 load zero-size-image.svg
 load 723441-1.html
 load 751515-1.svg
 load 761507-1.svg
+load 831561.html
--- a/content/svg/content/src/nsSVGAngle.cpp
+++ b/content/svg/content/src/nsSVGAngle.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Util.h"
 
 #include "nsSVGAngle.h"
 #include "prdtoa.h"
 #include "nsTextFormatter.h"
 #include "nsSVGAttrTearoffTable.h"
-#include "nsSVGMarkerElement.h"
+#include "mozilla/dom/SVGMarkerElement.h"
 #include "nsMathUtils.h"
 #include "nsContentUtils.h" // NS_ENSURE_FINITE
 #include "nsSMILValue.h"
 #include "SVGOrientSMILType.h"
 #include "nsAttrValueInlines.h"
 #include "SVGAngle.h"
 #include "SVGAnimatedAngle.h"
 #include "mozilla/Attributes.h"
@@ -212,42 +212,40 @@ nsSVGAngle::NewValueSpecifiedUnits(uint1
     aSVGElement->AnimationNeedsResample();
   }
   if (aSVGElement) {
     aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
   }
   return NS_OK;
 }
 
-nsresult
-nsSVGAngle::ToDOMBaseVal(SVGAngle **aResult, nsSVGElement *aSVGElement)
+already_AddRefed<SVGAngle>
+nsSVGAngle::ToDOMBaseVal(nsSVGElement *aSVGElement)
 {
   nsRefPtr<SVGAngle> domBaseVal =
     sBaseSVGAngleTearoffTable.GetTearoff(this);
   if (!domBaseVal) {
     domBaseVal = new SVGAngle(this, aSVGElement, SVGAngle::BaseValue);
     sBaseSVGAngleTearoffTable.AddTearoff(this, domBaseVal);
   }
 
-  domBaseVal.forget(aResult);
-  return NS_OK;
+  return domBaseVal.forget();
 }
 
-nsresult
-nsSVGAngle::ToDOMAnimVal(SVGAngle **aResult, nsSVGElement *aSVGElement)
+already_AddRefed<SVGAngle>
+nsSVGAngle::ToDOMAnimVal(nsSVGElement *aSVGElement)
 {
   nsRefPtr<SVGAngle> domAnimVal =
     sAnimSVGAngleTearoffTable.GetTearoff(this);
   if (!domAnimVal) {
     domAnimVal = new SVGAngle(this, aSVGElement, SVGAngle::AnimValue);
     sAnimSVGAngleTearoffTable.AddTearoff(this, domAnimVal);
   }
 
-  domAnimVal.forget(aResult);
-  return NS_OK;
+  return domAnimVal.forget();
 }
 
 SVGAngle::~SVGAngle()
 {
   if (mType == BaseValue) {
     sBaseSVGAngleTearoffTable.RemoveTearoff(mVal);
   } else if (mType == AnimValue) {
     sAnimSVGAngleTearoffTable.RemoveTearoff(mVal);
@@ -337,41 +335,39 @@ nsSVGAngle::SetAnimValue(float aValue, u
     return;
   }
   mAnimVal = aValue;
   mAnimValUnit = aUnit;
   mIsAnimated = true;
   aSVGElement->DidAnimateAngle(mAttrEnum);
 }
 
-nsresult
-nsSVGAngle::ToDOMAnimatedAngle(nsISupports **aResult,
-                               nsSVGElement *aSVGElement)
+already_AddRefed<SVGAnimatedAngle>
+nsSVGAngle::ToDOMAnimatedAngle(nsSVGElement *aSVGElement)
 {
   nsRefPtr<SVGAnimatedAngle> domAnimatedAngle =
     sSVGAnimatedAngleTearoffTable.GetTearoff(this);
   if (!domAnimatedAngle) {
     domAnimatedAngle = new SVGAnimatedAngle(this, aSVGElement);
     sSVGAnimatedAngleTearoffTable.AddTearoff(this, domAnimatedAngle);
   }
 
-  domAnimatedAngle.forget(aResult);
-  return NS_OK;
+  return domAnimatedAngle.forget();
 }
 
 SVGAnimatedAngle::~SVGAnimatedAngle()
 {
   sSVGAnimatedAngleTearoffTable.RemoveTearoff(mVal);
 }
 
 nsISMILAttr*
 nsSVGAngle::ToSMILAttr(nsSVGElement *aSVGElement)
 {
   if (aSVGElement->NodeInfo()->Equals(nsGkAtoms::marker, kNameSpaceID_SVG)) {
-    nsSVGMarkerElement *marker = static_cast<nsSVGMarkerElement*>(aSVGElement);
+    SVGMarkerElement *marker = static_cast<SVGMarkerElement*>(aSVGElement);
     return new SMILOrient(marker->GetOrientType(), this, aSVGElement);
   }
   // SMILOrient would not be useful for general angle attributes (also,
   // "orient" is the only animatable <angle>-valued attribute in SVG 1.1).
   NS_NOTREACHED("Trying to animate unknown angle attribute.");
   return nullptr;
 }
 
--- a/content/svg/content/src/nsSVGAngle.h
+++ b/content/svg/content/src/nsSVGAngle.h
@@ -11,28 +11,28 @@
 #include "nsError.h"
 #include "nsISMILAttr.h"
 #include "nsSVGElement.h"
 #include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 
 class nsISMILAnimationElement;
 class nsSMILValue;
-class nsSVGOrientType;
 
 namespace mozilla {
 
 // Angle Unit Types
 static const unsigned short SVG_ANGLETYPE_UNKNOWN     = 0;
 static const unsigned short SVG_ANGLETYPE_UNSPECIFIED = 1;
 static const unsigned short SVG_ANGLETYPE_DEG         = 2;
 static const unsigned short SVG_ANGLETYPE_RAD         = 3;
 static const unsigned short SVG_ANGLETYPE_GRAD        = 4;
 
 namespace dom {
+class nsSVGOrientType;
 class SVGAngle;
 class SVGAnimatedAngle;
 }
 }
 
 class nsSVGAngle
 {
   friend class mozilla::dom::SVGAngle;
@@ -63,18 +63,18 @@ public:
   void SetAnimValue(float aValue, uint8_t aUnit, nsSVGElement *aSVGElement);
 
   uint8_t GetBaseValueUnit() const { return mBaseValUnit; }
   uint8_t GetAnimValueUnit() const { return mAnimValUnit; }
   float GetBaseValInSpecifiedUnits() const { return mBaseVal; }
   float GetAnimValInSpecifiedUnits() const { return mAnimVal; }
 
   static nsresult ToDOMSVGAngle(nsISupports **aResult);
-  nsresult ToDOMAnimatedAngle(nsISupports **aResult,
-                              nsSVGElement* aSVGElement);
+  already_AddRefed<mozilla::dom::SVGAnimatedAngle>
+    ToDOMAnimatedAngle(nsSVGElement* aSVGElement);
   // Returns a new nsISMILAttr object that the caller must delete
   nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
 
   static float GetDegreesPerUnit(uint8_t aUnit);
 
 private:
 
   float mAnimVal;
@@ -83,40 +83,40 @@ private:
   uint8_t mBaseValUnit;
   uint8_t mAttrEnum; // element specified tracking for attribute
   bool mIsAnimated;
 
   void SetBaseValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement);
   nsresult NewValueSpecifiedUnits(uint16_t aUnitType, float aValue,
                                   nsSVGElement *aSVGElement);
   nsresult ConvertToSpecifiedUnits(uint16_t aUnitType, nsSVGElement *aSVGElement);
-  nsresult ToDOMBaseVal(mozilla::dom::SVGAngle **aResult, nsSVGElement* aSVGElement);
-  nsresult ToDOMAnimVal(mozilla::dom::SVGAngle **aResult, nsSVGElement* aSVGElement);
+  already_AddRefed<mozilla::dom::SVGAngle> ToDOMBaseVal(nsSVGElement* aSVGElement);
+  already_AddRefed<mozilla::dom::SVGAngle> ToDOMAnimVal(nsSVGElement* aSVGElement);
 
 public:
   // We do not currently implemente a SMILAngle struct because in SVG 1.1 the
   // only *animatable* attribute that takes an <angle> is 'orient', on the
   // 'marker' element, and 'orient' must be special cased since it can also
   // take the value 'auto', making it a more complex type.
 
   struct SMILOrient MOZ_FINAL : public nsISMILAttr
   {
   public:
-    SMILOrient(nsSVGOrientType* aOrientType,
+    SMILOrient(mozilla::dom::nsSVGOrientType* aOrientType,
                nsSVGAngle* aAngle,
                nsSVGElement* aSVGElement)
       : mOrientType(aOrientType)
       , mAngle(aAngle)
       , mSVGElement(aSVGElement)
     {}
 
     // These will stay alive because a nsISMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
-    nsSVGOrientType* mOrientType;
+    mozilla::dom::nsSVGOrientType* mOrientType;
     nsSVGAngle* mAngle;
     nsSVGElement* mSVGElement;
 
     // nsISMILAttr methods
     virtual nsresult ValueFromString(const nsAString& aStr,
                                      const nsISMILAnimationElement* aSrcElement,
                                      nsSMILValue& aValue,
                                      bool& aPreventCachingOfSandwich) const;
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -99,19 +99,18 @@
 #include "nsNodeInfoManager.h"
 #include "nsXBLBinding.h"
 #include "nsEventDispatcher.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsICSSDeclaration.h"
 
-#include "mozilla/dom/XULElementBinding.h"
-
-using namespace mozilla;
+namespace css = mozilla::css;
+namespace dom = mozilla::dom;
 
 //----------------------------------------------------------------------
 
 static NS_DEFINE_CID(kXULPopupListenerCID,        NS_XULPOPUPLISTENER_CID);
 
 //----------------------------------------------------------------------
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
@@ -162,18 +161,16 @@ NS_INTERFACE_MAP_END_AGGREGATED(mElement
 //
 
 nsXULElement::nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsStyledElement(aNodeInfo),
       mBindingParent(nullptr)
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
 
-    SetIsDOMBinding();
-
     // We may be READWRITE by default; check.
     if (IsReadWriteTextElement()) {
         AddStatesSilently(NS_EVENT_STATE_MOZ_READWRITE);
         RemoveStatesSilently(NS_EVENT_STATE_MOZ_READONLY);
     }
 }
 
 nsXULElement::nsXULSlots::nsXULSlots()
@@ -398,78 +395,66 @@ nsXULElement::Clone(nsINodeInfo *aNodeIn
 
 //----------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
                                      const nsAString& aValue,
                                      nsIDOMNodeList** aReturn)
 {
-    *aReturn = GetElementsByAttribute(aAttribute, aValue).get();
-    return NS_OK;
-}
-
-already_AddRefed<nsINodeList>
-nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
-                                     const nsAString& aValue)
-{
     nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
+    NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
     void* attrValue = new nsString(aValue);
-    nsRefPtr<nsContentList> list =
+    NS_ENSURE_TRUE(attrValue, NS_ERROR_OUT_OF_MEMORY);
+    nsContentList *list = 
         new nsContentList(this,
                           nsXULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
                           kNameSpaceID_Unknown);
-    return list.forget();
+    NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
+
+    NS_ADDREF(*aReturn = list);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                        const nsAString& aAttribute,
                                        const nsAString& aValue,
                                        nsIDOMNodeList** aReturn)
 {
-    ErrorResult rv;
-    *aReturn =
-        GetElementsByAttributeNS(aNamespaceURI, aAttribute, aValue, rv).get();
-    return rv.ErrorCode();
-}
-
-already_AddRefed<nsINodeList>
-nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
-                                       const nsAString& aAttribute,
-                                       const nsAString& aValue,
-                                       ErrorResult& rv)
-{
     nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
+    NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
 
     int32_t nameSpaceId = kNameSpaceID_Wildcard;
     if (!aNamespaceURI.EqualsLiteral("*")) {
-      rv =
+      nsresult rv =
         nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                               nameSpaceId);
-      if (rv.Failed()) {
-          return nullptr;
-      }
+      NS_ENSURE_SUCCESS(rv, rv);
     }
 
     void* attrValue = new nsString(aValue);
-    nsRefPtr<nsContentList> list =
+    NS_ENSURE_TRUE(attrValue, NS_ERROR_OUT_OF_MEMORY);
+    
+    nsContentList *list = 
         new nsContentList(this,
                           nsXULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
                           nameSpaceId);
+    NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
 
-    return list.forget();
+    NS_ADDREF(*aReturn = list);
+    return NS_OK;
 }
 
 nsEventListenerManager*
 nsXULElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer)
 {
     // XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc()
     // here, override BindToTree for those classes and munge event
     // listeners there?
@@ -1186,81 +1171,60 @@ nsXULElement::PreHandleEvent(nsEventChai
 
     return nsStyledElement::PreHandleEvent(aVisitor);
 }
 
 // XXX This _should_ be an implementation method, _not_ publicly exposed :-(
 NS_IMETHODIMP
 nsXULElement::GetResource(nsIRDFResource** aResource)
 {
-    ErrorResult rv;
-    *aResource = GetResource(rv).get();
-    return rv.ErrorCode();
-}
-
-already_AddRefed<nsIRDFResource>
-nsXULElement::GetResource(ErrorResult& rv)
-{
     nsAutoString id;
     GetAttr(kNameSpaceID_None, nsGkAtoms::ref, id);
     if (id.IsEmpty()) {
         GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
     }
 
-    if (id.IsEmpty()) {
-        return nullptr;
+    if (!id.IsEmpty()) {
+        return nsXULContentUtils::RDFService()->
+            GetUnicodeResource(id, aResource);
     }
+    *aResource = nullptr;
 
-    nsCOMPtr<nsIRDFResource> resource;
-    rv = nsXULContentUtils::RDFService()->
-        GetUnicodeResource(id, getter_AddRefs(resource));
-    return resource.forget();
+    return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
 {
-    *aDatabase = GetDatabase().get();
-    return NS_OK;
-}
+    nsCOMPtr<nsIXULTemplateBuilder> builder;
+    GetBuilder(getter_AddRefs(builder));
 
-already_AddRefed<nsIRDFCompositeDataSource>
-nsXULElement::GetDatabase()
-{
-    nsCOMPtr<nsIXULTemplateBuilder> builder = GetBuilder();
-    if (!builder) {
-        return nullptr;
-    }
+    if (builder)
+        builder->GetDatabase(aDatabase);
+    else
+        *aDatabase = nullptr;
 
-    nsCOMPtr<nsIRDFCompositeDataSource> database;
-    builder->GetDatabase(getter_AddRefs(database));
-    return database.forget();
+    return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
 {
-    *aBuilder = GetBuilder().get();
+    *aBuilder = nullptr;
+
+    // XXX sXBL/XBL2 issue! Owner or current document?
+    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(GetCurrentDoc());
+    if (xuldoc)
+        xuldoc->GetTemplateBuilderFor(this, aBuilder);
+
     return NS_OK;
 }
 
-already_AddRefed<nsIXULTemplateBuilder>
-nsXULElement::GetBuilder()
-{
-    // XXX sXBL/XBL2 issue! Owner or current document?
-    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(GetCurrentDoc());
-    if (!xuldoc) {
-        return nullptr;
-    }
-
-    nsCOMPtr<nsIXULTemplateBuilder> builder;
-    xuldoc->GetTemplateBuilderFor(this, getter_AddRefs(builder));
-    return builder.forget();
-}
 
 //----------------------------------------------------------------------
 // Implementation methods
 
 NS_IMETHODIMP
 nsXULElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
 {
     return NS_OK;
@@ -1300,55 +1264,39 @@ nsXULElement::IsAttributeMapped(const ns
 {
     return false;
 }
 
 // Controllers Methods
 NS_IMETHODIMP
 nsXULElement::GetControllers(nsIControllers** aResult)
 {
-    ErrorResult rv;
-    NS_IF_ADDREF(*aResult = GetControllers(rv));
-    return rv.ErrorCode();
-}
-
-nsIControllers*
-nsXULElement::GetControllers(ErrorResult& rv)
-{
     if (! Controllers()) {
         nsDOMSlots* slots = DOMSlots();
 
+        nsresult rv;
         rv = NS_NewXULControllers(nullptr, NS_GET_IID(nsIControllers),
                                   reinterpret_cast<void**>(&slots->mControllers));
 
-        NS_ASSERTION(NS_SUCCEEDED(rv.ErrorCode()),
-                     "unable to create a controllers");
-        if (rv.Failed()) {
-            return nullptr;
-        }
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a controllers");
+        if (NS_FAILED(rv)) return rv;
     }
 
-    return Controllers();
+    *aResult = Controllers();
+    NS_IF_ADDREF(*aResult);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::GetBoxObject(nsIBoxObject** aResult)
 {
-    ErrorResult rv;
-    *aResult = GetBoxObject(rv).get();
-    return rv.ErrorCode();
-}
+  *aResult = nullptr;
 
-already_AddRefed<nsIBoxObject>
-nsXULElement::GetBoxObject(ErrorResult& rv)
-{
-    nsCOMPtr<nsIBoxObject> boxObject;
-    // XXX sXBL/XBL2 issue! Owner or current document?
-    rv = OwnerDoc()->GetBoxObjectFor(this, getter_AddRefs(boxObject));
-    return boxObject.forget();
+  // XXX sXBL/XBL2 issue! Owner or current document?
+  return OwnerDoc()->GetBoxObjectFor(this, aResult);
 }
 
 // Methods for setting/getting attributes from nsIDOMXULElement
 #define NS_IMPL_XUL_STRING_ATTR(_method, _atom)                     \
   NS_IMETHODIMP                                                     \
   nsXULElement::Get##_method(nsAString& aReturn)                    \
   {                                                                 \
     GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aReturn);         \
@@ -1358,29 +1306,36 @@ nsXULElement::GetBoxObject(ErrorResult& 
   nsXULElement::Set##_method(const nsAString& aValue)               \
   {                                                                 \
     return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue,    \
                    true);                                        \
   }
 
 #define NS_IMPL_XUL_BOOL_ATTR(_method, _atom)                       \
   NS_IMETHODIMP                                                     \
-  nsXULElement::Get##_method(bool* aResult)                         \
+  nsXULElement::Get##_method(bool* aResult)                       \
   {                                                                 \
-    *aResult = _method();                                           \
+    *aResult = BoolAttrIsTrue(nsGkAtoms::_atom);                   \
+                                                                    \
     return NS_OK;                                                   \
   }                                                                 \
   NS_IMETHODIMP                                                     \
-  nsXULElement::Set##_method(bool aValue)                           \
+  nsXULElement::Set##_method(bool aValue)                         \
   {                                                                 \
-      SetXULBoolAttr(nsGkAtoms::_atom, aValue);                     \
-      return NS_OK;                                                 \
+    if (aValue)                                                     \
+      SetAttr(kNameSpaceID_None, nsGkAtoms::_atom,                 \
+              NS_LITERAL_STRING("true"), true);                  \
+    else                                                            \
+      UnsetAttr(kNameSpaceID_None, nsGkAtoms::_atom, true);     \
+                                                                    \
+    return NS_OK;                                                   \
   }
 
 
+NS_IMPL_XUL_STRING_ATTR(Id, id)
 NS_IMPL_XUL_STRING_ATTR(ClassName, _class)
 NS_IMPL_XUL_STRING_ATTR(Align, align)
 NS_IMPL_XUL_STRING_ATTR(Dir, dir)
 NS_IMPL_XUL_STRING_ATTR(Flex, flex)
 NS_IMPL_XUL_STRING_ATTR(FlexGroup, flexgroup)
 NS_IMPL_XUL_STRING_ATTR(Ordinal, ordinal)
 NS_IMPL_XUL_STRING_ATTR(Orient, orient)
 NS_IMPL_XUL_STRING_ATTR(Pack, pack)
@@ -1458,42 +1413,34 @@ nsresult
 nsXULElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
 {
     nsCOMPtr<nsIContent> otherContent(do_QueryInterface(aOtherOwner));
     NS_ENSURE_TRUE(otherContent, NS_ERROR_NOT_IMPLEMENTED);
 
     nsXULElement* otherEl = FromContent(otherContent);
     NS_ENSURE_TRUE(otherEl, NS_ERROR_NOT_IMPLEMENTED);
 
-    ErrorResult rv;
-    SwapFrameLoaders(*otherEl, rv);
-    return rv.ErrorCode();
-}
-
-void
-nsXULElement::SwapFrameLoaders(nsXULElement& aOtherElement, ErrorResult& rv)
-{
-    if (&aOtherElement == this) {
+    if (otherEl == this) {
         // nothing to do
-        return;
+        return NS_OK;
     }
 
     nsXULSlots *ourSlots = static_cast<nsXULSlots*>(GetExistingDOMSlots());
     nsXULSlots *otherSlots =
-        static_cast<nsXULSlots*>(aOtherElement.GetExistingDOMSlots());
+        static_cast<nsXULSlots*>(otherEl->GetExistingDOMSlots());
     if (!ourSlots || !ourSlots->mFrameLoader ||
         !otherSlots || !otherSlots->mFrameLoader) {
         // Can't handle swapping when there is nothing to swap... yet.
-        rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-        return;
+        return NS_ERROR_NOT_IMPLEMENTED;
     }
 
-    rv = ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
-                                                     ourSlots->mFrameLoader,
-                                                     otherSlots->mFrameLoader);
+    return
+        ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
+                                                    ourSlots->mFrameLoader,
+                                                    otherSlots->mFrameLoader);
 }
 
 NS_IMETHODIMP
 nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement)
 {
     for (nsIContent* current = GetParent(); current;
          current = current->GetParent()) {
         if (current->NodeInfo()->Equals(nsGkAtoms::listbox,
@@ -1507,68 +1454,44 @@ nsXULElement::GetParentTree(nsIDOMXULMul
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Focus()
 {
-    ErrorResult rv;
-    Focus(rv);
-    return rv.ErrorCode();
-}
-
-void
-nsXULElement::Focus(ErrorResult& rv)
-{
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     nsCOMPtr<nsIDOMElement> elem = do_QueryObject(this);
-    if (fm) {
-        rv = fm->SetFocus(this, 0);
-    }
+    return fm ? fm->SetFocus(this, 0) : NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Blur()
 {
-    ErrorResult rv;
-    Blur(rv);
-    return rv.ErrorCode();
-}
-
-void
-nsXULElement::Blur(ErrorResult& rv)
-{
     if (!ShouldBlur(this))
-      return;
+      return NS_OK;
 
     nsIDocument* doc = GetCurrentDoc();
     if (!doc)
-      return;
+      return NS_OK;
 
     nsIDOMWindow* win = doc->GetWindow();
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-    if (win && fm) {
-      rv = fm->ClearFocus(win);
-    }
+    if (win && fm)
+      return fm->ClearFocus(win);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Click()
 {
   return ClickWithInputSource(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN);
 }
 
-void
-nsXULElement::Click(ErrorResult& rv)
-{
-  rv = Click();
-}
-
 nsresult
 nsXULElement::ClickWithInputSource(uint16_t aInputSource)
 {
     if (BoolAttrIsTrue(nsGkAtoms::disabled))
         return NS_OK;
 
     nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // Strong just in case
     if (doc) {
@@ -1864,17 +1787,17 @@ nsXULElement::ResetChromeMargins()
     nsIWidget* mainWidget = GetWindowWidget();
     if (!mainWidget)
         return;
     // See nsIWidget
     nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget));
 }
 
 bool
-nsXULElement::BoolAttrIsTrue(nsIAtom* aName) const
+nsXULElement::BoolAttrIsTrue(nsIAtom* aName)
 {
     const nsAttrValue* attr =
         GetAttrInfo(kNameSpaceID_None, aName).mValue;
 
     return attr && attr->Type() == nsAttrValue::eAtom &&
            attr->GetAtomValue() == nsGkAtoms::_true;
 }
 
@@ -1902,22 +1825,16 @@ nsXULElement::RecompileScriptEventListen
 }
 
 bool
 nsXULElement::IsEventAttributeName(nsIAtom *aName)
 {
   return nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL);
 }
 
-JSObject*
-nsXULElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
-{
-    return dom::XULElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeNode)
     if (tmp->mType == nsXULPrototypeNode::eType_Element) {
         static_cast<nsXULPrototypeElement*>(tmp)->Unlink();
     }
     else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
         static_cast<nsXULPrototypeScript*>(tmp)->UnlinkJSObjects();
     }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -32,18 +32,16 @@
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsStyledElement.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsIFrameLoader.h"
 #include "jspubtd.h"
-#include "nsGenericHTMLElement.h"
-#include "nsFrameLoader.h"
 
 class nsIDocument;
 class nsString;
 class nsIDocShell;
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsIScriptGlobalObjectOwner;
@@ -390,30 +388,28 @@ public:
      * template-generated element has already had its children generated.
      */
     void SetTemplateGenerated() { SetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     void ClearTemplateGenerated() { UnsetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     bool GetTemplateGenerated() { return HasFlag(XUL_ELEMENT_TEMPLATE_GENERATED); }
 
     // nsIDOMNode
     NS_FORWARD_NSIDOMNODE_TO_NSINODE
-    // And since that shadowed GetParentElement with the XPCOM
-    // signature, pull in the one we care about.
-    using nsStyledElement::GetParentElement;
 
     // nsIDOMElement
     NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
     // nsIDOMXULElement
     NS_DECL_NSIDOMXULELEMENT
 
     virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
     virtual nsEventStates IntrinsicState() const;
 
     nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
+    already_AddRefed<nsFrameLoader> GetFrameLoader();
     nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
 
     virtual void RecompileScriptEventListeners();
 
     // This function should ONLY be used by BindToTree implementations.
     // The function exists solely because XUL elements store the binding
     // parent as a member instead of in the slots, as Element does.
     void SetXULBindingParent(nsIContent* aBindingParent)
@@ -422,179 +418,16 @@ public:
     }
 
     virtual nsXPCClassInfo* GetClassInfo();
 
     virtual nsIDOMNode* AsDOMNode() { return this; }
 
     virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
-    void SetXULAttr(nsIAtom* aName, const nsAString& aValue,
-                    mozilla::ErrorResult& aError)
-    {
-        aError = SetAttr(kNameSpaceID_None, aName, aValue, true);
-    }
-    void SetXULBoolAttr(nsIAtom* aName, bool aValue)
-    {
-        if (aValue) {
-            SetAttr(kNameSpaceID_None, aName, NS_LITERAL_STRING("true"), true);
-        } else {
-            UnsetAttr(kNameSpaceID_None, aName, true);
-        }
-    }
-
-    // WebIDL API
-    // The XPCOM getter is fine for our string attributes.
-    // The XPCOM setter is fine for our bool attributes.
-    void SetClassName(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::_class, aValue, rv);
-    }
-    void SetAlign(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::align, aValue, rv);
-    }
-    void SetDir(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::dir, aValue, rv);
-    }
-    void SetFlex(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::flex, aValue, rv);
-    }
-    void SetFlexGroup(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::flexgroup, aValue, rv);
-    }
-    void SetOrdinal(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::ordinal, aValue, rv);
-    }
-    void SetOrient(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::orient, aValue, rv);
-    }
-    void SetPack(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::pack, aValue, rv);
-    }
-    bool Hidden() const
-    {
-        return BoolAttrIsTrue(nsGkAtoms::hidden);
-    }
-    bool Collapsed() const
-    {
-        return BoolAttrIsTrue(nsGkAtoms::collapsed);
-    }
-    void SetObserves(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::observes, aValue, rv);
-    }
-    void SetMenu(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::menu, aValue, rv);
-    }
-    void SetContextMenu(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::contextmenu, aValue, rv);
-    }
-    void SetTooltip(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::tooltip, aValue, rv);
-    }
-    void SetWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::width, aValue, rv);
-    }
-    void SetHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::height, aValue, rv);
-    }
-    void SetMinWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::minwidth, aValue, rv);
-    }
-    void SetMinHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::minheight, aValue, rv);
-    }
-    void SetMaxWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::maxwidth, aValue, rv);
-    }
-    void SetMaxHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::maxheight, aValue, rv);
-    }
-    void SetPersist(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::persist, aValue, rv);
-    }
-    void SetLeft(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::left, aValue, rv);
-    }
-    void SetTop(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::top, aValue, rv);
-    }
-    void SetDatasources(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::datasources, aValue, rv);
-    }
-    void SetRef(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::ref, aValue, rv);
-    }
-    void SetTooltipText(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::tooltiptext, aValue, rv);
-    }
-    void SetStatusText(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::statustext, aValue, rv);
-    }
-    bool AllowEvents() const
-    {
-        return BoolAttrIsTrue(nsGkAtoms::allowevents);
-    }
-    already_AddRefed<nsIRDFCompositeDataSource> GetDatabase();
-    already_AddRefed<nsIXULTemplateBuilder> GetBuilder();
-    already_AddRefed<nsIRDFResource> GetResource(mozilla::ErrorResult& rv);
-    nsIControllers* GetControllers(mozilla::ErrorResult& rv);
-    already_AddRefed<nsIBoxObject> GetBoxObject(mozilla::ErrorResult& rv);
-    void Focus(mozilla::ErrorResult& rv);
-    void Blur(mozilla::ErrorResult& rv);
-    void Click(mozilla::ErrorResult& rv);
-    // The XPCOM DoCommand never fails, so it's OK for us.
-    already_AddRefed<nsINodeList>
-      GetElementsByAttribute(const nsAString& aAttribute,
-                             const nsAString& aValue);
-    already_AddRefed<nsINodeList>
-      GetElementsByAttributeNS(const nsAString& aNamespaceURI,
-                               const nsAString& aAttribute,
-                               const nsAString& aValue,
-                               mozilla::ErrorResult& rv);
-    // Style() inherited from nsStyledElement
-    already_AddRefed<nsFrameLoader> GetFrameLoader();
-    void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& rv);
-
-    // For XUL, the parent is the parent element, if any
-    nsINode* GetParentObject() const
-    {
-        Element* parent = GetParentElement();
-        if (parent) {
-            return parent;
-        }
-        return nsStyledElement::GetParentObject();
-    }
-    static bool PrefEnabled()
-    {
-        return nsGenericHTMLElement::PrefEnabled();
-    }
 protected:
 
     // This can be removed if EnsureContentsGenerated dies.
     friend class nsNSElementTearoff;
 
     // Implementation methods
     nsresult EnsureContentsGenerated(void) const;
 
@@ -673,17 +506,17 @@ protected:
     // Internal accessor. This shadows the 'Slots', and returns
     // appropriate value.
     nsIControllers *Controllers() {
       nsDOMSlots* slots = GetExistingDOMSlots();
       return slots ? slots->mControllers : nullptr; 
     }
 
     void UnregisterAccessKey(const nsAString& aOldValue);
-    bool BoolAttrIsTrue(nsIAtom* aName) const;
+    bool BoolAttrIsTrue(nsIAtom* aName);
 
     friend nsresult
     NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
     friend void
     NS_TrustedNewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
 
     static already_AddRefed<nsXULElement>
     Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
@@ -692,14 +525,11 @@ protected:
     bool IsReadWriteTextElement() const
     {
         const nsIAtom* tag = Tag();
         return
             GetNameSpaceID() == kNameSpaceID_XUL &&
             (tag == nsGkAtoms::textbox || tag == nsGkAtoms::textarea) &&
             !HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
     }
-
-    virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
-                               bool *aTriedToWrap) MOZ_OVERRIDE;
 };
 
 #endif // nsXULElement_h__
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -473,20 +473,17 @@ nsXULPrototypeDocument::Write(nsIObjectO
     if (NS_FAILED(tmp)) {
       rv = tmp;
     }
     for (i = 0; i < nodeInfoCount; ++i) {
         nsINodeInfo *nodeInfo = nodeInfos[i];
         NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
 
         nsAutoString namespaceURI;
-        tmp = nodeInfo->GetNamespaceURI(namespaceURI);
-        if (NS_FAILED(tmp)) {
-          rv = tmp;
-        }
+        nodeInfo->GetNamespaceURI(namespaceURI);
         tmp = aStream->WriteWStringZ(namespaceURI.get());
         if (NS_FAILED(tmp)) {
           rv = tmp;
         }
 
         nsAutoString prefix;
         nodeInfo->GetPrefix(prefix);
         bool nullPrefix = DOMStringIsNull(prefix);
--- a/dom/apps/src/FreeSpaceWatcher.jsm
+++ b/dom/apps/src/FreeSpaceWatcher.jsm
@@ -39,23 +39,23 @@ this.FreeSpaceWatcher = {
     let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     debug("Creating new FreeSpaceWatcher");
     let callback = {
       currentStatus: null,
       notify: function(aTimer) {
         try {
           let deviceStorage = Services.wm.getMostRecentWindow("navigator:browser")
                                          .navigator.getDeviceStorage("apps");
-          let req = deviceStorage.stat();
+          let req = deviceStorage.freeSpace();
           req.onsuccess = req.onerror = function statResult(e) {
             if (!e.target.result) {
               return;
             }
 
-            let freeBytes = e.target.result.freeBytes;
+            let freeBytes = e.target.result;
             debug("Free bytes: " + freeBytes);
             let newStatus = freeBytes > aThreshold;
             if (newStatus != callback.currentStatus) {
               debug("New status: " + (newStatus ? "free" : "full"));
               aOnStatusChange(newStatus ? "free" : "full");
               callback.currentStatus = newStatus;
             }
           }
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -2260,26 +2260,26 @@ this.DOMApplicationRegistry = {
         }
       });
 
       requestChannel.asyncOpen(listener, null);
     };
 
     let deviceStorage = Services.wm.getMostRecentWindow("navigator:browser")
                                 .navigator.getDeviceStorage("apps");
-    let req = deviceStorage.stat();
+    let req = deviceStorage.freeSpace();
     req.onsuccess = req.onerror = function statResult(e) {
       // Even if we could not retrieve the device storage free space, we try
       // to download the package.
       if (!e.target.result) {
         download();
         return;
       }
 
-      let freeBytes = e.target.result.freeBytes;
+      let freeBytes = e.target.result;
       if (freeBytes) {
         debug("Free storage: " + freeBytes + ". Download size: " +
               aApp.downloadSize);
         if (freeBytes <=
             aApp.downloadSize + AppDownloadManager.MIN_REMAINING_FREESPACE) {
           cleanup("INSUFFICIENT_STORAGE");
           return;
         }
@@ -2293,18 +2293,20 @@ this.DOMApplicationRegistry = {
     for (let id in this.webapps) {
       let app = this.webapps[id];
       if (app.origin != aData.origin) {
         continue;
       }
 
       dump("-- webapps.js uninstall " + app.manifestURL + "\n");
 
-      if (!app.removable)
-        return;
+      if (!app.removable) {
+        debug("Error: cannot unintall a non-removable app.");
+        break;
+      }
 
       // Check if we are downloading something for this app, and cancel the
       // download if needed.
       this.cancelDownload(app.manifestURL);
 
       // Clean up the deprecated manifest cache if needed.
       if (id in this._manifestCache) {
         delete this._manifestCache[id];
@@ -2338,16 +2340,19 @@ this.DOMApplicationRegistry = {
         aMm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
         this.broadcastMessage("Webapps:RemoveApp", { id: id });
       }).bind(this));
 
       return;
     }
 
+    // Fall-through, fails to uninstall the desired app because:
+    //   - we cannot find the app to be uninstalled.
+    //   - the app to be uninstalled is not removable.
     aMm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
   },
 
   getSelf: function(aData, aMm) {
     aData.apps = [];
 
     if (aData.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
         aData.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -330,17 +330,16 @@
 #include "nsIDOMSVGDefsElement.h"
 #include "nsIDOMSVGDescElement.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIDOMSVGElement.h"
 #include "nsIDOMSVGEllipseElement.h"
 #include "nsIDOMSVGEvent.h"
 #include "nsIDOMSVGFilterElement.h"
 #include "nsIDOMSVGFilters.h"
-#include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGForeignObjectElem.h"
 #include "nsIDOMSVGGElement.h"
 #include "nsIDOMSVGGradientElement.h"
 #include "nsIDOMSVGImageElement.h"
 #include "nsIDOMSVGLength.h"
 #include "nsIDOMSVGLineElement.h"
 #include "nsIDOMSVGMarkerElement.h"
 #include "nsIDOMSVGMaskElement.h"
@@ -353,17 +352,16 @@
 #include "nsIDOMSVGRect.h"
 #include "nsIDOMSVGRectElement.h"
 #include "nsIDOMSVGScriptElement.h"
 #include "nsIDOMSVGStopElement.h"
 #include "nsIDOMSVGStyleElement.h"
 #include "nsIDOMSVGSVGElement.h"
 #include "nsIDOMSVGSwitchElement.h"
 #include "nsIDOMSVGSymbolElement.h"
-#include "nsIDOMSVGTests.h"
 #include "nsIDOMSVGTextElement.h"
 #include "nsIDOMSVGTextPathElement.h"
 #include "nsIDOMSVGTitleElement.h"
 #include "nsIDOMSVGTSpanElement.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsIDOMSVGUseElement.h"
 #include "nsIDOMSVGViewElement.h"
@@ -2942,17 +2940,16 @@ nsDOMClassInfo::Init()
 
 #ifdef MOZ_XUL
   DOM_CLASSINFO_MAP_BEGIN(XULTemplateBuilder, nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(XULTreeBuilder, nsIXULTreeBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTreeBuilder)
-    DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeView)
   DOM_CLASSINFO_MAP_END
 #endif
 
   DOM_CLASSINFO_MAP_BEGIN(DOMStringList, nsIDOMDOMStringList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMStringList)
   DOM_CLASSINFO_MAP_END
 
@@ -2987,17 +2984,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver,          \
                                         nsDOMTouchEvent::PrefEnabled())
 
 #define DOM_CLASSINFO_SVG_TEXT_CONTENT_ELEMENT_MAP_ENTRIES \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextContentElement)   \
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
 
 #define DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES \
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)           \
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
 
   // XXX - the proto chain stuff is sort of hackish, because of the MI in
   // the SVG interfaces. I doubt that extending the proto on one interface
   // works properly on an element which inherits off multiple interfaces.
   // Tough luck. - bbaetz
 
   // The SVG document
@@ -3021,44 +3017,40 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(SVGAltGlyphElement, nsIDOMSVGAltGlyphElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextPositioningElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_TEXT_CONTENT_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimateElement, nsIDOMSVGAnimateElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimateTransformElement,
                           nsIDOMSVGAnimateTransformElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateTransformElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimateMotionElement,
                           nsIDOMSVGAnimateMotionElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateMotionElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSetElement,
                           nsIDOMSVGSetElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSetElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementTimeControl)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMpathElement, nsIDOMSVGMpathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
@@ -3266,17 +3258,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(SVGLineElement, nsIDOMSVGLineElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLineElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMarkerElement, nsIDOMSVGMarkerElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGMarkerElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGMaskElement, nsIDOMSVGMaskElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGMaskElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
@@ -3288,17 +3279,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPathElement, nsIDOMSVGPathElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPathElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPatternElement, nsIDOMSVGPatternElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPatternElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUnitTypes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGPolygonElement, nsIDOMSVGPolygonElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGPolygonElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
@@ -3336,30 +3326,27 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(SVGStyleElement, nsIDOMSVGStyleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStyleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMLinkStyle)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSVGElement, nsIDOMSVGSVGElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSVGElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSwitchElement, nsIDOMSVGSwitchElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSwitchElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGSymbolElement, nsIDOMSVGSymbolElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSymbolElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTests)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGTextElement, nsIDOMSVGTextElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextPositioningElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTextContentElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
@@ -3385,17 +3372,16 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(SVGUseElement, nsIDOMSVGUseElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGUseElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGURIReference)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGViewElement, nsIDOMSVGViewElement)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   // other SVG classes
   DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedEnumeration, nsIDOMSVGAnimatedEnumeration)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedEnumeration)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -2,17 +2,16 @@
 /* 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 nsWrapperCache_h___
 #define nsWrapperCache_h___
 
 #include "nsCycleCollectionParticipant.h"
-#include "mozilla/Assertions.h"
 
 class JSObject;
 struct JSContext;
 class XPCWrappedNativeScope;
 
 namespace mozilla {
 namespace dom {
 namespace workers {
@@ -157,17 +156,16 @@ public:
    * value set in triedToWrap is meaningless. If null is returned then
    * triedToWrap indicates whether an error occurred, if it's false then the
    * object doesn't actually support creating a wrapper through its WrapObject
    * hook.
    */
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
-    MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapObject");
     *triedToWrap = false;
     return nullptr;
   }
 
   /**
    * Returns true if the object has a non-gray wrapper.
    */
   bool IsBlack();
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -570,19 +570,19 @@ QueryInterface(JSContext* cx, unsigned a
     return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
   }
 
   JS::Value* argv = JS_ARGV(cx, vp);
   if (!argv[0].isObject()) {
     return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
 
-  nsIJSID* iid;
+  nsIJSIID* iid;
   xpc_qsSelfRef iidRef;
-  if (NS_FAILED(xpc_qsUnwrapArg<nsIJSID>(cx, argv[0], &iid, &iidRef.ptr,
+  if (NS_FAILED(xpc_qsUnwrapArg<nsIJSIID>(cx, argv[0], &iid, &iidRef.ptr,
                                           &argv[0]))) {
     return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
   MOZ_ASSERT(iid);
 
   if (iid->GetID()->Equals(NS_GET_IID(nsIClassInfo))) {
     nsresult rv;
     nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(native, &rv);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -557,16 +557,17 @@ DOMInterfaces = {
 
 'NodeList': {
     'nativeType': 'nsINodeList',
     'resultNotAddRefed': [ 'item' ]
 },
 
 'PaintRequest': {
     'nativeType': 'nsPaintRequest',
+    'prefable': True
 },
 
 'PaintRequestList': {
     'nativeType': 'nsPaintRequestList',
     'headerFile': 'nsPaintRequest.h',
     'resultNotAddRefed': [ 'item' ]
 },
 
@@ -607,16 +608,17 @@ DOMInterfaces = {
 
 'RGBColor': {
     "nativeType": "nsDOMCSSRGBColor",
     'resultNotAddRefed': [ "alpha", "blue", "green", "red" ]
 },
 
 'Screen': {
     'nativeType': 'nsScreen',
+    'prefable': True,
 },
 
 'SVGAElement': {
   'hasInstanceInterface': 'nsIDOMSVGAElement',
 },
 
 'SVGAnimatedLengthList': {
     'nativeType': 'mozilla::DOMSVGAnimatedLengthList',
@@ -1006,22 +1008,16 @@ DOMInterfaces = {
 },
 
 'XPathEvaluator': {
     'nativeType': 'nsXPathEvaluator',
     'headerFile': 'nsXPathEvaluator.h',
     'wrapperCache': False
 },
 
-'XULElement': {
-    'nativeType': 'nsXULElement',
-    'resultNotAddRefed': [ 'controllers', 'style' ],
-    'hasInstanceInterface': 'nsIDOMXULElement',
-},
-
 ####################################
 # Test Interfaces of various sorts #
 ####################################
 
 'TestInterface' : {
         # Keep this in sync with TestExampleInterface
         'headerFile': 'TestBindingHeader.h',
         'register': False,
@@ -1215,23 +1211,16 @@ addExternalIface('DOMStringList')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('HTMLHeadElement', nativeType='mozilla::dom::Element')
 addExternalIface('HTMLCanvasElement', nativeType='mozilla::dom::HTMLCanvasElement')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MediaStream')
-addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
-addExternalIface('MozControllers', nativeType='nsIControllers')
-addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
-addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
-                 notflattened=True)
-addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
-addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
 addExternalIface('NamedNodeMap')
 addExternalIface('NodeIterator')
 addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
 addExternalIface('nsISupports', nativeType='nsISupports')
 addExternalIface('OutputStream', nativeType='nsIOutputStream',
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
@@ -1250,8 +1239,9 @@ addExternalIface('TouchList', headerFile
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
 addExternalIface('UserDataHandler')
 addExternalIface('Window')
 addExternalIface('WindowProxy', nativeType='nsIDOMWindow')
 addExternalIface('XPathResult', nativeType='nsISupports')
 addExternalIface('XPathExpression')
 addExternalIface('XPathNSResolver')
+addExternalIface('XULElement')
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1820,23 +1820,28 @@ builtinNames = {
     IDLType.Tags.uint32: 'uint32_t',
     IDLType.Tags.uint64: 'uint64_t',
     IDLType.Tags.unrestricted_float: 'float',
     IDLType.Tags.float: 'float',
     IDLType.Tags.unrestricted_double: 'double',
     IDLType.Tags.double: 'double'
 }
 
-numericTags = [
-    IDLType.Tags.int8, IDLType.Tags.uint8,
-    IDLType.Tags.int16, IDLType.Tags.uint16,
-    IDLType.Tags.int32, IDLType.Tags.uint32,
-    IDLType.Tags.int64, IDLType.Tags.uint64,
-    IDLType.Tags.float, IDLType.Tags.double
-    ]
+numericSuffixes = {
+    IDLType.Tags.int8: '',
+    IDLType.Tags.uint8: '',
+    IDLType.Tags.int16: '',
+    IDLType.Tags.uint16: '',
+    IDLType.Tags.int32: '',
+    IDLType.Tags.uint32: 'U',
+    IDLType.Tags.int64: 'LL',
+    IDLType.Tags.uint64: 'ULL',
+    IDLType.Tags.float: 'F',
+    IDLType.Tags.double: 'D'
+}
 
 class CastableObjectUnwrapper():
     """
     A class for unwrapping an object named by the "source" argument
     based on the passed-in descriptor and storing it in a variable
     called by the name in the "target" argument.
 
     codeOnFailure is the code to run if unwrapping fails.
@@ -2982,18 +2987,19 @@ for (uint32_t i = 0; i < length; ++i) {
                      "  //       when passed a non-finite float too.\n"
                      "%s\n"
                      "}" % (readLoc, nonFiniteCode))
 
     if (defaultValue is not None and
         # We already handled IDLNullValue, so just deal with the other ones
         not isinstance(defaultValue, IDLNullValue)):
         tag = defaultValue.type.tag()
-        if tag in numericTags:
-            defaultStr = defaultValue.value
+        if tag in numericSuffixes:
+            # Some numeric literals require a suffix to compile without warnings
+            defaultStr = "%s%s" % (defaultValue.value, numericSuffixes[tag])
         else:
             assert(tag == IDLType.Tags.bool)
             defaultStr = toStringBool(defaultValue.value)
         template = CGWrapper(CGIndenter(CGGeneric(template)),
                              pre="if (${haveValue}) {\n",
                              post=("\n"
                                    "} else {\n"
                                    "  %s = %s;\n"
@@ -3088,19 +3094,19 @@ def instantiateJSToNativeConversionTempl
 def convertConstIDLValueToJSVal(value):
     if isinstance(value, IDLNullValue):
         return "JSVAL_NULL"
     tag = value.type.tag()
     if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
                IDLType.Tags.uint16, IDLType.Tags.int32]:
         return "INT_TO_JSVAL(%s)" % (value.value)
     if tag == IDLType.Tags.uint32:
-        return "UINT_TO_JSVAL(%s)" % (value.value)
+        return "UINT_TO_JSVAL(%sU)" % (value.value)
     if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
-        return "DOUBLE_TO_JSVAL(%s)" % (value.value)
+        return "DOUBLE_TO_JSVAL(%s%s)" % (value.value, numericSuffixes[tag])
     if tag == IDLType.Tags.bool:
         return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
     if tag in [IDLType.Tags.float, IDLType.Tags.double]:
         return "DOUBLE_TO_JSVAL(%s)" % (value.value)
     raise TypeError("Const value of unhandled type: " + value.type)
 
 class CGArgumentConverter(CGThing):
     """
@@ -4542,74 +4548,84 @@ class CGMemberJITInfo(CGThing):
     def __init__(self, descriptor, member):
         self.member = member
         self.descriptor = descriptor
 
     def declare(self):
         return ""
 
     def defineJitInfo(self, infoName, opName, opType, infallible, constant,
-                      returnTypes):
+                      pure, returnTypes):
+        assert(not constant or pure) # constants are always pure
         protoID = "prototypes::id::%s" % self.descriptor.name
         depth = "PrototypeTraits<%s>::Depth" % protoID
         failstr = toStringBool(infallible)
         conststr = toStringBool(constant)
+        purestr = toStringBool(pure)
         returnType = reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
                             "")
         return ("\n"
                 "const JSJitInfo %s = {\n"
                 "  %s,\n"
                 "  %s,\n"
                 "  %s,\n"
                 "  JSJitInfo::%s,\n"
                 "  %s,  /* isInfallible. False in setters. */\n"
                 "  %s,  /* isConstant. Only relevant for getters. */\n"
+                "  %s,  /* isPure.  Only relevant for getters. */\n"
                 "  %s   /* returnType.  Only relevant for getters/methods. */\n"
                 "};\n" % (infoName, opName, protoID, depth, opType, failstr,
-                          conststr, returnType))
+                          conststr, purestr, returnType))
 
     def define(self):
         if self.member.isAttr():
             getterinfo = ("%s_getterinfo" % self.member.identifier.name)
             getter = ("(JSJitPropertyOp)get_%s" % self.member.identifier.name)
             getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
+            getterconst = self.member.getExtendedAttribute("Constant")
+            getterpure = getterconst or self.member.getExtendedAttribute("Pure")
+            assert (getterinfal or (not getterconst and not getterpure))
+
             getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
-            getterconst = self.member.getExtendedAttribute("Constant")
             result = self.defineJitInfo(getterinfo, getter, "Getter",
-                                        getterinfal, getterconst,
+                                        getterinfal, getterconst, getterpure,
                                         [self.member.type])
             if not self.member.readonly or self.member.getExtendedAttribute("PutForwards") is not None:
                 setterinfo = ("%s_setterinfo" % self.member.identifier.name)
                 setter = ("(JSJitPropertyOp)set_%s" % self.member.identifier.name)
                 # Setters are always fallible, since they have to do a typed unwrap.
                 result += self.defineJitInfo(setterinfo, setter, "Setter",
-                                             False, False,
+                                             False, False, False,
                                              [BuiltinTypes[IDLBuiltinType.Types.void]])
             return result
         if self.member.isMethod():
             methodinfo = ("%s_methodinfo" % self.member.identifier.name)
             name = CppKeywords.checkMethodName(self.member.identifier.name)
             # Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition.
             method = ("(JSJitPropertyOp)%s" % name)
 
             # Methods are infallible if they are infallible, have no arguments
             # to unwrap, and have a return type that's infallible to wrap up for
             # return.
-            methodInfal = False
             sigs = self.member.signatures()
-            if len(sigs) == 1:
-                # Don't handle overloading. If there's more than one signature,
+            if len(sigs) != 1:
+                # Don't handle overloading.  If there's more than one signature,
                 # one of them must take arguments.
+                methodInfal = False
+            else:
                 sig = sigs[0]
-                if len(sig[1]) == 0 and infallibleForMember(self.member, sig[0], self.descriptor):
-                    # No arguments and infallible return boxing
-                    methodInfal = True
+                if (len(sig[1]) != 0 or
+                    not infallibleForMember(self.member, sig[0], self.descriptor)):
+                    # We have arguments or our return-value boxing can fail
+                    methodInfal = False
+                else:
+                    methodInfal = "infallible" in self.descriptor.getExtendedAttributes(self.member)
 
             result = self.defineJitInfo(methodinfo, method, "Method",
-                                        methodInfal, False,
+                                        methodInfal, False, False,
                                         [s[0] for s in sigs])
             return result
         raise TypeError("Illegal member type to CGPropertyJITInfo")
 
     @staticmethod
     def getJSReturnTypeTag(t):
         if t.nullable():
             # Sometimes it might return null, sometimes not
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -7,16 +7,17 @@ topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 MODULE           = dom
 LIBRARY_NAME     = dombindings_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY   = 1
+FAIL_ON_WARNINGS := 1
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 # Need this to find all our DOM source files.
 include $(topsrcdir)/dom/dom-config.mk
 
 include $(topsrcdir)/dom/webidl/WebIDL.mk
@@ -81,17 +82,16 @@ LOCAL_INCLUDES += -I$(topsrcdir)/js/xpco
   -I$(topsrcdir)/js/xpconnect/wrappers \
   -I$(topsrcdir)/content/canvas/src \
   -I$(topsrcdir)/content/html/content/src \
   -I$(topsrcdir)/media/webrtc/signaling/src/peerconnection \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/content/xslt/src/base \
   -I$(topsrcdir)/content/xslt/src/xpath \
   -I$(topsrcdir)/content/xml/content/src \
-  -I$(topsrcdir)/content/xul/content/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -2189,16 +2189,24 @@ class IDLAttribute(IDLInterfaceMember):
         identifier = attr.identifier()
         if identifier == "TreatNonCallableAsNull":
             raise WebIDLError("TreatNonCallableAsNull cannot be specified on attributes",
                               [attr.location, self.location])
         elif identifier == "SetterThrows" and self.readonly:
             raise WebIDLError("Readonly attributes must not be flagged as "
                               "[SetterThrows]",
                               [self.location])
+        elif (((identifier == "Throws" or identifier == "GetterThrows") and
+               (self.getExtendedAttribute("Pure") or
+                self.getExtendedAttribute("Constant"))) or
+              ((identifier == "Pure" or identifier == "Constant") and
+               (self.getExtendedAttribute("Throws") or
+                self.getExtendedAttribute("GetterThrows")))):
+            raise WebIDLError("Throwing things can't be [Pure] or [Constant]",
+                              [attr.location])
         elif identifier == "LenientThis":
             if not attr.noArguments():
                 raise WebIDLError("[LenientThis] must take no arguments",
                                   [attr.location])
             if self.isStatic():
                 raise WebIDLError("[LenientThis] is only allowed on non-static "
                                   "attributes", [attr.location, self.location])
             self.lenientThis = True
@@ -2731,18 +2739,21 @@ class IDLMethod(IDLInterfaceMember, IDLS
             raise WebIDLError("Methods must not be flagged as "
                               "[SetterThrows]",
                               [attr.location, self.location])
         elif identifier == "Unforgeable":
             raise WebIDLError("Methods must not be flagged as "
                               "[Unforgeable]",
                               [attr.location, self.location])
         elif identifier == "Constant":
-            raise WebIDLError("Methods must not be flagged as "
-                              "[Constant]",
+            raise WebIDLError("Methods must not be flagged as [Constant]",
+                              [attr.location, self.location]);
+        elif identifier == "Pure":
+            raise WebIDLError("Methods must not be flagged as [Pure] and if "
+                              "that changes, don't forget to check for [Throws]",
                               [attr.location, self.location]);
         elif identifier == "PutForwards":
             raise WebIDLError("Only attributes support [PutForwards]",
                               [attr.location, self.location])
         elif identifier == "LenientFloat":
             # This is called before we've done overload resolution
             assert len(self.signatures()) == 1
             sig = self.signatures()[0]
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -666,25 +666,25 @@ BluetoothHfpManager::HandleShutdown()
 }
 
 // Virtual function of class SocketConsumer
 void
 BluetoothHfpManager::ReceiveSocketData(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  nsAutoCString msg((const char*)aMessage->mData.get());
+  nsAutoCString msg((const char*)aMessage->mData.get(), aMessage->mSize);
   msg.StripWhitespace();
 
   nsTArray<nsCString> atCommandValues;
 
   // For more information, please refer to 4.34.1 "Bluetooth Defined AT
   // Capabilities" in Bluetooth hands-free profile 1.6
   if (msg.Find("AT+BRSF=") != -1) {
-    SendCommand("+BRSF: ", 33);
+    SendCommand("+BRSF: ", 97);
   } else if (msg.Find("AT+CIND=?") != -1) {
     // Asking for CIND range
     SendCommand("+CIND: ", 0);
   } else if (msg.Find("AT+CIND?") != -1) {
     // Asking for CIND value
     SendCommand("+CIND: ", 1);
   } else if (msg.Find("AT+CMER=") != -1) {
     /**
--- a/dom/bluetooth/BluetoothUtils.cpp
+++ b/dom/bluetooth/BluetoothUtils.cpp
@@ -43,17 +43,17 @@ SetJsObject(JSContext* aContext,
       JSString* JsData;
 
       switch(v.type()) {
         case BluetoothValue::TnsString:
           JsData =
             JS_NewStringCopyN(aContext,
                               NS_ConvertUTF16toUTF8(v.get_nsString()).get(),
                               v.get_nsString().Length());
-          NS_ENSURE_TRUE(JsData, NS_ERROR_FAILURE);
+          NS_ENSURE_TRUE(JsData, false);
           val = STRING_TO_JSVAL(JsData);
           break;
         case BluetoothValue::Tuint32_t:
           val = INT_TO_JSVAL(v.get_uint32_t());
           break;
         case BluetoothValue::Tbool:
           val = BOOLEAN_TO_JSVAL(v.get_bool());
           break;
@@ -61,17 +61,17 @@ SetJsObject(JSContext* aContext,
           NS_WARNING("SetJsObject: Parameter is not handled");
           break;
       }
 
       if (!JS_SetProperty(aContext, aObj,
                           NS_ConvertUTF16toUTF8(arr[i].name()).get(),
                           &val)) {
         NS_WARNING("Failed to set property");
-        return NS_ERROR_FAILURE;
+        return false;
       }
     }
   } else {
     NS_WARNING("Not handle the type of BluetoothValue!");
     return false;
   }
 
   return true;
--- a/dom/icc/interfaces/SimToolKit.idl
+++ b/dom/icc/interfaces/SimToolKit.idl
@@ -587,19 +587,36 @@ dictionary MozStkLocalInfo
   /**
    * Language Information
    *
    * @see ISO 639-1, Alpha-2 code
    */
   DOMString language;
 };
 
+dictionary MozStkLanguageSelectionEvent
+{
+  /**
+   * The type of this event.
+   * It shall be nsIDOMMozIccManager.STK_EVENT_TYPE_LANGUAGE_SELECTION.
+   */
+  unsigned short eventType;
+
+  /**
+   * Language Information
+   *
+   * @see ISO 639-1, Alpha-2 code
+   *      "de" for German, "en" for English, "zh" for Chinese, etc.
+   */
+  DOMString language;
+};
+
 dictionary MozStkGeneralEvent
 {
   /**
    * The type of this event, MozStkGeneralEvent can be used for all Stk Event
    * requires no more parameter than event type, including
-   * nsIDOMMozIccManager.STK_EVENT_TYPE_USER_ACTIVITY
-   * nsIDOMMozIccManager.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE
-   * HCI Connectivity Event(Not defined in interface yet)
+   * nsIDOMMozIccManager.STK_EVENT_TYPE_USER_ACTIVITY.
+   * nsIDOMMozIccManager.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE.
+   * HCI Connectivity Event(Not defined in interface yet).
    */
   unsigned short eventType;
 };
--- a/dom/icc/interfaces/nsIDOMIccManager.idl
+++ b/dom/icc/interfaces/nsIDOMIccManager.idl
@@ -251,16 +251,18 @@ interface nsIDOMMozIccManager : nsIDOMEv
   /**
    * Send "Event Download" Envelope command to ICC.
    * ICC will not respond with any data for this command.
    *
    * @param event
    *        one of events below:
    *        - MozStkLocationEvent
    *        - MozStkCallEvent
+   *        - MozStkLanguageSelectionEvent
+   *        - MozStkGeneralEvent
    */
   void sendStkEventDownload(in jsval event);
 
   /**
    * The 'stkcommand' event is notified whenever STK Proactive Command is
    * issued from ICC.
    */
   [implicit_jscontext] attribute jsval onstkcommand;
--- a/dom/interfaces/svg/Makefile.in
+++ b/dom/interfaces/svg/Makefile.in
@@ -34,17 +34,16 @@ XPIDLSRCS	= \
 		nsIDOMSVGDefsElement.idl \
 		nsIDOMSVGDescElement.idl \
 		nsIDOMSVGDocument.idl \
 		nsIDOMSVGElement.idl \
 		nsIDOMSVGEllipseElement.idl \
 		nsIDOMSVGEvent.idl \
 		nsIDOMSVGFilterElement.idl \
 		nsIDOMSVGFilters.idl \
-		nsIDOMSVGFitToViewBox.idl \
 		nsIDOMSVGForeignObjectElem.idl \
 		nsIDOMSVGGElement.idl \
 		nsIDOMSVGGradientElement.idl \
 		nsIDOMSVGImageElement.idl \
 		nsIDOMSVGLength.idl \
 		nsIDOMSVGLineElement.idl \
 		nsIDOMSVGMarkerElement.idl \
 		nsIDOMSVGMaskElement.idl \
@@ -60,17 +59,16 @@ XPIDLSRCS	= \
 		nsIDOMSVGScriptElement.idl \
 		nsIDOMSVGSetElement.idl \
 		nsIDOMSVGSVGElement.idl \
 		nsIDOMSVGStopElement.idl \
 		nsIDOMSVGStringList.idl \
 		nsIDOMSVGStyleElement.idl \
 		nsIDOMSVGSwitchElement.idl \
 		nsIDOMSVGSymbolElement.idl \
-		nsIDOMSVGTests.idl \
 		nsIDOMSVGTextContentElement.idl \
 		nsIDOMSVGTextElement.idl \
 		nsIDOMSVGTextPathElement.idl \
 		nsIDOMSVGTextPositionElem.idl \
 		nsIDOMSVGTitleElement.idl \
 		nsIDOMSVGTSpanElement.idl \
 		nsIDOMSVGURIReference.idl \
 		nsIDOMSVGUnitTypes.idl \
deleted file mode 100644
--- a/dom/interfaces/svg/nsIDOMSVGFitToViewBox.idl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: IDL; 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 "domstubs.idl"
-
-interface nsIDOMSVGAnimatedRect;
-
-[scriptable, uuid(089410F3-9777-44f1-A882-AB4225696434)]
-interface nsIDOMSVGFitToViewBox : nsISupports
-{
-  readonly attribute nsIDOMSVGAnimatedRect                viewBox;
-  readonly attribute nsISupports                          preserveAspectRatio;
-};
deleted file mode 100644
--- a/dom/interfaces/svg/nsIDOMSVGTests.idl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: IDL; 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 "nsIDOMSVGStringList.idl"
-
-[scriptable, uuid(b6186ed0-0861-11e1-be50-0800200c9a66)]
-interface nsIDOMSVGTests : nsISupports
-{
-  readonly attribute nsIDOMSVGStringList requiredFeatures;
-  readonly attribute nsIDOMSVGStringList requiredExtensions;
-  readonly attribute nsIDOMSVGStringList systemLanguage;
-
-  boolean hasExtension(in DOMString extension);
-};
-
--- a/dom/interfaces/xul/nsIDOMXULElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULElement.idl
@@ -7,19 +7,20 @@
 
 interface nsIRDFCompositeDataSource;
 interface nsIXULTemplateBuilder;
 interface nsIRDFResource;
 interface nsIControllers;
 interface nsIBoxObject;
 
 
-[scriptable, uuid(bece5b0b-6e59-4de5-98d0-088adfd1cadc)]
+[scriptable, uuid(3a07dead-39e5-4dad-bc68-6ef369994126)]
 interface nsIDOMXULElement : nsIDOMElement
 {
+  attribute DOMString                 id;
   attribute DOMString                 className;
 
   // Layout properties
   attribute DOMString align;
   attribute DOMString dir;
   attribute DOMString flex;
   attribute DOMString flexGroup;
   attribute DOMString ordinal;
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -6,16 +6,18 @@
 
 #include "MediaStreamGraph.h"
 #include "nsIDOMFile.h"
 #include "nsIEventTarget.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIPopupWindowManager.h"
 #include "nsISupportsArray.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
 
 // For PR_snprintf
 #include "prprf.h"
 
 #include "nsJSUtils.h"
 #include "nsDOMFile.h"
 #include "nsGlobalWindow.h"
 
@@ -377,16 +379,43 @@ public:
     // Dispatch to the media thread to ask it to start the sources,
     // because that can take a while
     nsIThread *mediaThread = MediaManager::GetThread();
     nsRefPtr<MediaOperationRunnable> runnable(
       new MediaOperationRunnable(MEDIA_START, mListener,
                                  mAudioSource, mVideoSource, false));
     mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
 
+#ifdef MOZ_WEBRTC
+    // Right now these configs are only of use if webrtc is available
+    nsresult rv;
+    nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
+    if (NS_SUCCEEDED(rv)) {
+      nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
+
+      if (branch) {
+        int32_t aec = (int32_t) webrtc::kEcUnchanged;
+        int32_t agc = (int32_t) webrtc::kAgcUnchanged;
+        int32_t noise = (int32_t) webrtc::kNsUnchanged;
+        bool aec_on = false, agc_on = false, noise_on = false;
+
+        branch->GetBoolPref("media.peerconnection.aec_enabled", &aec_on);
+        branch->GetIntPref("media.peerconnection.aec", &aec);
+        branch->GetBoolPref("media.peerconnection.agc_enabled", &agc_on);
+        branch->GetIntPref("media.peerconnection.agc", &agc);
+        branch->GetBoolPref("media.peerconnection.noise_enabled", &noise_on);
+        branch->GetIntPref("media.peerconnection.noise", &noise);
+
+        mListener->AudioConfig(aec_on, (uint32_t) aec,
+                               agc_on, (uint32_t) agc,
+                               noise_on, (uint32_t) noise);
+      }
+    }
+#endif
+
     // We're in the main thread, so no worries here either.
     nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
     nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
 
     if (!(mManager->IsWindowStillActive(mWindowID))) {
       return NS_OK;
     }
     // This is safe since we're on main-thread, and the windowlist can only
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -16,16 +16,20 @@
 
 #include "nsPIDOMWindow.h"
 #include "nsIDOMNavigatorUserMedia.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/StaticPtr.h"
 #include "prlog.h"
 
+#ifdef MOZ_WEBRTC
+#include "mtransport/runnable_utils.h"
+#endif
+
 namespace mozilla {
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaManagerLog();
 #define MM_LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
 #else
 #define MM_LOG(msg)
 #endif
@@ -124,16 +128,33 @@ public:
     return mStream->AsSourceStream();
   }
 
   // implement in .cpp to avoid circular dependency with MediaOperationRunnable
   // Can be invoked from EITHER MainThread or MSG thread
   void Invalidate();
 
   void
+  AudioConfig(bool aEchoOn, uint32_t aEcho,
+              bool aAgcOn, uint32_t aAGC,
+              bool aNoiseOn, uint32_t aNoise)
+  {
+    if (mAudioSource) {
+#ifdef MOZ_WEBRTC
+      // Right now these configs are only of use if webrtc is available
+      RUN_ON_THREAD(mMediaThread,
+                    WrapRunnable(nsRefPtr<MediaEngineSource>(mAudioSource), // threadsafe
+                                 &MediaEngineSource::Config,
+                                 aEchoOn, aEcho, aAgcOn, aAGC, aNoiseOn, aNoise),
+                    NS_DISPATCH_NORMAL);
+#endif
+    }
+  }
+
+  void
   Remove()
   {
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
     // allow calling even if inactive (!mStream) for easier cleanup
     // Caller holds strong reference to us, so no death grip required
     MutexAutoLock lock(mLock); // protect access to mRemoved
     if (mStream && !mRemoved) {
       MM_LOG(("Listener removed on purpose, mFinished = %d", (int) mFinished));
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1232,18 +1232,22 @@ RadioInterfaceLayer.prototype = {
                 + gAudioManager.phoneState);
         }
         break;
       case nsIRadioInterfaceLayer.CALL_STATE_HELD: // Fall through...
       case nsIRadioInterfaceLayer.CALL_STATE_DISCONNECTED:
         call.isActive = false;
         if (this._activeCall &&
             this._activeCall.callIndex == call.callIndex) {
-          // Previously active call is not active now. Disable audio.
+          // Previously active call is not active now.
           this._activeCall = null;
+        }
+
+        if (!this._activeCall) {
+          // No active call. Disable the audio.
           gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
           debug("No active call, put audio system into PHONE_STATE_NORMAL: "
                 + gAudioManager.phoneState);
         }
         break;
     }
   },
 
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -902,16 +902,21 @@ this.STK_TERMINAL_SUPPORT_PROACTIVE_SET_
 this.STK_TERMINAL_SUPPORT_EVENT_MT_CALL                = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_CALL_CONNECTED         = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_CALL_DISCONNECTED      = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_LOCATION_STATUS        = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_USER_ACTIVITY          = 0;
 this.STK_TERMINAL_SUPPORT_EVENT_IDLE_SCREEN_AVAILABLE  = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_CARD_READER_STATUS     = 0;
 
+this.STK_TERMINAL_SUPPORT_EVENT_LANGUAGE_SELECTION     = 1;
+this.STK_TERMINAL_SUPPORT_EVENT_BROWSER_TERMINATION    = 0;
+this.STK_TERMINAL_SUPPORT_EVENT_DATA_AVAILABLE         = 0;
+this.STK_TERMINAL_SUPPORT_EVENT_CHANNEL_STATUS         = 0;
+
 this.STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_START_STOP   = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_GET_CURRENT  = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_DATE    = 1;
 this.STK_TERMINAL_SUPPORT_GET_INKEY                    = 1;
 this.STK_TERMINAL_SUPPORT_SET_UP_IDLE_MODE_TEXT        = 1;
 this.STK_TERMINAL_SUPPORT_RUN_AT_COMMAND               = 0;
 this.STK_TERMINAL_SUPPORT_SET_UP_CALL                  = 1;
 this.STK_TERMINAL_SUPPORT_CALL_CONTROL_BY_NNA          = 0;
@@ -920,16 +925,21 @@ this.STK_TERMINAL_SUPPORT_DISPLAY_TEXT  
 this.STK_TERMINAL_SUPPORT_SEND_DTMF_COMMAND                 = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_NMR          = 0;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_LANGUAGE     = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_TIME_ADVANCE = 0;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LANGUAGE_NOTIFICATION   = 0;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LAUNCH_BROWSER          = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_ACCESS_TECH  = 0;
 
+/**
+ * SAT profile
+ *
+ * @see ETSI TS 101.267, section 5.2.
+ */
 this.STK_TERMINAL_PROFILE_DOWNLOAD =
   (STK_TERMINAL_SUPPORT_PROFILE_DOWNLOAD << 0) |
   (STK_TERMINAL_SUPPORT_SMS_PP_DOWNLOAD  << 1) |
   (STK_TERMINAL_SUPPORT_CELL_BROADCAST_DATA_DOWNLOAD  << 2) |
   (STK_TERMINAL_SUPPORT_MENU_SELECTION << 3) |
   (STK_TERMINAL_SUPPORT_SIM_DATA_DOWNLOAD_ERROR << 4) |
   (STK_TERMINAL_SUPPORT_TIMER_EXPIRATION << 5) |
   (STK_TERMINAL_SUPPORT_USSD_IN_CALL_CONTROL << 6) |
@@ -970,16 +980,22 @@ this.STK_TERMINAL_PROFILE_EVENT =
   (STK_TERMINAL_SUPPORT_EVENT_MT_CALL << 1) |
   (STK_TERMINAL_SUPPORT_EVENT_CALL_CONNECTED << 2) |
   (STK_TERMINAL_SUPPORT_EVENT_CALL_DISCONNECTED << 3) |
   (STK_TERMINAL_SUPPORT_EVENT_LOCATION_STATUS << 4) |
   (STK_TERMINAL_SUPPORT_EVENT_USER_ACTIVITY << 5) |
   (STK_TERMINAL_SUPPORT_EVENT_IDLE_SCREEN_AVAILABLE << 6) |
   (STK_TERMINAL_SUPPORT_EVENT_CARD_READER_STATUS << 7);
 
+this.STK_TERMINAL_PROFILE_EVENT_EXT =
+  (STK_TERMINAL_SUPPORT_EVENT_LANGUAGE_SELECTION << 0) |
+  (STK_TERMINAL_SUPPORT_EVENT_BROWSER_TERMINATION << 1) |
+  (STK_TERMINAL_SUPPORT_EVENT_DATA_AVAILABLE << 2) |
+  (STK_TERMINAL_SUPPORT_EVENT_CHANNEL_STATUS << 3);
+
 this.STK_TERMINAL_PROFILE_PROACTIVE_3 =
   (STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_START_STOP << 0) |
   (STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_GET_CURRENT << 1) |
   (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_DATE << 2) |
   (STK_TERMINAL_SUPPORT_GET_INKEY << 3) |
   (STK_TERMINAL_SUPPORT_SET_UP_IDLE_MODE_TEXT << 4) |
   (STK_TERMINAL_SUPPORT_RUN_AT_COMMAND << 5) |
   (STK_TERMINAL_SUPPORT_SET_UP_CALL << 6) |
@@ -996,17 +1012,17 @@ this.STK_TERMINAL_PROFILE_PROACTIVE_4 =
   (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_ACCESS_TECH << 7);
 
 this.STK_SUPPORTED_TERMINAL_PROFILE = [
   STK_TERMINAL_PROFILE_DOWNLOAD,
   STK_TERMINAL_PROFILE_OTHER,
   STK_TERMINAL_PROFILE_PROACTIVE_1,
   STK_TERMINAL_PROFILE_PROACTIVE_2,
   STK_TERMINAL_PROFILE_EVENT,
-  0x00, // Event extension
+  STK_TERMINAL_PROFILE_EVENT_EXT, // Event extension
   0x00, // Multiple card proactive commands
   STK_TERMINAL_PROFILE_PROACTIVE_3,
   STK_TERMINAL_PROFILE_PROACTIVE_4,
   0x00, // Softkey support
   0x00, // Softkey information
   0x00, // BIP proactive commands
   0x00, // BIP supported bearers
   0x00, // Screen height
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -2603,16 +2603,23 @@ let RIL = {
         command.transactionId = 0;
         break;
       case STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE:
         command.deviceId = {
           sourceId: STK_DEVICE_ID_DISPLAY,
           destinationId: STK_DEVICE_ID_SIM
         };
         break;
+      case STK_EVENT_TYPE_LANGUAGE_SELECTION:
+        command.deviceId = {
+          sourceId: STK_DEVICE_ID_ME,
+          destinationId: STK_DEVICE_ID_SIM
+        };
+        command.language = command.event.language;
+        break;
     }
     this.sendICCEnvelopeCommand(command);
   },
 
   /**
    * Send REQUEST_STK_SEND_ENVELOPE_COMMAND to ICC.
    *
    * @param tag
@@ -2724,16 +2731,21 @@ let RIL = {
         GsmPDUHelper.writeHexOctet(options.timerId);
     }
 
     // Timer Value
     if (options.timerValue != null) {
         ComprehensionTlvHelper.writeTimerValueTlv(options.timerValue, true);
     }
 
+    // Language
+    if (options.language) {
+      ComprehensionTlvHelper.writeLanguageTlv(options.language);
+    }
+
     // Calculate and write BER length to 2nd mark
     Buf.stopCalOutgoingSize();
 
     // Calculate and write Parcel size to 1st mark
     Buf.stopCalOutgoingSize();
 
     Buf.writeUint32(0);
     Buf.sendParcel();
--- a/dom/system/gonk/tests/test_ril_worker_icc.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc.js
@@ -1510,16 +1510,74 @@ add_test(function test_stk_terminal_resp
     },
     input: "Mozilla",
     resultCode: STK_RESULT_OK
   };
   worker.RIL.sendStkTerminalResponse(response);
 });
 
 /**
+ * Verify Event Download Command : Language Selection
+ */
+add_test(function test_stk_event_download_language_selection() {
+  let worker = newUint8SupportOutgoingIndexWorker();
+  let buf = worker.Buf;
+  let pduHelper = worker.GsmPDUHelper;
+
+  buf.sendParcel = function () {
+    // Type
+    do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND)
+
+    // Token : we don't care
+    this.readUint32();
+
+    // Data Size, 26 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
+    //                      TLV_EVENT_LIST_SIZE(3) +
+    //                      TLV_LANGUAGE(4))
+    do_check_eq(this.readUint32(), 26);
+
+    // BER tag
+    do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
+
+    // BER length, 19 = TLV_DEVICE_ID_SIZE(4) +
+    //                  TLV_EVENT_LIST_SIZE(3) +
+    //                  TLV_LANGUAGE(4)
+    do_check_eq(pduHelper.readHexOctet(), 11);
+
+    // Device Identifies, Type-Length-Value(Source ID-Destination ID)
+    do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
+                                          COMPREHENSIONTLV_FLAG_CR);
+    do_check_eq(pduHelper.readHexOctet(), 2);
+    do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
+    do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
+
+    // Event List, Type-Length-Value
+    do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
+                                          COMPREHENSIONTLV_FLAG_CR);
+    do_check_eq(pduHelper.readHexOctet(), 1);
+    do_check_eq(pduHelper.readHexOctet(), STK_EVENT_TYPE_LANGUAGE_SELECTION);
+
+    // Language, Type-Length-Value
+    do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LANGUAGE);
+    do_check_eq(pduHelper.readHexOctet(), 2);
+    do_check_eq(pduHelper.read8BitUnpackedToString(2), "zh");
+
+    run_next_test();
+  };
+
+  let event = {
+    eventType: STK_EVENT_TYPE_LANGUAGE_SELECTION,
+    language: "zh"
+  };
+  worker.RIL.sendStkEventDownload({
+    event: event
+  });
+});
+
+/**
  * Verify Event Download Command : Idle Screen Available
  */
 add_test(function test_stk_event_download_idle_screen_available() {
   let worker = newUint8SupportOutgoingIndexWorker();
   let buf = worker.Buf;
   let pduHelper = worker.GsmPDUHelper;
 
   buf.sendParcel = function () {
--- a/dom/tests/mochitest/webapps/Makefile.in
+++ b/dom/tests/mochitest/webapps/Makefile.in
@@ -23,16 +23,17 @@ MOCHITEST_CHROME_FILES = \
     test_cross_origin.xul \
     test_install_app.xul \
     test_list_api.xul \
     test_install_errors.xul \
     test_install_utf8.xul \
     test_install_receipts.xul \
     test_getNotInstalled.xul \
     test_launch_paths.xul \
+    test_uninstall_errors.xul \
     $(NULL)
 
 MOCHITEST_FILES = \
     test_bug_779982.html \
     file_bug_779982.js \
     file_bug_779982.html \
     $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/webapps/test_uninstall_errors.xul
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Mozilla Bug 830258">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="head.js"/>
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=830258"
+     target="_blank">Mozilla Bug 830258</a>
+  </body>
+<script>
+
+var url1 = "http://test1.example.com/chrome/dom/tests/mochitest/webapps/apps/basic.webapp";
+var url2 = "http://test2.example.com/chrome/dom/tests/mochitest/webapps/apps/basic.webapp";
+var app1, app2;
+
+var steps = [
+  installTwoApps,
+  uninstallApp1,
+  uninstallApp1Again,
+  uninstallApp2
+];
+
+runAll(steps);
+
+function installTwoApps(next) {
+  confirmNextInstall();
+  navigator.mozApps.install(url1, null).onsuccess = function onInstallApp1(evt) {
+    app1 = evt.target.result;
+    confirmNextInstall();
+    navigator.mozApps.install(url2, null).onsuccess = function onInstallApp2(evt) {
+      app2 = evt.target.result;
+      next();
+    };
+  };
+}
+
+function uninstallApp1(next) {
+  var request = navigator.mozApps.mgmt.uninstall(app1);
+  request.onsuccess = function onUninstallApp1Success() {
+    ok(true, "Succeed to uninstall the app1 as expected");
+    next();
+  };
+  request.onerror = function onUninstallApp1Error() {
+    ok(false, "Fail to uninstall the app1");
+    next();
+  };
+}
+
+function uninstallApp1Again(next) {
+  var request = navigator.mozApps.mgmt.uninstall(app1);
+  request.onsuccess = function onUninstallApp1AgainSuccess() {
+    ok(false, "Shouldn't be able to uninstall the app1 again");
+    next();
+  };
+  request.onerror = function onUninstallApp1AgainError() {
+    is(this.error.name, "NOT_INSTALLED", "Error name should be 'NOT_INSTALLED'");
+    next();
+  };
+}
+
+function uninstallApp2(next) {
+  var request = navigator.mozApps.mgmt.uninstall(app2);
+  request.onsuccess = function onUninstallApp2Success() {
+    ok(true, "Succeed to uninstall the app2 as expected");
+    next();
+  };
+  request.onerror = function onUninstallApp2Error() {
+    ok(false, "Fail to uninstall the app2");
+    next();
+  };
+}
+
+</script>
+</window>
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -13,16 +13,17 @@
 
 interface CanvasGradient;
 interface CanvasPattern;
 interface HitRegionOptions;
 interface HTMLCanvasElement;
 interface HTMLVideoElement;
 interface TextMetrics;
 interface Window;
+interface XULElement;
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
 interface CanvasRenderingContext2D {
 
   // back-reference to the canvas.  Might be null if we're not
   // associated with a canvas.
   readonly attribute HTMLCanvasElement? canvas;
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -26,17 +26,17 @@ interface TreeWalker;
 interface WindowProxy;
 interface nsISupports;
 
 enum VisibilityState { "hidden", "visible" };
 
 /* http://dom.spec.whatwg.org/#interface-document */
 [Constructor]
 interface Document : Node {
-  [Throws, Constant]
+  [Throws]
   readonly attribute DOMImplementation implementation;
   readonly attribute DOMString URL;
   readonly attribute DOMString documentURI;
   readonly attribute DOMString compatMode;
   readonly attribute DOMString characterSet;
   readonly attribute DOMString contentType;
 
   readonly attribute DocumentType? doctype;
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -21,18 +21,20 @@ interface Element : Node {
   We haven't moved these from Node to Element like the spec wants.
 
   [Throws]
   readonly attribute DOMString? namespaceURI;
   readonly attribute DOMString? prefix;
   readonly attribute DOMString localName;
 */
   // Not [Constant] because it depends on which document we're in
+  [Pure]
   readonly attribute DOMString tagName;
 
+  [Pure]
            attribute DOMString id;
 /*
   FIXME Bug 810677 Move className from HTMLElement to Element
            attribute DOMString className;
 */
   [Constant]
   readonly attribute DOMTokenList? classList;
 
@@ -52,20 +54,25 @@ interface Element : Node {
 
   HTMLCollection getElementsByTagName(DOMString localName);
   [Throws]
   HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
   HTMLCollection getElementsByClassName(DOMString classNames);
 
   [Constant]
   readonly attribute HTMLCollection children;
+  [Pure]
   readonly attribute Element? firstElementChild;
+  [Pure]
   readonly attribute Element? lastElementChild;
+  [Pure]
   readonly attribute Element? previousElementSibling;
+  [Pure]
   readonly attribute Element? nextElementSibling;
+  [Pure]
   readonly attribute unsigned long childElementCount;
 
   // NEW
 /*
   FIXME We haven't implemented these yet.
 
   void prepend((Node or DOMString)... nodes);
   void append((Node or DOMString)... nodes);
@@ -143,16 +150,17 @@ interface Element : Node {
 // http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface
 partial interface Element {
   [Throws]
   ClientRectList getClientRects();
   ClientRect getBoundingClientRect();
 
   // scrolling
   void scrollIntoView(optional boolean top = true);
+  // None of the CSSOM attributes are [Pure], because they flush
            attribute long scrollTop;   // scroll on setting
            attribute long scrollLeft;  // scroll on setting
   readonly attribute long scrollWidth;
   readonly attribute long scrollHeight;
 
   readonly attribute long clientTop;
   readonly attribute long clientLeft;
   readonly attribute long clientWidth;
--- a/dom/webidl/HTMLElement.webidl
+++ b/dom/webidl/HTMLElement.webidl
@@ -10,64 +10,66 @@
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 interface DOMStringMap;
 interface HTMLMenuElement;
 
-// Hack to make sure that we initialize the touch prefs properly
 [PrefControlled]
 interface HTMLElement : Element {
   // metadata attributes
            attribute DOMString title;
            attribute DOMString lang;
   //         attribute boolean translate;
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute DOMString dir;
   [Constant]
   readonly attribute DOMStringMap dataset;
 
   // microdata 
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute boolean itemScope;
   [PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemType;
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute DOMString itemId;
   [PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemRef;
   [PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemProp;
   [Constant]
   readonly attribute HTMLPropertiesCollection properties;
   [Throws]
            attribute any itemValue;
 
   // user interaction
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute boolean hidden;
   void click();
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute long tabIndex;
   [Throws]
   void focus();
   [Throws]
   void blur();
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute DOMString accessKey;
+  [Pure]
   readonly attribute DOMString accessKeyLabel;
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute boolean draggable;
   //[PutForwards=value] readonly attribute DOMSettableTokenList dropzone;
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute DOMString contentEditable;
+  [Pure]
   readonly attribute boolean isContentEditable;
+  [Pure]
   readonly attribute HTMLMenuElement? contextMenu;
   //[SetterThrows]
   //         attribute HTMLMenuElement? contextMenu;
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute boolean spellcheck;
 
   // command API
   //readonly attribute DOMString? commandType;
   //readonly attribute DOMString? commandLabel;
   //readonly attribute DOMString? commandIcon;
   //readonly attribute boolean? commandHidden;
   //readonly attribute boolean? commandDisabled;
@@ -76,46 +78,43 @@ interface HTMLElement : Element {
   // styling
   [Constant]
   readonly attribute CSSStyleDeclaration style;
 
   // Mozilla specific stuff
   // FIXME Bug 810677 Move className from HTMLElement to Element
            attribute DOMString className;
 
-  [SetterThrows]
-           attribute EventHandler oncopy;
-  [SetterThrows]
-           attribute EventHandler oncut;
-  [SetterThrows]
-           attribute EventHandler onpaste;
-};
-
-// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-htmlelement-interface
-partial interface HTMLElement {
-  readonly attribute Element? offsetParent;
-  readonly attribute long offsetTop;
-  readonly attribute long offsetLeft;
-  readonly attribute long offsetWidth;
-  readonly attribute long offsetHeight;
-};
-
-[NoInterfaceObject]
-interface TouchEventHandlers {
   [SetterThrows,Pref="dom.w3c_touch_events.expose"]
            attribute EventHandler ontouchstart;
   [SetterThrows,Pref="dom.w3c_touch_events.expose"]
            attribute EventHandler ontouchend;
   [SetterThrows,Pref="dom.w3c_touch_events.expose"]
            attribute EventHandler ontouchmove;
   [SetterThrows,Pref="dom.w3c_touch_events.expose"]
            attribute EventHandler ontouchenter;
   [SetterThrows,Pref="dom.w3c_touch_events.expose"]
            attribute EventHandler ontouchleave;
   [SetterThrows,Pref="dom.w3c_touch_events.expose"]
            attribute EventHandler ontouchcancel;
+
+  [SetterThrows]
+           attribute EventHandler oncopy;
+  [SetterThrows]
+           attribute EventHandler oncut;
+  [SetterThrows]
+           attribute EventHandler onpaste;
+};
+
+// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-htmlelement-interface
+partial interface HTMLElement {
+  // CSSOM things are not [Pure] because they can flush
+  readonly attribute Element? offsetParent;
+  readonly attribute long offsetTop;
+  readonly attribute long offsetLeft;
+  readonly attribute long offsetWidth;
+  readonly attribute long offsetHeight;
 };
 
 HTMLElement implements GlobalEventHandlers;
 HTMLElement implements NodeEventHandlers;
-HTMLElement implements TouchEventHandlers;
 
 interface HTMLUnknownElement : HTMLElement {};
--- a/dom/webidl/Node.webidl
+++ b/dom/webidl/Node.webidl
@@ -25,34 +25,43 @@ interface Node : EventTarget {
   const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
   const unsigned short COMMENT_NODE = 8;
   const unsigned short DOCUMENT_NODE = 9;
   const unsigned short DOCUMENT_TYPE_NODE = 10;
   const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
   const unsigned short NOTATION_NODE = 12; // historical
   [Constant]
   readonly attribute unsigned short nodeType;
+  [Pure]
   readonly attribute DOMString nodeName;
 
+  [Pure]
   readonly attribute DOMString? baseURI;
 
+  [Pure]
   readonly attribute Document? ownerDocument;
+  [Pure]
   readonly attribute Node? parentNode;
+  [Pure]
   readonly attribute Element? parentElement;
   boolean hasChildNodes();
   [Constant]
   readonly attribute NodeList childNodes;
+  [Pure]
   readonly attribute Node? firstChild;
+  [Pure]
   readonly attribute Node? lastChild;
+  [Pure]
   readonly attribute Node? previousSibling;
+  [Pure]
   readonly attribute Node? nextSibling;
 
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute DOMString? nodeValue;
-  [SetterThrows]
+  [SetterThrows, Pure]
            attribute DOMString? textContent;
   [Throws]
   Node insertBefore(Node node, Node? child);
   [Throws]
   Node appendChild(Node node);
   [Throws]
   Node replaceChild(Node node, Node child);
   [Throws]
@@ -77,17 +86,17 @@ interface Node : EventTarget {
   boolean isDefaultNamespace(DOMString? namespace);
 
   // Mozilla-specific stuff
   // These have been moved to Element in the spec.
   [Constant]
   readonly attribute NamedNodeMap? attributes;
   // If we move namespaceURI, prefix and localName to Element they should return
   // a non-nullable type.
-  [Throws, Constant]
+  [Constant]
   readonly attribute DOMString? namespaceURI;
   [Constant]
   readonly attribute DOMString? prefix;
   [Constant]
   readonly attribute DOMString? localName;
 
   // This has been removed from the spec.
   boolean isSupported(DOMString feature, DOMString version);
--- a/dom/webidl/SVGClipPathElement.webidl
+++ b/dom/webidl/SVGClipPathElement.webidl
@@ -7,14 +7,15 @@
  * http://www.w3.org/TR/SVG2/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface SVGAnimatedEnumeration;
 
-interface SVGClipPathElement : SVGTransformableElement {
+interface SVGClipPathElement : SVGElement {
   readonly attribute SVGAnimatedEnumeration clipPathUnits;
+  readonly attribute SVGAnimatedTransformList transform;
 };
 
 SVGClipPathElement implements SVGUnitTypes;
 
--- a/dom/webidl/SVGElement.webidl
+++ b/dom/webidl/SVGElement.webidl
@@ -29,19 +29,31 @@ interface SVGElement : Element {
   attribute DOMString xmllang;
   [SetterThrows]
   attribute DOMString xmlspace;*/
 
   [Throws]
   readonly attribute SVGSVGElement? ownerSVGElement;
   readonly attribute SVGElement? viewportElement;
 
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchstart;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchend;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchmove;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchenter;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchleave;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchcancel;
+
   [SetterThrows]
            attribute EventHandler oncopy;
   [SetterThrows]
            attribute EventHandler oncut;
   [SetterThrows]
            attribute EventHandler onpaste;
 };
 
 SVGElement implements GlobalEventHandlers;
 SVGElement implements NodeEventHandlers;
-SVGElement implements TouchEventHandlers;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGMarkerElement.webidl
@@ -0,0 +1,41 @@
+/* -*- Mode: IDL; 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGAnimatedEnumeration;
+
+interface SVGMarkerElement : SVGElement {
+
+  // Marker Unit Types
+  const unsigned short SVG_MARKERUNITS_UNKNOWN = 0;
+  const unsigned short SVG_MARKERUNITS_USERSPACEONUSE = 1;
+  const unsigned short SVG_MARKERUNITS_STROKEWIDTH = 2;
+
+  // Marker Orientation Types
+  const unsigned short SVG_MARKER_ORIENT_UNKNOWN = 0;
+  const unsigned short SVG_MARKER_ORIENT_AUTO = 1;
+  const unsigned short SVG_MARKER_ORIENT_ANGLE = 2;
+
+  readonly attribute SVGAnimatedLength refX;
+  readonly attribute SVGAnimatedLength refY;
+  readonly attribute SVGAnimatedEnumeration markerUnits;
+  readonly attribute SVGAnimatedLength markerWidth;
+  readonly attribute SVGAnimatedLength markerHeight;
+  readonly attribute SVGAnimatedEnumeration orientType;
+  readonly attribute SVGAnimatedAngle orientAngle;
+
+  void setOrientToAuto();
+  [Throws]
+  void setOrientToAngle(SVGAngle angle);
+};
+
+SVGMarkerElement implements SVGFitToViewBox;
+
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -128,16 +128,17 @@ webidl_files = \
   SVGGElement.webidl \
   SVGGradientElement.webidl \
   SVGGraphicsElement.webidl \
   SVGImageElement.webidl \
   SVGLengthList.webidl \
   SVGLinearGradientElement.webidl \
   SVGLineElement.webidl \
   SVGLocatableElement.webidl \
+  SVGMarkerElement.webidl \
   SVGMaskElement.webidl \
   SVGMatrix.webidl \
   SVGMetadataElement.webidl \
   SVGMPathElement.webidl \
   SVGNumberList.webidl \
   SVGPathElement.webidl \
   SVGPathSeg.webidl \
   SVGPathSegList.webidl \
@@ -179,17 +180,16 @@ webidl_files = \
   WebSocket.webidl \
   UndoManager.webidl \
   USSDReceivedEvent.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   XMLSerializer.webidl \
   XPathEvaluator.webidl \
-  XULElement.webidl \
   $(NULL)
 
 ifdef MOZ_WEBGL
 webidl_files += \
   WebGLRenderingContext.webidl \
   $(NULL)
 endif
 
deleted file mode 100644
--- a/dom/webidl/XULElement.webidl
+++ /dev/null
@@ -1,134 +0,0 @@
-/* -*- Mode: IDL; 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/.
- */
-
-interface MozBoxObject;
-interface MozControllers;
-interface MozFrameLoader;
-interface MozRDFCompositeDataSource;
-interface MozRDFResource;
-interface MozXULTemplateBuilder;
-
-// Hack to make sure that we initialize the touch prefs properly
-[PrefControlled]
-interface XULElement : Element {
-  [SetterThrows]
-  attribute DOMString className;
-
-  // Layout properties
-  [SetterThrows]
-  attribute DOMString align;
-  [SetterThrows]
-  attribute DOMString dir;
-  [SetterThrows]
-  attribute DOMString flex;
-  [SetterThrows]
-  attribute DOMString flexGroup;
-  [SetterThrows]
-  attribute DOMString ordinal;
-  [SetterThrows]
-  attribute DOMString orient;
-  [SetterThrows]
-  attribute DOMString pack;
-
-  // Properties for hiding elements.
-  attribute boolean hidden;
-  attribute boolean collapsed;
-
-  // Property for hooking up to broadcasters
-  [SetterThrows]
-  attribute DOMString observes;
-
-  // Properties for hooking up to popups
-  [SetterThrows]
-  attribute DOMString menu;
-  [SetterThrows]
-  attribute DOMString contextMenu;
-  [SetterThrows]
-  attribute DOMString tooltip;
-
-  // Width/height properties
-  [SetterThrows]
-  attribute DOMString width;
-  [SetterThrows]
-  attribute DOMString height;
-  [SetterThrows]
-  attribute DOMString minWidth;
-  [SetterThrows]
-  attribute DOMString minHeight;
-  [SetterThrows]
-  attribute DOMString maxWidth;
-  [SetterThrows]
-  attribute DOMString maxHeight;
-
-  // Persistence
-  [SetterThrows]
-  attribute DOMString persist;
-
-  // Position properties for
-  // * popups - these are screen coordinates
-  // * other elements - these are client coordinates relative to parent stack.
-  [SetterThrows]
-  attribute DOMString left;
-  [SetterThrows]
-  attribute DOMString top;
-
-  // XUL Template Builder
-  [SetterThrows]
-  attribute DOMString datasources;
-  [SetterThrows]
-  attribute DOMString ref;
-
-  // Tooltip and status info
-  [SetterThrows]
-  attribute DOMString tooltipText;
-  [SetterThrows]
-  attribute DOMString statusText;
-
-  attribute boolean allowEvents;
-
-  readonly attribute MozRDFCompositeDataSource? database;
-  readonly attribute MozXULTemplateBuilder?     builder;
-  [Throws]
-  readonly attribute MozRDFResource?            resource;
-  [Throws]
-  readonly attribute MozControllers             controllers;
-  [Throws]
-  readonly attribute MozBoxObject?              boxObject;
-
-  [Throws]
-  void                      focus();
-  [Throws]
-  void                      blur();
-  [Throws]
-  void                      click();
-  void                      doCommand();
-
-  // XXXbz this isn't really a nodelist!  See bug 818548
-  NodeList            getElementsByAttribute(DOMString name,
-                                             DOMString value);
-  // XXXbz this isn't really a nodelist!  See bug 818548
-  [Throws]
-  NodeList            getElementsByAttributeNS(DOMString namespaceURI,
-                                               DOMString name,
-                                               DOMString value);
-  [Constant]
-  readonly attribute CSSStyleDeclaration style;
-};
-
-// And the things from nsIFrameLoaderOwner
-[NoInterfaceObject]
-interface MozFrameLoaderOwner {
-  [ChromeOnly]
-  readonly attribute MozFrameLoader? frameLoader;
-
-  [ChromeOnly, Throws]
-  void swapFrameLoaders(XULElement aOtherOwner);
-};
-
-XULElement implements GlobalEventHandlers;
-XULElement implements NodeEventHandlers;
-XULElement implements TouchEventHandlers;
-XULElement implements MozFrameLoaderOwner;
--- a/gfx/cairo/libpixman/src/Makefile.in
+++ b/gfx/cairo/libpixman/src/Makefile.in
@@ -78,39 +78,44 @@ endif
 endif
 
 endif
 
 
 CSRCS	= \
 	pixman-access.c \
 	pixman-access-accessors.c \
+	pixman-arm.c \
 	pixman-bits-image.c \
 	pixman.c \
 	pixman-combine16.c \
 	pixman-combine32.c \
 	pixman-combine64.c \
 	pixman-conical-gradient.c \
-	pixman-cpu.c \
 	pixman-edge.c \
 	pixman-edge-accessors.c \
 	pixman-fast-path.c \
 	pixman-general.c \
 	pixman-gradient-walker.c \
+	pixman-glyph.c \
 	pixman-image.c \
 	pixman-implementation.c \
 	pixman-linear-gradient.c \
 	pixman-matrix.c \
+	pixman-mips.c \
 	pixman-noop.c \
+	pixman-ppc.c \
 	pixman-radial-gradient.c \
 	pixman-region16.c \
 	pixman-region32.c \
 	pixman-solid-fill.c \
+	pixman-srgb.c \
 	pixman-trap.c \
 	pixman-utils.c \
+	pixman-x86.c \
 	$(NULL)
 
 ifdef USE_MMX
 CSRCS += pixman-mmx.c
 DEFINES += -DUSE_MMX
 endif
 
 ifdef USE_SSE2
--- a/gfx/cairo/libpixman/src/pixman-access.c
+++ b/gfx/cairo/libpixman/src/pixman-access.c
@@ -27,18 +27,18 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 
+#include "pixman-accessor.h"
 #include "pixman-private.h"
-#include "pixman-accessor.h"
 
 #define CONVERT_RGB24_TO_Y15(s)						\
     (((((s) >> 16) & 0xff) * 153 +					\
       (((s) >>  8) & 0xff) * 301 +					\
       (((s)      ) & 0xff) * 58) >> 2)
 
 #define CONVERT_RGB24_TO_RGB15(s)                                       \
     ((((s) >> 3) & 0x001f) |                                            \
@@ -205,16 +205,17 @@ get_shifts (pixman_format_code_t  format
     case PIXMAN_TYPE_A:
 	*b = 0;
 	*g = 0;
 	*r = 0;
 	*a = 0;
 	break;
 
     case PIXMAN_TYPE_ARGB:
+    case PIXMAN_TYPE_ARGB_SRGB:
 	*b = 0;
 	*g = *b + PIXMAN_FORMAT_B (format);
 	*r = *g + PIXMAN_FORMAT_G (format);
 	*a = *r + PIXMAN_FORMAT_R (format);
 	break;
 
     case PIXMAN_TYPE_ABGR:
 	*r = 0;
@@ -1060,16 +1061,140 @@ fetch_pixel_generic_64 (bits_image_t *im
 	format = PIXMAN_a8r8g8b8;
     }
 
     pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
 
     return result;
 }
 
+/* The 32_sRGB paths should be deleted after narrow processing
+ * is no longer invoked for formats that are considered wide.
+ * (Also see fetch_pixel_generic_lossy_32) */
+static void
+fetch_scanline_a8r8g8b8_32_sRGB (pixman_image_t *image,
+                                 int             x,
+                                 int             y,
+                                 int             width,
+                                 uint32_t       *buffer,
+                                 const uint32_t *mask)
+{
+    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+    const uint32_t *pixel = (uint32_t *)bits + x;
+    const uint32_t *end = pixel + width;
+    uint32_t tmp;
+    
+    while (pixel < end)
+    {
+	tmp = READ (image, pixel++);
+	*buffer++ =                 (tmp >> 24)               << 24
+		  | (srgb_to_linear[(tmp >> 16) & 0xff] >> 8) << 16
+		  | (srgb_to_linear[(tmp >>  8) & 0xff] >> 8) <<  8
+		  | (srgb_to_linear[(tmp >>  0) & 0xff] >> 8) <<  0;
+    }
+}
+
+static void
+fetch_scanline_a8r8g8b8_64_sRGB (pixman_image_t *image,
+                                 int             x,
+                                 int             y,
+                                 int             width,
+                                 uint32_t       *b,
+                                 const uint32_t *mask)
+{
+    const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+    const uint32_t *pixel = (uint32_t *)bits + x;
+    const uint32_t *end = pixel + width;
+    uint64_t *buffer = (uint64_t *)b;
+    uint32_t tmp;
+    
+    while (pixel < end)
+    {
+	tmp = READ (image, pixel++);
+	*buffer++ = (uint64_t)               ((tmp >> 24) * 257)  << 48
+		  | (uint64_t) srgb_to_linear[(tmp >> 16) & 0xff] << 32
+		  | (uint64_t) srgb_to_linear[(tmp >>  8) & 0xff] << 16
+		  | (uint64_t) srgb_to_linear[(tmp >>  0) & 0xff] <<  0;
+    }
+}
+
+static uint32_t
+fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image,
+			      int           offset,
+			      int           line)
+{
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t tmp = READ (image, bits + offset);
+    return                 (tmp >> 24)               << 24
+	 | (srgb_to_linear[(tmp >> 16) & 0xff] >> 8) << 16
+	 | (srgb_to_linear[(tmp >>  8) & 0xff] >> 8) <<  8
+	 | (srgb_to_linear[(tmp >>  0) & 0xff] >> 8) <<  0;
+}
+
+static uint64_t
+fetch_pixel_a8r8g8b8_64_sRGB (bits_image_t *image,
+			      int           offset,
+			      int	    line)
+{
+    uint32_t *bits = image->bits + line * image->rowstride;
+    uint32_t tmp = READ (image, bits + offset);
+    return (uint64_t)               ((tmp >> 24) * 257)  << 48
+	 | (uint64_t) srgb_to_linear[(tmp >> 16) & 0xff] << 32
+	 | (uint64_t) srgb_to_linear[(tmp >>  8) & 0xff] << 16
+	 | (uint64_t) srgb_to_linear[(tmp >>  0) & 0xff] <<  0;
+}
+
+static void
+store_scanline_a8r8g8b8_32_sRGB (bits_image_t   *image,
+                                 int             x,
+                                 int             y,
+                                 int             width,
+                                 const uint32_t *v)
+{
+    uint32_t *bits = image->bits + image->rowstride * y;
+    uint64_t *values = (uint64_t *)v;
+    uint32_t *pixel = bits + x;
+    uint64_t tmp;
+    int i;
+    
+    for (i = 0; i < width; ++i)
+    {
+	tmp = values[i];
+	WRITE (image, pixel++,
+		  ((uint32_t)     (tmp >> 24     )          << 24)
+		| (linear_to_srgb[(tmp >> 16 << 4) & 0xfff] << 16)
+		| (linear_to_srgb[(tmp >>  8 << 4) & 0xfff] <<  8)
+		| (linear_to_srgb[(tmp >>  0 << 4) & 0xfff] <<  0));
+    }
+}
+
+static void
+store_scanline_a8r8g8b8_64_sRGB (bits_image_t  *image,
+                                int             x,
+                                int             y,
+                                int             width,
+                                const uint32_t *v)
+{
+    uint32_t *bits = image->bits + image->rowstride * y;
+    uint64_t *values = (uint64_t *)v;
+    uint32_t *pixel = bits + x;
+    uint64_t tmp;
+    int i;
+    
+    for (i = 0; i < width; ++i)
+    {
+	tmp = values[i];
+	WRITE (image, pixel++,
+		  ((uint32_t)     (tmp >> 56)          << 24)
+		| (linear_to_srgb[(tmp >> 36) & 0xfff] << 16)
+		| (linear_to_srgb[(tmp >> 20) & 0xfff] <<  8)
+		| (linear_to_srgb[(tmp >>  4) & 0xfff] <<  0));
+    }
+}
+
 /*
  * XXX: The transformed fetch path only works at 32-bpp so far.  When all
  * paths have wide versions, this can be removed.
  *
  * WARNING: This function loses precision!
  */
 static uint32_t
 fetch_pixel_generic_lossy_32 (bits_image_t *image,
@@ -1127,16 +1252,23 @@ static const format_info_t accessors[] =
     FORMAT_INFO (a8b8g8r8),
     FORMAT_INFO (x8b8g8r8),
     FORMAT_INFO (b8g8r8a8),
     FORMAT_INFO (b8g8r8x8),
     FORMAT_INFO (r8g8b8a8),
     FORMAT_INFO (r8g8b8x8),
     FORMAT_INFO (x14r6g6b6),
 
+/* sRGB formats */
+  { PIXMAN_a8r8g8b8_sRGB,
+    fetch_scanline_a8r8g8b8_32_sRGB,
+    fetch_scanline_a8r8g8b8_64_sRGB,
+    fetch_pixel_a8r8g8b8_32_sRGB, fetch_pixel_a8r8g8b8_64_sRGB,
+    store_scanline_a8r8g8b8_32_sRGB, store_scanline_a8r8g8b8_64_sRGB },
+
 /* 24bpp formats */
     FORMAT_INFO (r8g8b8),
     FORMAT_INFO (b8g8r8),
     
 /* 16bpp formats */
     FORMAT_INFO16 (r5g6b5),
     FORMAT_INFO16 (b5g6r5),
     
--- a/gfx/cairo/libpixman/src/pixman-arm-neon-asm-bilinear.S
+++ b/gfx/cairo/libpixman/src/pixman-arm-neon-asm-bilinear.S
@@ -59,16 +59,17 @@
 .arch armv7a
 .object_arch armv4
 .eabi_attribute 10, 0
 .eabi_attribute 12, 0
 .arm
 .altmacro
 .p2align 2
 
+#include "pixman-private.h"
 #include "pixman-arm-neon-asm.h"
 
 /*
  * Bilinear macros from pixman-arm-neon-asm.S
  */
 
 /* Supplementary macro for setting function attributes */
 .macro pixman_asm_function fname
@@ -483,22 +484,22 @@ fname:
 
 .macro bilinear_interpolate_last_pixel src_fmt, mask_fmt, dst_fmt, op
     bilinear_load_&src_fmt d0, d1, d2
     bilinear_load_mask mask_fmt, 1, d4
     bilinear_load_dst dst_fmt, op, 1, d18, d19, q9
     vmull.u8  q1, d0, d28
     vmlal.u8  q1, d1, d29
     /* 5 cycles bubble */
-    vshll.u16 q0, d2, #8
+    vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d2, d30
     vmlal.u16 q0, d3, d30
     /* 5 cycles bubble */
     bilinear_duplicate_mask mask_fmt, 1, d4
-    vshrn.u32 d0, q0, #16
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
     /* 3 cycles bubble */
     vmovn.u16 d0, q0
     /* 1 cycle bubble */
     bilinear_interleave_src_dst \
                 mask_fmt, op, 1, d0, d1, q0, d18, d19, q9
     bilinear_apply_mask_to_src \
                 mask_fmt, 1, d0, d1, q0, d4, \
                 q3, q8, q10, q11
@@ -509,26 +510,26 @@ fname:
     bilinear_store_&dst_fmt 1, q2, q3
 .endm
 
 .macro bilinear_interpolate_two_pixels src_fmt, mask_fmt, dst_fmt, op
     bilinear_load_and_vertical_interpolate_two_&src_fmt \
                 q1, q11, d0, d1, d20, d21, d22, d23
     bilinear_load_mask mask_fmt, 2, d4
     bilinear_load_dst dst_fmt, op, 2, d18, d19, q9
-    vshll.u16 q0, d2, #8
+    vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d2, d30
     vmlal.u16 q0, d3, d30
-    vshll.u16 q10, d22, #8
+    vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q10, d22, d31
     vmlal.u16 q10, d23, d31
-    vshrn.u32 d0, q0, #16
-    vshrn.u32 d1, q10, #16
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS)
     bilinear_duplicate_mask mask_fmt, 2, d4
-    vshr.u16  q15, q12, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16  q12, q12, q13
     vmovn.u16 d0, q0
     bilinear_interleave_src_dst \
                 mask_fmt, op, 2, d0, d1, q0, d18, d19, q9
     bilinear_apply_mask_to_src \
                 mask_fmt, 2, d0, d1, q0, d4, \
                 q3, q8, q10, q11
     bilinear_combine \
@@ -539,39 +540,39 @@ fname:
 .endm
 
 .macro bilinear_interpolate_four_pixels src_fmt, mask_fmt, dst_fmt, op
     bilinear_load_and_vertical_interpolate_four_&src_fmt \
                 q1, q11, d0, d1, d20, d21, d22, d23 \
                 q3, q9,  d4, d5, d16, d17, d18, d19
     pld       [TMP1, PF_OFFS]
     sub       TMP1, TMP1, STRIDE
-    vshll.u16 q0, d2, #8
+    vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d2, d30
     vmlal.u16 q0, d3, d30
-    vshll.u16 q10, d22, #8
+    vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q10, d22, d31
     vmlal.u16 q10, d23, d31
-    vshr.u16  q15, q12, #8
-    vshll.u16 q2, d6, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshll.u16 q2, d6, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q2, d6, d30
     vmlal.u16 q2, d7, d30
-    vshll.u16 q8, d18, #8
+    vshll.u16 q8, d18, #BILINEAR_INTERPOLATION_BITS
     bilinear_load_mask mask_fmt, 4, d22
     bilinear_load_dst dst_fmt, op, 4, d2, d3, q1
     pld       [TMP1, PF_OFFS]
     vmlsl.u16 q8, d18, d31
     vmlal.u16 q8, d19, d31
     vadd.u16  q12, q12, q13
-    vshrn.u32 d0, q0, #16
-    vshrn.u32 d1, q10, #16
-    vshrn.u32 d4, q2, #16
-    vshrn.u32 d5, q8, #16
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d5, q8, #(2 * BILINEAR_INTERPOLATION_BITS)
     bilinear_duplicate_mask mask_fmt, 4, d22
-    vshr.u16  q15, q12, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vmovn.u16 d0, q0
     vmovn.u16 d1, q2
     vadd.u16  q12, q12, q13
     bilinear_interleave_src_dst \
                 mask_fmt, op, 4, d0, d1, q0, d2, d3, q1
     bilinear_apply_mask_to_src \
                 mask_fmt, 4, d0, d1, q0, d22, \
                 q3, q8, q9, q10
@@ -689,23 +690,23 @@ pixman_asm_function fname
     vdup.u8   d29, WB
     vadd.u16  d25, d25, d26
 
     /* ensure good destination alignment  */
     cmp       WIDTH, #1
     blt       0f
     tst       OUT, #(1 << dst_bpp_shift)
     beq       0f
-    vshr.u16  q15, q12, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16  q12, q12, q13
     bilinear_process_last_pixel
     sub       WIDTH, WIDTH, #1
 0:
     vadd.u16  q13, q13, q13
-    vshr.u16  q15, q12, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16  q12, q12, q13
 
     cmp       WIDTH, #2
     blt       0f
     tst       OUT, #(1 << (dst_bpp_shift + 1))
     beq       0f
     bilinear_process_two_pixels
     sub       WIDTH, WIDTH, #2
@@ -916,48 +917,48 @@ 3:
     vmull.u8    q9, d22, d28
     vmlal.u8    q9, d23, d29
 
     vld1.32     {d22}, [TMP3], STRIDE
     vld1.32     {d23}, [TMP3]
     vmull.u8    q10, d22, d28
     vmlal.u8    q10, d23, d29
 
-    vshll.u16   q0, d16, #8
+    vshll.u16   q0, d16, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q0, d16, d30
     vmlal.u16   q0, d17, d30
 
     pld         [TMP4, PF_OFFS]
     vld1.32     {d16}, [TMP4], STRIDE
     vld1.32     {d17}, [TMP4]
     pld         [TMP4, PF_OFFS]
     vmull.u8    q11, d16, d28
     vmlal.u8    q11, d17, d29
 
-    vshll.u16   q1, d18, #8
+    vshll.u16   q1, d18, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q1, d18, d31
     vmlal.u16   q1, d19, d31
-    vshr.u16    q15, q12, #8
+    vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16    q12, q12, q13
 .endm
 
 .macro bilinear_over_8888_8888_process_pixblock_tail
-    vshll.u16   q2, d20, #8
+    vshll.u16   q2, d20, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q2, d20, d30
     vmlal.u16   q2, d21, d30
-    vshll.u16   q3, d22, #8
+    vshll.u16   q3, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q3, d22, d31
     vmlal.u16   q3, d23, d31
-    vshrn.u32   d0, q0, #16
-    vshrn.u32   d1, q1, #16
+    vshrn.u32   d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32   d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
     vld1.32     {d2, d3}, [OUT, :128]
     pld         [OUT, #(prefetch_offset * 4)]
-    vshrn.u32   d4, q2, #16
-    vshr.u16    q15, q12, #8
-    vshrn.u32   d5, q3, #16
+    vshrn.u32   d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32   d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
     vmovn.u16   d6, q0
     vmovn.u16   d7, q2
     vuzp.8      d6, d7
     vuzp.8      d2, d3
     vuzp.8      d6, d7
     vuzp.8      d2, d3
     vdup.32     d4, d7[1]
     vmvn.8      d4, d4
@@ -970,40 +971,40 @@ 3:
     vqadd.u8    q3, q1, q3
     vuzp.8      d6, d7
     vuzp.8      d6, d7
     vadd.u16    q12, q12, q13
     vst1.32     {d6, d7}, [OUT, :128]!
 .endm
 
 .macro bilinear_over_8888_8888_process_pixblock_tail_head
-                                            vshll.u16   q2, d20, #8
+                                            vshll.u16   q2, d20, #BILINEAR_INTERPOLATION_BITS
     mov         TMP1, X, asr #16
     add         X, X, UX
     add         TMP1, TOP, TMP1, asl #2
                                             vmlsl.u16   q2, d20, d30
     mov         TMP2, X, asr #16
     add         X, X, UX
     add         TMP2, TOP, TMP2, asl #2
                                             vmlal.u16   q2, d21, d30
-                                            vshll.u16   q3, d22, #8
+                                            vshll.u16   q3, d22, #BILINEAR_INTERPOLATION_BITS
     vld1.32     {d20}, [TMP1], STRIDE
                                             vmlsl.u16   q3, d22, d31
                                             vmlal.u16   q3, d23, d31
     vld1.32     {d21}, [TMP1]
     vmull.u8    q8, d20, d28
     vmlal.u8    q8, d21, d29
-                                            vshrn.u32   d0, q0, #16
-                                            vshrn.u32   d1, q1, #16
+                                            vshrn.u32   d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+                                            vshrn.u32   d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
                                             vld1.32     {d2, d3}, [OUT, :128]
                                             pld         [OUT, PF_OFFS]
-                                            vshrn.u32   d4, q2, #16
-                                            vshr.u16    q15, q12, #8
+                                            vshrn.u32   d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
+                                            vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vld1.32     {d22}, [TMP2], STRIDE
-                                            vshrn.u32   d5, q3, #16
+                                            vshrn.u32   d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
                                             vmovn.u16   d6, q0
     vld1.32     {d23}, [TMP2]
     vmull.u8    q9, d22, d28
     mov         TMP3, X, asr #16
     add         X, X, UX
     add         TMP3, TOP, TMP3, asl #2
     mov         TMP4, X, asr #16
     add         X, X, UX
@@ -1017,37 +1018,37 @@ 3:
                                             vuzp.8      d2, d3
                                             vdup.32     d4, d7[1]
     vld1.32     {d23}, [TMP3]
                                             vmvn.8      d4, d4
     vmull.u8    q10, d22, d28
     vmlal.u8    q10, d23, d29
                                             vmull.u8    q11, d2, d4
                                             vmull.u8    q2, d3, d4
-    vshll.u16   q0, d16, #8
+    vshll.u16   q0, d16, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q0, d16, d30
                                             vrshr.u16   q1, q11, #8
     vmlal.u16   q0, d17, d30
                                             vrshr.u16   q8, q2, #8
                                             vraddhn.u16 d2, q1, q11
                                             vraddhn.u16 d3, q8, q2
     pld         [TMP4, PF_OFFS]
     vld1.32     {d16}, [TMP4], STRIDE
                                             vqadd.u8    q3, q1, q3
     vld1.32     {d17}, [TMP4]
     pld         [TMP4, PF_OFFS]
     vmull.u8    q11, d16, d28
     vmlal.u8    q11, d17, d29
                                             vuzp.8      d6, d7
-    vshll.u16   q1, d18, #8
+    vshll.u16   q1, d18, #BILINEAR_INTERPOLATION_BITS
                                             vuzp.8      d6, d7
     vmlsl.u16   q1, d18, d31
                                             vadd.u16    q12, q12, q13
     vmlal.u16   q1, d19, d31
-    vshr.u16    q15, q12, #8
+    vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16    q12, q12, q13
                                             vst1.32     {d6, d7}, [OUT, :128]!
 .endm
 
 /* over_8888_8_8888 */
 .macro bilinear_over_8888_8_8888_process_last_pixel
     bilinear_interpolate_last_pixel 8888, 8, 8888, over
 .endm
@@ -1076,53 +1077,53 @@ 3:
     mov         TMP4, X, asr #16
     add         X, X, UX
     add         TMP4, TOP, TMP4, asl #2
     vld1.32     {d3}, [TMP2]
     vmull.u8    q2, d0, d28
     vmull.u8    q3, d2, d28
     vmlal.u8    q2, d1, d29
     vmlal.u8    q3, d3, d29
-    vshll.u16   q0, d4, #8
-    vshll.u16   q1, d6, #8
+    vshll.u16   q0, d4, #BILINEAR_INTERPOLATION_BITS
+    vshll.u16   q1, d6, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q0, d4, d30
     vmlsl.u16   q1, d6, d31
     vmlal.u16   q0, d5, d30
     vmlal.u16   q1, d7, d31
-    vshrn.u32   d0, q0, #16
-    vshrn.u32   d1, q1, #16
+    vshrn.u32   d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32   d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
     vld1.32     {d2}, [TMP3], STRIDE
     vld1.32     {d3}, [TMP3]
     pld         [TMP4, PF_OFFS]
     vld1.32     {d4}, [TMP4], STRIDE
     vld1.32     {d5}, [TMP4]
     pld         [TMP4, PF_OFFS]
     vmull.u8    q3, d2, d28
     vmlal.u8    q3, d3, d29
     vmull.u8    q1, d4, d28
     vmlal.u8    q1, d5, d29
-    vshr.u16    q15, q12, #8
+    vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vld1.32     {d22[0]}, [MASK]!
     pld         [MASK, #prefetch_offset]
     vadd.u16    q12, q12, q13
     vmovn.u16   d16, q0
 .endm
 
 .macro bilinear_over_8888_8_8888_process_pixblock_tail
-    vshll.u16   q9, d6, #8
-    vshll.u16   q10, d2, #8
+    vshll.u16   q9, d6, #BILINEAR_INTERPOLATION_BITS
+    vshll.u16   q10, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16   q9, d6, d30
     vmlsl.u16   q10, d2, d31
     vmlal.u16   q9, d7, d30
     vmlal.u16   q10, d3, d31
-    vshr.u16    q15, q12, #8
+    vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16    q12, q12, q13
     vdup.32     d22, d22[0]
-    vshrn.u32   d18, q9, #16
-    vshrn.u32   d19, q10, #16
+    vshrn.u32   d18, q9, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32   d19, q10, #(2 * BILINEAR_INTERPOLATION_BITS)
     vmovn.u16   d17, q9
     vld1.32     {d18, d19}, [OUT, :128]
     pld         [OUT, PF_OFFS]
     vuzp.8      d16, d17
     vuzp.8      d18, d19
     vuzp.8      d16, d17
     vuzp.8      d18, d19
     vmull.u8    q10, d16, d22
@@ -1141,66 +1142,66 @@ 3:
     vraddhn.u16 d19, q0, q11
     vqadd.u8    q9, q8, q9
     vuzp.8      d18, d19
     vuzp.8      d18, d19
     vst1.32     {d18, d19}, [OUT, :128]!
 .endm
 
 .macro bilinear_over_8888_8_8888_process_pixblock_tail_head
-                                            vshll.u16   q9, d6, #8
+                                            vshll.u16   q9, d6, #BILINEAR_INTERPOLATION_BITS
     mov         TMP1, X, asr #16
     add         X, X, UX
     add         TMP1, TOP, TMP1, asl #2
-                                            vshll.u16   q10, d2, #8
+                                            vshll.u16   q10, d2, #BILINEAR_INTERPOLATION_BITS
     vld1.32     {d0}, [TMP1], STRIDE
     mov         TMP2, X, asr #16
     add         X, X, UX
     add         TMP2, TOP, TMP2, asl #2
                                             vmlsl.u16   q9, d6, d30
                                             vmlsl.u16   q10, d2, d31
     vld1.32     {d1}, [TMP1]
     mov         TMP3, X, asr #16
     add         X, X, UX
     add         TMP3, TOP, TMP3, asl #2
                                             vmlal.u16   q9, d7, d30
                                             vmlal.u16   q10, d3, d31
     vld1.32     {d2}, [TMP2], STRIDE
     mov         TMP4, X, asr #16
     add         X, X, UX
     add         TMP4, TOP, TMP4, asl #2
-                                            vshr.u16    q15, q12, #8
+                                            vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
                                             vadd.u16    q12, q12, q13
     vld1.32     {d3}, [TMP2]
                                             vdup.32     d22, d22[0]
-                                            vshrn.u32   d18, q9, #16
-                                            vshrn.u32   d19, q10, #16
+                                            vshrn.u32   d18, q9, #(2 * BILINEAR_INTERPOLATION_BITS)
+                                            vshrn.u32   d19, q10, #(2 * BILINEAR_INTERPOLATION_BITS)
     vmull.u8    q2, d0, d28
     vmull.u8    q3, d2, d28
                                             vmovn.u16   d17, q9
                                             vld1.32     {d18, d19}, [OUT, :128]
                                             pld         [OUT, #(prefetch_offset * 4)]
     vmlal.u8    q2, d1, d29
     vmlal.u8    q3, d3, d29
                                             vuzp.8      d16, d17
                                             vuzp.8      d18, d19
-    vshll.u16   q0, d4, #8
-    vshll.u16   q1, d6, #8
+    vshll.u16   q0, d4, #BILINEAR_INTERPOLATION_BITS
+    vshll.u16   q1, d6, #BILINEAR_INTERPOLATION_BITS
                                             vuzp.8      d16, d17
                                             vuzp.8      d18, d19
     vmlsl.u16   q0, d4, d30
     vmlsl.u16   q1, d6, d31
                                             vmull.u8    q10, d16, d22
                                             vmull.u8    q11, d17, d22
     vmlal.u16   q0, d5, d30
     vmlal.u16   q1, d7, d31
                                             vrsra.u16   q10, q10, #8
                                             vrsra.u16   q11, q11, #8
-    vshrn.u32   d0, q0, #16
-    vshrn.u32   d1, q1, #16
+    vshrn.u32   d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32   d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
                                             vrshrn.u16  d16, q10, #8
                                             vrshrn.u16  d17, q11, #8
     vld1.32     {d2}, [TMP3], STRIDE
                                             vdup.32     d22, d17[1]
     vld1.32     {d3}, [TMP3]
                                             vmvn.8      d22, d22
     pld         [TMP4, PF_OFFS]
     vld1.32     {d4}, [TMP4], STRIDE
@@ -1211,17 +1212,17 @@ 3:
     vmull.u8    q3, d2, d28
                                             vrshr.u16   q9, q10, #8
                                             vrshr.u16   q15, q11, #8
     vmlal.u8    q3, d3, d29
     vmull.u8    q1, d4, d28
                                             vraddhn.u16 d18, q9, q10
                                             vraddhn.u16 d19, q15, q11
     vmlal.u8    q1, d5, d29
-    vshr.u16    q15, q12, #8
+    vshr.u16    q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
                                             vqadd.u8    q9, q8, q9
     vld1.32     {d22[0]}, [MASK]!
                                             vuzp.8      d18, d19
     vadd.u16    q12, q12, q13
                                             vuzp.8      d18, d19
     vmovn.u16   d16, q0
                                             vst1.32     {d18, d19}, [OUT, :128]!
 .endm
--- a/gfx/cairo/libpixman/src/pixman-arm-neon-asm.S
+++ b/gfx/cairo/libpixman/src/pixman-arm-neon-asm.S
@@ -44,16 +44,17 @@
     .arch armv7a
     .object_arch armv4
     .eabi_attribute 10, 0 /* suppress Tag_FP_arch */
     .eabi_attribute 12, 0 /* suppress Tag_Advanced_SIMD_arch */
     .arm
     .altmacro
     .p2align 2
 
+#include "pixman-private.h"
 #include "pixman-arm-neon-asm.h"
 
 /* Global configuration options and preferences */
 
 /*
  * The code can optionally make use of unaligned memory accesses to improve
  * performance of handling leading/trailing pixels for each scanline.
  * Configuration variable RESPECT_STRICT_ALIGNMENT can be set to 0 for
@@ -2981,70 +2982,70 @@ fname:
 .endif
 .endm
 
 .macro bilinear_interpolate_last_pixel src_fmt, dst_fmt
     bilinear_load_&src_fmt d0, d1, d2
     vmull.u8  q1, d0, d28
     vmlal.u8  q1, d1, d29
     /* 5 cycles bubble */
-    vshll.u16 q0, d2, #8
+    vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d2, d30
     vmlal.u16 q0, d3, d30
     /* 5 cycles bubble */
-    vshrn.u32 d0, q0, #16
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
     /* 3 cycles bubble */
     vmovn.u16 d0, q0
     /* 1 cycle bubble */
     bilinear_store_&dst_fmt 1, q2, q3
 .endm
 
 .macro bilinear_interpolate_two_pixels src_fmt, dst_fmt
     bilinear_load_and_vertical_interpolate_two_&src_fmt \
                 q1, q11, d0, d1, d20, d21, d22, d23
-    vshll.u16 q0, d2, #8
+    vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d2, d30
     vmlal.u16 q0, d3, d30
-    vshll.u16 q10, d22, #8
+    vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q10, d22, d31
     vmlal.u16 q10, d23, d31
-    vshrn.u32 d0, q0, #16
-    vshrn.u32 d1, q10, #16
-    vshr.u16  q15, q12, #8
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16  q12, q12, q13
     vmovn.u16 d0, q0
     bilinear_store_&dst_fmt 2, q2, q3
 .endm
 
 .macro bilinear_interpolate_four_pixels src_fmt, dst_fmt
     bilinear_load_and_vertical_interpolate_four_&src_fmt \
                 q1, q11, d0, d1, d20, d21, d22, d23 \
                 q3, q9,  d4, d5, d16, d17, d18, d19
     pld       [TMP1, PF_OFFS]
     sub       TMP1, TMP1, STRIDE
-    vshll.u16 q0, d2, #8
+    vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d2, d30
     vmlal.u16 q0, d3, d30
-    vshll.u16 q10, d22, #8
+    vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q10, d22, d31
     vmlal.u16 q10, d23, d31
-    vshr.u16  q15, q12, #8
-    vshll.u16 q2, d6, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshll.u16 q2, d6, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q2, d6, d30
     vmlal.u16 q2, d7, d30
-    vshll.u16 q8, d18, #8
+    vshll.u16 q8, d18, #BILINEAR_INTERPOLATION_BITS
     pld       [TMP2, PF_OFFS]
     vmlsl.u16 q8, d18, d31
     vmlal.u16 q8, d19, d31
     vadd.u16  q12, q12, q13
-    vshrn.u32 d0, q0, #16
-    vshrn.u32 d1, q10, #16
-    vshrn.u32 d4, q2, #16
-    vshrn.u32 d5, q8, #16
-    vshr.u16  q15, q12, #8
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d5, q8, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vmovn.u16 d0, q0
     vmovn.u16 d1, q2
     vadd.u16  q12, q12, q13
     bilinear_store_&dst_fmt 4, q2, q3
 .endm
 
 .macro bilinear_interpolate_four_pixels_head src_fmt, dst_fmt
 .ifdef have_bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt
@@ -3153,23 +3154,23 @@ pixman_asm_function fname
     vdup.u8   d29, WB
     vadd.u16  d25, d25, d26
 
     /* ensure good destination alignment  */
     cmp       WIDTH, #1
     blt       0f
     tst       OUT, #(1 << dst_bpp_shift)
     beq       0f
-    vshr.u16  q15, q12, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16  q12, q12, q13
     bilinear_interpolate_last_pixel src_fmt, dst_fmt
     sub       WIDTH, WIDTH, #1
 0:
     vadd.u16  q13, q13, q13
-    vshr.u16  q15, q12, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vadd.u16  q12, q12, q13
 
     cmp       WIDTH, #2
     blt       0f
     tst       OUT, #(1 << (dst_bpp_shift + 1))
     beq       0f
     bilinear_interpolate_two_pixels src_fmt, dst_fmt
     sub       WIDTH, WIDTH, #2
@@ -3277,105 +3278,105 @@ 3:
     vmull.u8  q9, d22, d28
     vmlal.u8  q9, d23, d29
 
     vld1.32   {d22}, [TMP3], STRIDE
     vld1.32   {d23}, [TMP3]
     vmull.u8  q10, d22, d28
     vmlal.u8  q10, d23, d29
 
-    vshll.u16 q0, d16, #8
+    vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d16, d30
     vmlal.u16 q0, d17, d30
 
     pld       [TMP4, PF_OFFS]
     vld1.32   {d16}, [TMP4], STRIDE
     vld1.32   {d17}, [TMP4]
     pld       [TMP4, PF_OFFS]
     vmull.u8  q11, d16, d28
     vmlal.u8  q11, d17, d29
 
-    vshll.u16 q1, d18, #8
+    vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q1, d18, d31
 .endm
 
 .macro bilinear_interpolate_four_pixels_8888_8888_tail
     vmlal.u16 q1, d19, d31
-    vshr.u16  q15, q12, #8
-    vshll.u16 q2, d20, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q2, d20, d30
     vmlal.u16 q2, d21, d30
-    vshll.u16 q3, d22, #8
+    vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q3, d22, d31
     vmlal.u16 q3, d23, d31
     vadd.u16  q12, q12, q13
-    vshrn.u32 d0, q0, #16
-    vshrn.u32 d1, q1, #16
-    vshrn.u32 d4, q2, #16
-    vshr.u16  q15, q12, #8
-    vshrn.u32 d5, q3, #16
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
     vmovn.u16 d6, q0
     vmovn.u16 d7, q2
     vadd.u16  q12, q12, q13
     vst1.32   {d6, d7}, [OUT, :128]!
 .endm
 
 .macro bilinear_interpolate_four_pixels_8888_8888_tail_head
     mov       TMP1, X, asr #16
     add       X, X, UX
     add       TMP1, TOP, TMP1, asl #2
     mov       TMP2, X, asr #16
     add       X, X, UX
     add       TMP2, TOP, TMP2, asl #2
         vmlal.u16 q1, d19, d31
-        vshr.u16  q15, q12, #8
-        vshll.u16 q2, d20, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+        vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS
         vmlsl.u16 q2, d20, d30
         vmlal.u16 q2, d21, d30
-        vshll.u16 q3, d22, #8
+        vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS
     vld1.32   {d20}, [TMP1], STRIDE
         vmlsl.u16 q3, d22, d31
         vmlal.u16 q3, d23, d31
     vld1.32   {d21}, [TMP1]
     vmull.u8  q8, d20, d28
     vmlal.u8  q8, d21, d29
-        vshrn.u32 d0, q0, #16
-        vshrn.u32 d1, q1, #16
-        vshrn.u32 d4, q2, #16
+        vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+        vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
+        vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d22}, [TMP2], STRIDE
-        vshrn.u32 d5, q3, #16
+        vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
         vadd.u16  q12, q12, q13
     vld1.32   {d23}, [TMP2]
     vmull.u8  q9, d22, d28
     mov       TMP3, X, asr #16
     add       X, X, UX
     add       TMP3, TOP, TMP3, asl #2
     mov       TMP4, X, asr #16
     add       X, X, UX
     add       TMP4, TOP, TMP4, asl #2
     vmlal.u8  q9, d23, d29
     vld1.32   {d22}, [TMP3], STRIDE
-        vshr.u16  q15, q12, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d23}, [TMP3]
     vmull.u8  q10, d22, d28
     vmlal.u8  q10, d23, d29
         vmovn.u16 d6, q0
-    vshll.u16 q0, d16, #8
+    vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS
         vmovn.u16 d7, q2
     vmlsl.u16 q0, d16, d30
     vmlal.u16 q0, d17, d30
     pld       [TMP4, PF_OFFS]
     vld1.32   {d16}, [TMP4], STRIDE
         vadd.u16  q12, q12, q13
     vld1.32   {d17}, [TMP4]
     pld       [TMP4, PF_OFFS]
     vmull.u8  q11, d16, d28
     vmlal.u8  q11, d17, d29
         vst1.32   {d6, d7}, [OUT, :128]!
-    vshll.u16 q1, d18, #8
+    vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q1, d18, d31
 .endm
 
 /*****************************************************************************/
 
 .set have_bilinear_interpolate_eight_pixels_8888_0565, 1
 
 .macro bilinear_interpolate_eight_pixels_8888_0565_head
@@ -3398,97 +3399,97 @@ 3:
     mov       TMP4, X, asr #16
     add       X, X, UX
     add       TMP4, TOP, TMP4, asl #2
     vmlal.u8  q9, d23, d29
     vld1.32   {d22}, [TMP3], STRIDE
     vld1.32   {d23}, [TMP3]
     vmull.u8  q10, d22, d28
     vmlal.u8  q10, d23, d29
-    vshll.u16 q0, d16, #8
+    vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q0, d16, d30
     vmlal.u16 q0, d17, d30
     pld       [TMP4, PF_OFFS]
     vld1.32   {d16}, [TMP4], STRIDE
     vld1.32   {d17}, [TMP4]
     pld       [TMP4, PF_OFFS]
     vmull.u8  q11, d16, d28
     vmlal.u8  q11, d17, d29
-    vshll.u16 q1, d18, #8
+    vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q1, d18, d31
 
     mov       TMP1, X, asr #16
     add       X, X, UX
     add       TMP1, TOP, TMP1, asl #2
     mov       TMP2, X, asr #16
     add       X, X, UX
     add       TMP2, TOP, TMP2, asl #2
         vmlal.u16 q1, d19, d31
-        vshr.u16  q15, q12, #8
-        vshll.u16 q2, d20, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+        vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS
         vmlsl.u16 q2, d20, d30
         vmlal.u16 q2, d21, d30
-        vshll.u16 q3, d22, #8
+        vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS
     vld1.32   {d20}, [TMP1], STRIDE
         vmlsl.u16 q3, d22, d31
         vmlal.u16 q3, d23, d31
     vld1.32   {d21}, [TMP1]
     vmull.u8  q8, d20, d28
     vmlal.u8  q8, d21, d29
-        vshrn.u32 d0, q0, #16
-        vshrn.u32 d1, q1, #16
-        vshrn.u32 d4, q2, #16
+        vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+        vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
+        vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d22}, [TMP2], STRIDE
-        vshrn.u32 d5, q3, #16
+        vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
         vadd.u16  q12, q12, q13
     vld1.32   {d23}, [TMP2]
     vmull.u8  q9, d22, d28
     mov       TMP3, X, asr #16
     add       X, X, UX
     add       TMP3, TOP, TMP3, asl #2
     mov       TMP4, X, asr #16
     add       X, X, UX
     add       TMP4, TOP, TMP4, asl #2
     vmlal.u8  q9, d23, d29
     vld1.32   {d22}, [TMP3], STRIDE
-        vshr.u16  q15, q12, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d23}, [TMP3]
     vmull.u8  q10, d22, d28
     vmlal.u8  q10, d23, d29
         vmovn.u16 d8, q0
-    vshll.u16 q0, d16, #8
+    vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS
         vmovn.u16 d9, q2
     vmlsl.u16 q0, d16, d30
     vmlal.u16 q0, d17, d30
     pld       [TMP4, PF_OFFS]
     vld1.32   {d16}, [TMP4], STRIDE
         vadd.u16  q12, q12, q13
     vld1.32   {d17}, [TMP4]
     pld       [TMP4, PF_OFFS]
     vmull.u8  q11, d16, d28
     vmlal.u8  q11, d17, d29
-    vshll.u16 q1, d18, #8
+    vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q1, d18, d31
 .endm
 
 .macro bilinear_interpolate_eight_pixels_8888_0565_tail
     vmlal.u16 q1, d19, d31
-    vshr.u16  q15, q12, #8
-    vshll.u16 q2, d20, #8
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q2, d20, d30
     vmlal.u16 q2, d21, d30
-    vshll.u16 q3, d22, #8
+    vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q3, d22, d31
     vmlal.u16 q3, d23, d31
     vadd.u16  q12, q12, q13
-    vshrn.u32 d0, q0, #16
-    vshrn.u32 d1, q1, #16
-    vshrn.u32 d4, q2, #16
-    vshr.u16  q15, q12, #8
-    vshrn.u32 d5, q3, #16
+    vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
+    vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+    vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
     vmovn.u16 d10, q0
     vmovn.u16 d11, q2
     vadd.u16  q12, q12, q13
 
     vuzp.u8   d8, d9
     vuzp.u8   d10, d11
     vuzp.u8   d9, d11
     vuzp.u8   d8, d10
@@ -3503,122 +3504,122 @@ 3:
 .macro bilinear_interpolate_eight_pixels_8888_0565_tail_head
     mov       TMP1, X, asr #16
     add       X, X, UX
     add       TMP1, TOP, TMP1, asl #2
     mov       TMP2, X, asr #16
     add       X, X, UX
     add       TMP2, TOP, TMP2, asl #2
         vmlal.u16 q1, d19, d31
-        vshr.u16  q15, q12, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
             vuzp.u8 d8, d9
-        vshll.u16 q2, d20, #8
+        vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS
         vmlsl.u16 q2, d20, d30
         vmlal.u16 q2, d21, d30
-        vshll.u16 q3, d22, #8
+        vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS
     vld1.32   {d20}, [TMP1], STRIDE
         vmlsl.u16 q3, d22, d31
         vmlal.u16 q3, d23, d31
     vld1.32   {d21}, [TMP1]
     vmull.u8  q8, d20, d28
     vmlal.u8  q8, d21, d29
-        vshrn.u32 d0, q0, #16
-        vshrn.u32 d1, q1, #16
-        vshrn.u32 d4, q2, #16
+        vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
+        vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
+        vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d22}, [TMP2], STRIDE
-        vshrn.u32 d5, q3, #16
+        vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
         vadd.u16  q12, q12, q13
     vld1.32   {d23}, [TMP2]
     vmull.u8  q9, d22, d28
     mov       TMP3, X, asr #16
     add       X, X, UX
     add       TMP3, TOP, TMP3, asl #2
     mov       TMP4, X, asr #16
     add       X, X, UX
     add       TMP4, TOP, TMP4, asl #2
     vmlal.u8  q9, d23, d29
     vld1.32   {d22}, [TMP3], STRIDE
-        vshr.u16  q15, q12, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d23}, [TMP3]
     vmull.u8  q10, d22, d28
     vmlal.u8  q10, d23, d29
         vmovn.u16 d10, q0
-    vshll.u16 q0, d16, #8
+    vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS
         vmovn.u16 d11, q2
     vmlsl.u16 q0, d16, d30
     vmlal.u16 q0, d17, d30
     pld       [TMP4, PF_OFFS]
     vld1.32   {d16}, [TMP4], STRIDE
         vadd.u16  q12, q12, q13
     vld1.32   {d17}, [TMP4]
     pld       [TMP4, PF_OFFS]
     vmull.u8  q11, d16, d28
     vmlal.u8  q11, d17, d29
             vuzp.u8 d10, d11
-    vshll.u16 q1, d18, #8
+    vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS
     vmlsl.u16 q1, d18, d31
 
     mov       TMP1, X, asr #16
     add       X, X, UX
     add       TMP1, TOP, TMP1, asl #2
     mov       TMP2, X, asr #16
     add       X, X, UX
     add       TMP2, TOP, TMP2, asl #2
         vmlal.u16 q1, d19, d31
             vuzp.u8 d9, d11
-        vshr.u16  q15, q12, #8
-        vshll.u16 q2, d20, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
+        vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS
             vuzp.u8 d8, d10
         vmlsl.u16 q2, d20, d30
         vmlal.u16 q2, d21, d30
-        vshll.u16 q3, d22, #8
+        vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS
     vld1.32   {d20}, [TMP1], STRIDE
         vmlsl.u16 q3, d22, d31
         vmlal.u16 q3, d23, d31
     vld1.32   {d21}, [TMP1]
     vmull.u8  q8, d20, d28
     vmlal.u8  q8, d21, d29
             vshll.u8  q6, d9, #8
             vshll.u8  q5, d10, #8
             vshll.u8  q7, d8, #8
-        vshrn.u32 d0, q0, #16
+        vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS)
             vsri.u16  q5, q6, #5
-        vshrn.u32 d1, q1, #16
+        vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS)
             vsri.u16  q5, q7, #11
-        vshrn.u32 d4, q2, #16
+        vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d22}, [TMP2], STRIDE
-        vshrn.u32 d5, q3, #16
+        vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS)
         vadd.u16  q12, q12, q13
     vld1.32   {d23}, [TMP2]
     vmull.u8  q9, d22, d28
     mov       TMP3, X, asr #16
     add       X, X, UX
     add       TMP3, TOP, TMP3, asl #2
     mov       TMP4, X, asr #16
     add       X, X, UX
     add       TMP4, TOP, TMP4, asl #2
     vmlal.u8  q9, d23, d29
     vld1.32   {d22}, [TMP3], STRIDE
-        vshr.u16  q15, q12, #8
+        vshr.u16  q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS)
     vld1.32   {d23}, [TMP3]
     vmull.u8  q10, d22, d28
     vmlal.u8  q10, d23, d29
         vmovn.u16 d8, q0
-    vshll.u16 q0, d16, #8
+    vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS
         vmovn.u16 d9, q2
     vmlsl.u16 q0, d16, d30
     vmlal.u16 q0, d17, d30
     pld       [TMP4, PF_OFFS]
     vld1.32   {d16}, [TMP4], STRIDE
         vadd.u16  q12, q12, q13
     vld1.32   {d17}, [TMP4]
     pld       [TMP4, PF_OFFS]
     vmull.u8  q11, d16, d28
     vmlal.u8  q11, d17, d29
-    vshll.u16 q1, d18, #8
+    vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS
             vst1.32   {d10, d11}, [OUT, :128]!
     vmlsl.u16 q1, d18, d31
 .endm
 /*****************************************************************************/
 
 generate_bilinear_scanline_func \
     pixman_scaled_bilinear_scanline_8888_8888_SRC_asm_neon, 8888, 8888, \
     2, 2, 28, BILINEAR_FLAG_UNROLL_4
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/libpixman/src/pixman-arm.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+
+typedef enum
+{
+    ARM_V7		= (1 << 0),
+    ARM_V6		= (1 << 1),
+    ARM_VFP		= (1 << 2),
+    ARM_NEON		= (1 << 3),
+    ARM_IWMMXT		= (1 << 4)
+} arm_cpu_features_t;
+
+#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
+
+#if defined(_MSC_VER)
+
+/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
+#include <windows.h>
+
+extern int pixman_msvc_try_arm_neon_op ();
+extern int pixman_msvc_try_arm_simd_op ();
+
+static arm_cpu_features_t
+detect_cpu_features (void)
+{
+    arm_cpu_features_t features = 0;
+
+    __try
+    {
+	pixman_msvc_try_arm_simd_op ();
+	features |= ARM_V6;
+    }
+    __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
+    {
+    }
+
+    __try
+    {
+	pixman_msvc_try_arm_neon_op ();
+	features |= ARM_NEON;
+    }
+    __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
+    {
+    }
+
+    return features;
+}
+
+#elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) /* iOS */
+
+#include "TargetConditionals.h"
+
+static arm_cpu_features_t
+detect_cpu_features (void)
+{
+    arm_cpu_features_t features = 0;
+
+    features |= ARM_V6;
+
+    /* Detection of ARM NEON on iOS is fairly simple because iOS binaries
+     * contain separate executable images for each processor architecture.
+     * So all we have to do is detect the armv7 architecture build. The
+     * operating system automatically runs the armv7 binary for armv7 devices
+     * and the armv6 binary for armv6 devices.
+     */
+#if defined(__ARM_NEON__)
+    features |= ARM_NEON;
+#endif
+
+    return features;
+}
+
+#elif defined(__ANDROID__) || defined(ANDROID) /* Android */
+
+static arm_cpu_features_t
+detect_cpu_features (void)
+{
+    arm_cpu_features_t features = 0;
+    char buf[1024];
+    char* pos;
+    const char* ver_token = "CPU architecture: ";
+    FILE* f = fopen("/proc/cpuinfo", "r");
+    if (!f) {
+	return features;
+    }
+
+    fread(buf, sizeof(char), sizeof(buf), f);
+    fclose(f);
+    pos = strstr(buf, ver_token);
+    if (pos) {
+	char vchar = *(pos + strlen(ver_token));
+	if (vchar >= '0' && vchar <= '9') {
+	    int ver = vchar - '0';
+	    if (ver >= 7)
+		features |= ARM_V7;
+	}
+    }
+    if (strstr(buf, "neon") != NULL)
+	features |= ARM_NEON;
+    if (strstr(buf, "vfp") != NULL)
+	features |= ARM_VFP;
+
+    return features;
+}
+
+#elif defined (__linux__) /* linux ELF */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <elf.h>
+
+static arm_cpu_features_t
+detect_cpu_features (void)
+{
+    arm_cpu_features_t features = 0;
+    Elf32_auxv_t aux;
+    int fd;
+
+    fd = open ("/proc/self/auxv", O_RDONLY);
+    if (fd >= 0)
+    {
+	while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
+	{
+	    if (aux.a_type == AT_HWCAP)
+	    {
+		uint32_t hwcap = aux.a_un.a_val;
+
+		/* hardcode these values to avoid depending on specific
+		 * versions of the hwcap header, e.g. HWCAP_NEON
+		 */
+		if ((hwcap & 64) != 0)
+		    features |= ARM_VFP;
+		if ((hwcap & 512) != 0)
+		    features |= ARM_IWMMXT;
+		/* this flag is only present on kernel 2.6.29 */
+		if ((hwcap & 4096) != 0)
+		    features |= ARM_NEON;
+	    }
+	    else if (aux.a_type == AT_PLATFORM)
+	    {
+		const char *plat = (const char*) aux.a_un.a_val;
+
+		if (strncmp (plat, "v7l", 3) == 0)
+		    features |= (ARM_V7 | ARM_V6);
+		else if (strncmp (plat, "v6l", 3) == 0)
+		    features |= ARM_V6;
+	    }
+	}
+	close (fd);
+    }
+
+    return features;
+}
+
+#else /* Unknown */
+
+static arm_cpu_features_t
+detect_cpu_features (void)
+{
+    return 0;
+}
+
+#endif /* Linux elf */
+
+static pixman_bool_t
+have_feature (arm_cpu_features_t feature)
+{
+    static pixman_bool_t initialized;
+    static arm_cpu_features_t features;
+
+    if (!initialized)
+    {
+	features = detect_cpu_features();
+	initialized = TRUE;
+    }
+
+    return (features & feature) == feature;
+}
+
+#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
+
+pixman_implementation_t *
+_pixman_arm_get_implementations (pixman_implementation_t *imp)
+{
+#ifdef USE_ARM_SIMD
+    if (!_pixman_disabled ("arm-simd") && have_feature (ARM_V6))
+	imp = _pixman_implementation_create_arm_simd (imp);
+#endif
+
+#ifdef USE_ARM_IWMMXT
+    if (!_pixman_disabled ("arm-iwmmxt") && have_feature (ARM_IWMMXT))
+	imp = _pixman_implementation_create_mmx (imp);
+#endif
+
+#ifdef USE_ARM_NEON
+    if (!_pixman_disabled ("arm-neon") && have_feature (ARM_NEON))
+	imp = _pixman_implementation_create_arm_neon (imp);
+#endif
+
+    return imp;
+}
--- a/gfx/cairo/libpixman/src/pixman-bits-image.c
+++ b/gfx/cairo/libpixman/src/pixman-bits-image.c
@@ -37,45 +37,47 @@
 #include "pixman-inlines.h"
 
 /*
  * By default, just evaluate the image at 32bpp and expand.  Individual image
  * types can plug in a better scanline getter if they want to. For example
  * we  could produce smoother gradients by evaluating them at higher color
  * depth, but that's a project for the future.
  */
-static void
-_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
-                                       int              x,
-                                       int              y,
-                                       int              width,
-                                       uint32_t *       buffer,
-                                       const uint32_t * mask)
+static uint32_t *
+_pixman_image_get_scanline_generic_64 (pixman_iter_t * iter,
+                                       const uint32_t *mask)
 {
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
+    pixman_iter_get_scanline_t fetch_32 = iter->data;
     uint32_t *mask8 = NULL;
 
     /* Contract the mask image, if one exists, so that the 32-bit fetch
      * function can use it.
      */
     if (mask)
     {
 	mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
 	if (!mask8)
-	    return;
+	    return buffer;
 
 	pixman_contract (mask8, (uint64_t *)mask, width);
     }
 
     /* Fetch the source image into the first half of buffer. */
-    image->bits.get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
+    fetch_32 (iter, mask8);
 
     /* Expand from 32bpp to 64bpp in place. */
     pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
 
     free (mask8);
+
+    return buffer;
 }
 
 /* Fetch functions */
 
 static force_inline uint32_t
 fetch_pixel_no_alpha (bits_image_t *image,
 		      int x, int y, pixman_bool_t check_bounds)
 {
@@ -124,18 +126,18 @@ bits_image_fetch_pixel_bilinear (bits_im
     int height = image->height;
     int x1, y1, x2, y2;
     uint32_t tl, tr, bl, br;
     int32_t distx, disty;
 
     x1 = x - pixman_fixed_1 / 2;
     y1 = y - pixman_fixed_1 / 2;
 
-    distx = interpolation_coord(x1);
-    disty = interpolation_coord(y1);
+    distx = pixman_fixed_to_bilinear_weight (x1);
+    disty = pixman_fixed_to_bilinear_weight (y1);
 
     x1 = pixman_fixed_to_int (x1);
     y1 = pixman_fixed_to_int (y1);
     x2 = x1 + 1;
     y2 = y1 + 1;
 
     if (repeat_mode != PIXMAN_REPEAT_NONE)
     {
@@ -155,24 +157,27 @@ bits_image_fetch_pixel_bilinear (bits_im
 	tr = get_pixel (image, x2, y1, TRUE);
 	bl = get_pixel (image, x1, y2, TRUE);
 	br = get_pixel (image, x2, y2, TRUE);
     }
 
     return bilinear_interpolation (tl, tr, bl, br, distx, disty);
 }
 
-static void
-bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
-					  int              offset,
-					  int              line,
-					  int              width,
-					  uint32_t *       buffer,
-					  const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
+					  const uint32_t *mask)
 {
+
+    pixman_image_t * ima = iter->image;
+    int              offset = iter->x;
+    int              line = iter->y++;
+    int              width = iter->width;
+    uint32_t *       buffer = iter->buffer;
+
     bits_image_t *bits = &ima->bits;
     pixman_fixed_t x_top, x_bottom, x;
     pixman_fixed_t ux_top, ux_bottom, ux;
     pixman_vector_t v;
     uint32_t top_mask, bottom_mask;
     uint32_t *top_row;
     uint32_t *bottom_row;
     uint32_t *end;
@@ -184,23 +189,23 @@ bits_image_fetch_bilinear_no_repeat_8888
     int w;
 
     /* reference point is the center of the pixel */
     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     if (!pixman_transform_point_3d (bits->common.transform, &v))
-	return;
+	return iter->buffer;
 
     ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
     x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
 
     y = v.vector[1] - pixman_fixed_1/2;
-    disty = interpolation_coord(y);
+    disty = pixman_fixed_to_bilinear_weight (y);
 
     /* Load the pointers to the first and second lines from the source
      * image that bilinear code must read.
      *
      * The main trick in this code is about the check if any line are
      * outside of the image;
      *
      * When I realize that a line (any one) is outside, I change
@@ -251,17 +256,17 @@ bits_image_fetch_bilinear_no_repeat_8888
         /* If have a mask, prepare the variables to check it */
         mask_inc = 1;
     }
 
     /* If both are zero, then the whole thing is zero */
     if (top_row == zero && bottom_row == zero)
     {
 	memset (buffer, 0, width * sizeof (uint32_t));
-	return;
+	return iter->buffer;
     }
     else if (bits->format == PIXMAN_x8r8g8b8)
     {
 	if (top_row == zero)
 	{
 	    top_mask = 0;
 	    bottom_mask = 0xff000000;
 	}
@@ -299,17 +304,17 @@ bits_image_fetch_bilinear_no_repeat_8888
     while (buffer < end && x < 0)
     {
 	uint32_t tr, br;
 	int32_t distx;
 
 	tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask;
 	br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
 
-	distx = interpolation_coord(x);
+	distx = pixman_fixed_to_bilinear_weight (x);
 
 	*buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
 
 	x += ux;
 	x_top += ux_top;
 	x_bottom += ux_bottom;
 	mask += mask_inc;
     }
@@ -324,17 +329,17 @@ bits_image_fetch_bilinear_no_repeat_8888
 	    uint32_t tl, tr, bl, br;
 	    int32_t distx;
 
 	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
 	    tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask;
 	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
 	    br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask;
 
-	    distx = interpolation_coord(x);
+	    distx = pixman_fixed_to_bilinear_weight (x);
 
 	    *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
 	}
 
 	buffer++;
 	x += ux;
 	x_top += ux_top;
 	x_bottom += ux_bottom;
@@ -348,49 +353,51 @@ bits_image_fetch_bilinear_no_repeat_8888
 	if (*mask)
 	{
 	    uint32_t tl, bl;
 	    int32_t distx;
 
 	    tl = top_row [pixman_fixed_to_int (x_top)] | top_mask;
 	    bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask;
 
-	    distx = interpolation_coord(x);
+	    distx = pixman_fixed_to_bilinear_weight (x);
 
 	    *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
 	}
 
 	buffer++;
 	x += ux;
 	x_top += ux_top;
 	x_bottom += ux_bottom;
 	mask += mask_inc;
     }
 
     /* Zero fill to the left of the image */
     while (buffer < end)
 	*buffer++ = 0;
+
+    return iter->buffer;
 }
 
 static force_inline uint32_t
 bits_image_fetch_pixel_convolution (bits_image_t   *image,
 				    pixman_fixed_t  x,
 				    pixman_fixed_t  y,
 				    get_pixel_t     get_pixel)
 {
     pixman_fixed_t *params = image->common.filter_params;
     int x_off = (params[0] - pixman_fixed_1) >> 1;
     int y_off = (params[1] - pixman_fixed_1) >> 1;
     int32_t cwidth = pixman_fixed_to_int (params[0]);
     int32_t cheight = pixman_fixed_to_int (params[1]);
-    int32_t srtot, sgtot, sbtot, satot;
     int32_t i, j, x1, x2, y1, y2;
     pixman_repeat_t repeat_mode = image->common.repeat;
     int width = image->width;
     int height = image->height;
+    int srtot, sgtot, sbtot, satot;
 
     params += 2;
 
     x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
     y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
     x2 = x1 + cwidth;
     y2 = y1 + cheight;
 
@@ -416,20 +423,20 @@ bits_image_fetch_pixel_convolution (bits
 
 		    pixel = get_pixel (image, rx, ry, FALSE);
 		}
 		else
 		{
 		    pixel = get_pixel (image, rx, ry, TRUE);
 		}
 
-		srtot += RED_8 (pixel) * f;
-		sgtot += GREEN_8 (pixel) * f;
-		sbtot += BLUE_8 (pixel) * f;
-		satot += ALPHA_8 (pixel) * f;
+		srtot += (int)RED_8 (pixel) * f;
+		sgtot += (int)GREEN_8 (pixel) * f;
+		sbtot += (int)BLUE_8 (pixel) * f;
+		satot += (int)ALPHA_8 (pixel) * f;
 	    }
 
 	    params++;
 	}
     }
 
     satot >>= 16;
     srtot >>= 16;
@@ -469,38 +476,40 @@ bits_image_fetch_pixel_filtered (bits_im
 
     default:
         break;
     }
 
     return 0;
 }
 
-static void
-bits_image_fetch_affine_no_alpha (pixman_image_t * image,
-				  int              offset,
-				  int              line,
-				  int              width,
-				  uint32_t *       buffer,
+static uint32_t *
+bits_image_fetch_affine_no_alpha (pixman_iter_t *  iter,
 				  const uint32_t * mask)
 {
+    pixman_image_t *image  = iter->image;
+    int             offset = iter->x;
+    int             line   = iter->y++;
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
     pixman_fixed_t x, y;
     pixman_fixed_t ux, uy;
     pixman_vector_t v;
     int i;
 
     /* reference point is the center of the pixel */
     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     if (image->common.transform)
     {
 	if (!pixman_transform_point_3d (image->common.transform, &v))
-	    return;
+	    return iter->buffer;
 
 	ux = image->common.transform->matrix[0][0];
 	uy = image->common.transform->matrix[1][0];
     }
     else
     {
 	ux = pixman_fixed_1;
 	uy = 0;
@@ -515,16 +524,18 @@ bits_image_fetch_affine_no_alpha (pixman
 	{
 	    buffer[i] = bits_image_fetch_pixel_filtered (
 		&image->bits, x, y, fetch_pixel_no_alpha);
 	}
 
 	x += ux;
 	y += uy;
     }
+
+    return buffer;
 }
 
 /* General fetcher */
 static force_inline uint32_t
 fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds)
 {
     uint32_t pixel;
 
@@ -558,38 +569,40 @@ fetch_pixel_general (bits_image_t *image
 
 	pixel &= 0x00ffffff;
 	pixel |= (pixel_a << 24);
     }
 
     return pixel;
 }
 
-static void
-bits_image_fetch_general (pixman_image_t * image,
-			  int              offset,
-			  int              line,
-			  int              width,
-			  uint32_t *       buffer,
-			  const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_general (pixman_iter_t  *iter,
+			  const uint32_t *mask)
 {
+    pixman_image_t *image  = iter->image;
+    int             offset = iter->x;
+    int             line   = iter->y++;
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
     pixman_fixed_t x, y, w;
     pixman_fixed_t ux, uy, uw;
     pixman_vector_t v;
     int i;
 
     /* reference point is the center of the pixel */
     v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
     v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     if (image->common.transform)
     {
 	if (!pixman_transform_point_3d (image->common.transform, &v))
-	    return;
+	    return buffer;
 
 	ux = image->common.transform->matrix[0][0];
 	uy = image->common.transform->matrix[1][0];
 	uw = image->common.transform->matrix[2][0];
     }
     else
     {
 	ux = pixman_fixed_1;
@@ -621,16 +634,18 @@ bits_image_fetch_general (pixman_image_t
 	    buffer[i] = bits_image_fetch_pixel_filtered (
 		&image->bits, x0, y0, fetch_pixel_general);
 	}
 
 	x += ux;
 	y += uy;
 	w += uw;
     }
+
+    return buffer;
 }
 
 static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
 typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
 
 static force_inline void
 bits_image_fetch_bilinear_affine (pixman_image_t * image,
@@ -675,18 +690,18 @@ bits_image_fetch_bilinear_affine (pixman
 	const uint8_t *row2;
 
 	if (mask && !mask[i])
 	    goto next;
 
 	x1 = x - pixman_fixed_1 / 2;
 	y1 = y - pixman_fixed_1 / 2;
 
-	distx = interpolation_coord(x1);
-	disty = interpolation_coord(y1);
+	distx = pixman_fixed_to_bilinear_weight (x1);
+	disty = pixman_fixed_to_bilinear_weight (y1);
 
 	y1 = pixman_fixed_to_int (y1);
 	y2 = y1 + 1;
 	x1 = pixman_fixed_to_int (x1);
 	x2 = x1 + 1;
 
 	if (repeat_mode != PIXMAN_REPEAT_NONE)
 	{
@@ -877,45 +892,43 @@ convert_a8 (const uint8_t *row, int x)
 
 static force_inline uint32_t
 convert_r5g6b5 (const uint8_t *row, int x)
 {
     return CONVERT_0565_TO_0888 (*((uint16_t *)row + x));
 }
 
 #define MAKE_BILINEAR_FETCHER(name, format, repeat_mode)		\
-    static void								\
-    bits_image_fetch_bilinear_affine_ ## name (pixman_image_t *image,	\
-					       int              offset,	\
-					       int              line,	\
-					       int              width,	\
-					       uint32_t *       buffer,	\
+    static uint32_t *							\
+    bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t   *iter,	\
 					       const uint32_t * mask)	\
     {									\
-	bits_image_fetch_bilinear_affine (image, offset, line,		\
-					  width, buffer, mask,		\
+	bits_image_fetch_bilinear_affine (iter->image,			\
+					  iter->x, iter->y++,		\
+					  iter->width,			\
+					  iter->buffer, mask,		\
 					  convert_ ## format,		\
 					  PIXMAN_ ## format,		\
 					  repeat_mode);			\
+	return iter->buffer;						\
     }
 
 #define MAKE_NEAREST_FETCHER(name, format, repeat_mode)			\
-    static void								\
-    bits_image_fetch_nearest_affine_ ## name (pixman_image_t *image,	\
-					      int              offset,	\
-					      int              line,	\
-					      int              width,	\
-					      uint32_t *       buffer,	\
+    static uint32_t *							\
+    bits_image_fetch_nearest_affine_ ## name (pixman_iter_t   *iter,	\
 					      const uint32_t * mask)	\
     {									\
-	bits_image_fetch_nearest_affine (image, offset, line,		\
-					 width, buffer, mask,		\
+	bits_image_fetch_nearest_affine (iter->image,			\
+					 iter->x, iter->y++,		\
+					 iter->width,			\
+					 iter->buffer, mask,		\
 					 convert_ ## format,		\
 					 PIXMAN_ ## format,		\
 					 repeat_mode);			\
+	return iter->buffer;						\
     }
 
 #define MAKE_FETCHERS(name, format, repeat_mode)			\
     MAKE_NEAREST_FETCHER (name, format, repeat_mode)			\
     MAKE_BILINEAR_FETCHER (name, format, repeat_mode)
 
 MAKE_FETCHERS (pad_a8r8g8b8,     a8r8g8b8, PIXMAN_REPEAT_PAD)
 MAKE_FETCHERS (none_a8r8g8b8,    a8r8g8b8, PIXMAN_REPEAT_NONE)
@@ -1054,62 +1067,77 @@ bits_image_fetch_untransformed_repeat_no
 	    image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL);
 
 	buffer += w * (wide? 2 : 1);
 	x += w;
 	width -= w;
     }
 }
 
-static void
-bits_image_fetch_untransformed_32 (pixman_image_t * image,
-                                   int              x,
-                                   int              y,
-                                   int              width,
-                                   uint32_t *       buffer,
-                                   const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
+				   const uint32_t *mask)
 {
+    pixman_image_t *image  = iter->image;
+    int             x      = iter->x;
+    int             y      = iter->y;
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
     if (image->common.repeat == PIXMAN_REPEAT_NONE)
     {
 	bits_image_fetch_untransformed_repeat_none (
 	    &image->bits, FALSE, x, y, width, buffer);
     }
     else
     {
 	bits_image_fetch_untransformed_repeat_normal (
 	    &image->bits, FALSE, x, y, width, buffer);
     }
+
+    iter->y++;
+    return buffer;
 }
 
-static void
-bits_image_fetch_untransformed_64 (pixman_image_t * image,
-                                   int              x,
-                                   int              y,
-                                   int              width,
-                                   uint32_t *       buffer,
-                                   const uint32_t * unused)
+static uint32_t *
+bits_image_fetch_untransformed_64 (pixman_iter_t * iter,
+                                   const uint32_t *mask)
+				   
 {
+    pixman_image_t *image  = iter->image;
+    int             x      = iter->x;
+    int             y      = iter->y;
+    int             width  = iter->width;
+    uint32_t *      buffer = iter->buffer;
+
     if (image->common.repeat == PIXMAN_REPEAT_NONE)
     {
 	bits_image_fetch_untransformed_repeat_none (
 	    &image->bits, TRUE, x, y, width, buffer);
     }
     else
     {
 	bits_image_fetch_untransformed_repeat_normal (
 	    &image->bits, TRUE, x, y, width, buffer);
     }
+
+    iter->y++;
+    return buffer;
 }
 
+static uint32_t *
+_pixman_image_get_scanline_generic_64 (pixman_iter_t   *iter,
+				       const uint32_t * mask);
+
 typedef struct
 {
     pixman_format_code_t	format;
     uint32_t			flags;
-    fetch_scanline_t		fetch_32;
-    fetch_scanline_t		fetch_64;
+    pixman_iter_get_scanline_t	get_scanline_32;
+    pixman_iter_get_scanline_t	get_scanline_64;
 } fetcher_info_t;
 
 static const fetcher_info_t fetcher_info[] =
 {
     { PIXMAN_any,
       (FAST_PATH_NO_ALPHA_MAP			|
        FAST_PATH_ID_TRANSFORM			|
        FAST_PATH_NO_CONVOLUTION_FILTER		|
@@ -1201,63 +1229,46 @@ static const fetcher_info_t fetcher_info
     { PIXMAN_any, 0, bits_image_fetch_general, _pixman_image_get_scanline_generic_64 },
 
     { PIXMAN_null },
 };
 
 static void
 bits_image_property_changed (pixman_image_t *image)
 {
-    uint32_t flags = image->common.flags;
-    pixman_format_code_t format = image->common.extended_format_code;
-    const fetcher_info_t *info;
-
     _pixman_bits_image_setup_accessors (&image->bits);
-
-    info = fetcher_info;
-    while (info->format != PIXMAN_null)
-    {
-	if ((info->format == format || info->format == PIXMAN_any)	&&
-	    (info->flags & flags) == info->flags)
-	{
-	    image->bits.get_scanline_32 = info->fetch_32;
-	    image->bits.get_scanline_64 = info->fetch_64;
-	    break;
-	}
-
-	info++;
-    }
-}
-
-static uint32_t *
-src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
-{
-    iter->image->bits.get_scanline_32 (
-	iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
-
-    return iter->buffer;
-}
-
-static uint32_t *
-src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
-{
-    iter->image->bits.get_scanline_64 (
-	iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
-
-    return iter->buffer;
 }
 
 void
 _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
 {
-    if (iter->flags & ITER_NARROW)
-	iter->get_scanline = src_get_scanline_narrow;
-    else
-	iter->get_scanline = src_get_scanline_wide;
+    pixman_format_code_t format = image->common.extended_format_code;
+    uint32_t flags = image->common.flags;
+    const fetcher_info_t *info;
 
+    for (info = fetcher_info; info->format != PIXMAN_null; ++info)
+    {
+	if ((info->format == format || info->format == PIXMAN_any)	&&
+	    (info->flags & flags) == info->flags)
+	{
+	    if (iter->iter_flags & ITER_NARROW)
+	    {
+		iter->get_scanline = info->get_scanline_32;
+	    }
+	    else
+	    {
+		iter->data = info->get_scanline_32;
+		iter->get_scanline = info->get_scanline_64;
+	    }
+	    return;
+	}
+    }
+
+    /* Just in case we somehow didn't find a scanline function */
+    iter->get_scanline = _pixman_iter_get_scanline_noop;
 }
 
 static uint32_t *
 dest_get_scanline_16 (pixman_iter_t *iter, const uint32_t *mask)
 {
     pixman_image_t *image  = iter->image;
     int             x      = iter->x;
     int             y      = iter->y;
@@ -1404,32 +1415,32 @@ dest_write_back_wide (pixman_iter_t *ite
     }
 
     iter->y++;
 }
 
 void
 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
 {
-    if (iter->flags & ITER_16)
+    if (iter->iter_flags & ITER_16)
     {
-        if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
+        if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
 	    (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
 	{
             iter->get_scanline = _pixman_iter_get_scanline_noop;
         }
         else
         {
 	    iter->get_scanline = dest_get_scanline_16;
         }
 	iter->write_back = dest_write_back_16;
     }
-    else if (iter->flags & ITER_NARROW)
+    else if (iter->iter_flags & ITER_NARROW)
     {
-	if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
+	if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
 	    (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
 	{
 	    iter->get_scanline = _pixman_iter_get_scanline_noop;
 	}
 	else
 	{
 	    iter->get_scanline = dest_get_scanline_narrow;
 	}
--- a/gfx/cairo/libpixman/src/pixman-combine32.c
+++ b/gfx/cairo/libpixman/src/pixman-combine32.c
@@ -436,17 +436,17 @@ combine_saturate_u (pixman_implementatio
  * it has been designed to mirror ISO 32000. Note that at the current point
  * no released draft exists that shows this, as the formulas have not been
  * updated yet after the release of ISO 32000.
  *
  * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
  * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
  * argument. Note that this implementation operates on premultiplied colors,
  * while the PDF specification does not. Therefore the code uses the formula
- * ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
+ * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
  */
 
 /*
  * Multiply
  * B(Dca, ad, Sca, as) = Dca.Sca
  */
 
 static void
@@ -521,17 +521,17 @@ combine_multiply_ca (pixman_implementati
 	    uint8_t da = ALPHA_8 (d);					\
 	    uint8_t ida = ~da;						\
 	    uint32_t result;						\
 									\
 	    result = d;							\
 	    UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida);	\
 	    								\
 	    *(dest + i) = result +					\
-		(DIV_ONE_UN8 (sa * da) << A_SHIFT) +			\
+		(DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) +		\
 		(blend_ ## name (RED_8 (d), da, RED_8 (s), sa) << R_SHIFT) + \
 		(blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa) << G_SHIFT) + \
 		(blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa));	\
 	}								\
     }									\
     									\
     static void								\
     combine_ ## name ## _ca (pixman_implementation_t *imp,		\
@@ -551,17 +551,17 @@ combine_multiply_ca (pixman_implementati
 	    uint32_t result;						\
             								\
 	    combine_mask_value_ca (&s, &m);				\
             								\
 	    result = d;							\
 	    UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida);     \
             								\
 	    result +=							\
-	        (DIV_ONE_UN8 (ALPHA_8 (m) * da) << A_SHIFT) +		\
+	        (DIV_ONE_UN8 (ALPHA_8 (m) * (uint32_t)da) << A_SHIFT) +	\
 	        (blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)) << R_SHIFT) + \
 	        (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)) << G_SHIFT) + \
 	        (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m))); \
 	    								\
 	    *(dest + i) = result;					\
 	}								\
     }
 
@@ -848,17 +848,17 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
  *   = clip_color ( r * C + r × l - r * LUM (C), r * a)
  *
  *   = set_lum ( r * C, r * l, r * a)
  *
  * Finally, set_sat:
  *
  *    r * set_sat (C, s) = set_sat (x * C, r * s)
  *
- * The above holds for all non-zero x, because they x'es in the fraction for
+ * The above holds for all non-zero x, because the x'es in the fraction for
  * C_mid cancel out. Specifically, it holds for x = r:
  *
  *    r * set_sat (C, s) = set_sat (r_c, rs)
  *
  */
 
 /* So, for the non-separable PDF blend modes, we have (using s, d for
  * non-premultiplied colors, and S, D for premultiplied:
@@ -884,18 +884,17 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
  *   = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)),
  *                                        a_s * LUM (D), a_s * a_d)
  *   = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d))
  *
  *   Hue:
  *
  *     a_s * a_d * B(s, d)
  *   = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
- *   = a_s * a_d * set_lum (set_sat (a_d * S, a_s * SAT (D)),
- *                                        a_s * LUM (D), a_s * a_d)
+ *   = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
  *
  */
 
 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
 #define SAT(c) (CH_MAX (c) - CH_MIN (c))
 
@@ -926,17 +925,17 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
 	    sc[0] = RED_8 (s);						\
 	    dc[1] = GREEN_8 (d);					\
 	    sc[1] = GREEN_8 (s);					\
 	    dc[2] = BLUE_8 (d);						\
 	    sc[2] = BLUE_8 (s);						\
 	    blend_ ## name (c, dc, da, sc, sa);				\
             								\
 	    *(dest + i) = result +					\
-		(DIV_ONE_UN8 (sa * da) << A_SHIFT) +			\
+		(DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) +		\
 		(DIV_ONE_UN8 (c[0]) << R_SHIFT) +			\
 		(DIV_ONE_UN8 (c[1]) << G_SHIFT) +			\
 		(DIV_ONE_UN8 (c[2]));					\
 	}								\
     }
 
 static void
 set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum)
@@ -1143,19 +1142,17 @@ blend_hsl_luminosity (uint32_t c[3],
 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
 
 #undef SAT
 #undef LUM
 #undef CH_MAX
 #undef CH_MIN
 #undef PDF_NON_SEPARABLE_BLEND_MODE
 
-/* Overlay
- *
- * All of the disjoint composing functions
+/* All of the disjoint/conjoint composing functions
  *
  * The four entries in the first column indicate what source contributions
  * come from each of the four areas of the picture -- areas covered by neither
  * A nor B, areas covered only by A, areas covered only by B and finally
  * areas covered by both A and B.
  * 
  * Disjoint			Conjoint
  * Fa		Fb		Fa		Fb
@@ -1166,16 +1163,19 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_lumino
  * (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
  * (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
  * (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
  * (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
  * (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
  * (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
  * (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
  * (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
+ *
+ * See  http://marc.info/?l=xfree-render&m=99792000027857&w=2  for more
+ * information about these operators.
  */
 
 #define COMBINE_A_OUT 1
 #define COMBINE_A_IN  2
 #define COMBINE_B_OUT 4
 #define COMBINE_B_IN  8
 
 #define COMBINE_CLEAR   0
--- a/gfx/cairo/libpixman/src/pixman-combine32.h
+++ b/gfx/cairo/libpixman/src/pixman-combine32.h
@@ -24,20 +24,20 @@
 #define GREEN_8(x) (((x) >> G_SHIFT) & MASK)
 #define BLUE_8(x) ((x) & MASK)
 
 /*
  * Helper macros.
  */
 
 #define MUL_UN8(a, b, t)						\
-    ((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
+    ((t) = (a) * (uint16_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
 
 #define DIV_UN8(a, b)							\
-    (((uint16_t) (a) * MASK) / (b))
+    (((uint16_t) (a) * MASK + ((b) / 2)) / (b))
 
 #define ADD_UN8(x, y, t)				     \
     ((t) = (x) + (y),					     \
      (uint32_t) (uint8_t) ((t) | (0 - ((t) >> G_SHIFT))))
 
 #define DIV_ONE_UN8(x)							\
     (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
 
--- a/gfx/cairo/libpixman/src/pixman-combine64.c
+++ b/gfx/cairo/libpixman/src/pixman-combine64.c
@@ -436,17 +436,17 @@ combine_saturate_u (pixman_implementatio
  * it has been designed to mirror ISO 32000. Note that at the current point
  * no released draft exists that shows this, as the formulas have not been
  * updated yet after the release of ISO 32000.
  *
  * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
  * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
  * argument. Note that this implementation operates on premultiplied colors,
  * while the PDF specification does not. Therefore the code uses the formula
- * ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
+ * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
  */
 
 /*
  * Multiply
  * B(Dca, ad, Sca, as) = Dca.Sca
  */
 
 static void
@@ -521,17 +521,17 @@ combine_multiply_ca (pixman_implementati
 	    uint16_t da = ALPHA_16 (d);					\
 	    uint16_t ida = ~da;						\
 	    uint64_t result;						\
 									\
 	    result = d;							\
 	    UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16 (result, isa, s, ida);	\
 	    								\
 	    *(dest + i) = result +					\
-		(DIV_ONE_UN16 (sa * da) << A_SHIFT) +			\
+		(DIV_ONE_UN16 (sa * (uint64_t)da) << A_SHIFT) +		\
 		(blend_ ## name (RED_16 (d), da, RED_16 (s), sa) << R_SHIFT) + \
 		(blend_ ## name (GREEN_16 (d), da, GREEN_16 (s), sa) << G_SHIFT) + \
 		(blend_ ## name (BLUE_16 (d), da, BLUE_16 (s), sa));	\
 	}								\
     }									\
     									\
     static void								\
     combine_ ## name ## _ca (pixman_implementation_t *imp,		\
@@ -551,17 +551,17 @@ combine_multiply_ca (pixman_implementati
 	    uint64_t result;						\
             								\
 	    combine_mask_value_ca (&s, &m);				\
             								\
 	    result = d;							\
 	    UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16 (result, ~m, s, ida);     \
             								\
 	    result +=							\
-	        (DIV_ONE_UN16 (ALPHA_16 (m) * da) << A_SHIFT) +		\
+	        (DIV_ONE_UN16 (ALPHA_16 (m) * (uint64_t)da) << A_SHIFT) +	\
 	        (blend_ ## name (RED_16 (d), da, RED_16 (s), RED_16 (m)) << R_SHIFT) + \
 	        (blend_ ## name (GREEN_16 (d), da, GREEN_16 (s), GREEN_16 (m)) << G_SHIFT) + \
 	        (blend_ ## name (BLUE_16 (d), da, BLUE_16 (s), BLUE_16 (m))); \
 	    								\
 	    *(dest + i) = result;					\
 	}								\
     }
 
@@ -848,17 +848,17 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
  *   = clip_color ( r * C + r × l - r * LUM (C), r * a)
  *
  *   = set_lum ( r * C, r * l, r * a)
  *
  * Finally, set_sat:
  *
  *    r * set_sat (C, s) = set_sat (x * C, r * s)
  *
- * The above holds for all non-zero x, because they x'es in the fraction for
+ * The above holds for all non-zero x, because the x'es in the fraction for
  * C_mid cancel out. Specifically, it holds for x = r:
  *
  *    r * set_sat (C, s) = set_sat (r_c, rs)
  *
  */
 
 /* So, for the non-separable PDF blend modes, we have (using s, d for
  * non-premultiplied colors, and S, D for premultiplied:
@@ -884,18 +884,17 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
  *   = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)),
  *                                        a_s * LUM (D), a_s * a_d)
  *   = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d))
  *
  *   Hue:
  *
  *     a_s * a_d * B(s, d)
  *   = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
- *   = a_s * a_d * set_lum (set_sat (a_d * S, a_s * SAT (D)),
- *                                        a_s * LUM (D), a_s * a_d)
+ *   = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
  *
  */
 
 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
 #define SAT(c) (CH_MAX (c) - CH_MIN (c))
 
@@ -926,17 +925,17 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
 	    sc[0] = RED_16 (s);						\
 	    dc[1] = GREEN_16 (d);					\
 	    sc[1] = GREEN_16 (s);					\
 	    dc[2] = BLUE_16 (d);						\
 	    sc[2] = BLUE_16 (s);						\
 	    blend_ ## name (c, dc, da, sc, sa);				\
             								\
 	    *(dest + i) = result +					\
-		(DIV_ONE_UN16 (sa * da) << A_SHIFT) +			\
+		(DIV_ONE_UN16 (sa * (uint64_t)da) << A_SHIFT) +		\
 		(DIV_ONE_UN16 (c[0]) << R_SHIFT) +			\
 		(DIV_ONE_UN16 (c[1]) << G_SHIFT) +			\
 		(DIV_ONE_UN16 (c[2]));					\
 	}								\
     }
 
 static void
 set_lum (uint64_t dest[3], uint64_t src[3], uint64_t sa, uint64_t lum)
@@ -1143,19 +1142,17 @@ blend_hsl_luminosity (uint64_t c[3],
 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
 
 #undef SAT
 #undef LUM
 #undef CH_MAX
 #undef CH_MIN
 #undef PDF_NON_SEPARABLE_BLEND_MODE
 
-/* Overlay
- *
- * All of the disjoint composing functions
+/* All of the disjoint/conjoint composing functions
  *
  * The four entries in the first column indicate what source contributions
  * come from each of the four areas of the picture -- areas covered by neither
  * A nor B, areas covered only by A, areas covered only by B and finally
  * areas covered by both A and B.
  * 
  * Disjoint			Conjoint
  * Fa		Fb		Fa		Fb
@@ -1166,16 +1163,19 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_lumino
  * (0,A,B,B)	min((1-b)/a,1)	1		max(1-b/a,0)	1
  * (0,0,0,A)	max(1-(1-b)/a,0) 0		min(1,b/a)	0
  * (0,0,0,B)	0		max(1-(1-a)/b,0) 0		min(a/b,1)
  * (0,A,0,0)	min(1,(1-b)/a)	0		max(1-b/a,0)	0
  * (0,0,B,0)	0		min(1,(1-a)/b)	0		max(1-a/b,0)
  * (0,0,B,A)	max(1-(1-b)/a,0) min(1,(1-a)/b)	 min(1,b/a)	max(1-a/b,0)
  * (0,A,0,B)	min(1,(1-b)/a)	max(1-(1-a)/b,0) max(1-b/a,0)	min(1,a/b)
  * (0,A,B,0)	min(1,(1-b)/a)	min(1,(1-a)/b)	max(1-b/a,0)	max(1-a/b,0)
+ *
+ * See  http://marc.info/?l=xfree-render&m=99792000027857&w=2  for more
+ * information about these operators.
  */
 
 #define COMBINE_A_OUT 1
 #define COMBINE_A_IN  2
 #define COMBINE_B_OUT 4
 #define COMBINE_B_IN  8
 
 #define COMBINE_CLEAR   0
--- a/gfx/cairo/libpixman/src/pixman-combine64.h
+++ b/gfx/cairo/libpixman/src/pixman-combine64.h
@@ -24,20 +24,20 @@
 #define GREEN_16(x) (((x) >> G_SHIFT) & MASK)
 #define BLUE_16(x) ((x) & MASK)
 
 /*
  * Helper macros.
  */
 
 #define MUL_UN16(a, b, t)						\
-    ((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
+    ((t) = (a) * (uint32_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
 
 #define DIV_UN16(a, b)							\
-    (((uint32_t) (a) * MASK) / (b))
+    (((uint32_t) (a) * MASK + ((b) / 2)) / (b))
 
 #define ADD_UN16(x, y, t)				     \
     ((t) = (x) + (y),					     \
      (uint64_t) (uint16_t) ((t) | (0 - ((t) >> G_SHIFT))))
 
 #define DIV_ONE_UN16(x)							\
     (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
 
--- a/gfx/cairo/libpixman/src/pixman-compiler.h
+++ b/gfx/cairo/libpixman/src/pixman-compiler.h
@@ -91,16 +91,20 @@
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
 #   define PIXMAN_EXPORT __global
 #else
 #   define PIXMAN_EXPORT
 #endif
 
 #endif
 
+/* member offsets */
+#define CONTAINER_OF(type, member, data)				\
+    ((type *)(((uint8_t *)data) - offsetof (type, member)))
+
 /* TLS */
 #if defined(PIXMAN_NO_TLS)
 
 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)			\
     static type name
 #   define PIXMAN_GET_THREAD_LOCAL(name)				\
     (&name)
 
--- a/gfx/cairo/libpixman/src/pixman-conical-gradient.c
+++ b/gfx/cairo/libpixman/src/pixman-conical-gradient.c
@@ -168,17 +168,17 @@ conical_get_scanline_wide (pixman_iter_t
     pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
 
     return buffer;
 }
 
 void
 _pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
 {
-    if (iter->flags & ITER_NARROW)
+    if (iter->iter_flags & ITER_NARROW)
 	iter->get_scanline = conical_get_scanline_narrow;
     else
 	iter->get_scanline = conical_get_scanline_wide;
 }
 
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_conical_gradient (pixman_point_fixed_t *        center,
                                       pixman_fixed_t                angle,
--- a/gfx/cairo/libpixman/src/pixman-fast-path.c
+++ b/gfx/cairo/libpixman/src/pixman-fast-path.c
@@ -805,16 +805,58 @@ fast_composite_add_8_8 (pixman_implement
 		*dst = s;
 	    }
 	    dst++;
 	}
     }
 }
 
 static void
+fast_composite_add_0565_0565 (pixman_implementation_t *imp,
+                              pixman_composite_info_t *info)
+{
+    PIXMAN_COMPOSITE_ARGS (info);
+    uint16_t    *dst_line, *dst;
+    uint32_t	d;
+    uint16_t    *src_line, *src;
+    uint32_t	s;
+    int dst_stride, src_stride;
+    int32_t w;
+
+    PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint16_t, src_stride, src_line, 1);
+    PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1);
+
+    while (height--)
+    {
+	dst = dst_line;
+	dst_line += dst_stride;
+	src = src_line;
+	src_line += src_stride;
+	w = width;
+
+	while (w--)
+	{
+	    s = *src++;
+	    if (s)
+	    {
+		d = *dst;
+		s = CONVERT_0565_TO_8888 (s);
+		if (d)
+		{
+		    d = CONVERT_0565_TO_8888 (d);
+		    UN8x4_ADD_UN8x4 (s, d);
+		}
+		*dst = CONVERT_8888_TO_0565 (s);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
 fast_composite_add_8888_8888 (pixman_implementation_t *imp,
                               pixman_composite_info_t *info)
 {
     PIXMAN_COMPOSITE_ARGS (info);
     uint32_t    *dst_line, *dst;
     uint32_t    *src_line, *src;
     int dst_stride, src_stride;
     int32_t w;
@@ -1210,18 +1252,18 @@ scaled_bilinear_scanline_8888_565_OVER (
 	uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
 	uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
 	uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
 	uint32_t src, result;
 	uint16_t d;
 	d = *dst;
 	src = bilinear_interpolation (tl, tr,
 				      bl, br,
-				      interpolation_coord(vx),
-				      wb >> (8 - INTERPOLATION_PRECISION_BITS));
+				      pixman_fixed_to_bilinear_weight(vx),
+				      wb);
 	vx += unit_x;
 	result = over (src, CONVERT_0565_TO_0888 (d));
 	*dst++ = CONVERT_8888_TO_0565(result);
     }
 }
 
 static force_inline void
 scaled_bilinear_scanline_8888_8888_OVER (uint32_t *       dst,
@@ -1243,18 +1285,18 @@ scaled_bilinear_scanline_8888_8888_OVER 
 	uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
 	uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
 	uint32_t src;
 	uint32_t d;
 	uint32_t result;
 	d = *dst;
 	src = bilinear_interpolation (tl, tr,
 				      bl, br,
-				      interpolation_coord(vx),
-				      wb >> (8 - INTERPOLATION_PRECISION_BITS));
+				      pixman_fixed_to_bilinear_weight(vx),
+				      wb);
 	vx += unit_x;
 	*dst++ = over (src, d);
     }
 }
 
 #ifndef LOWER_QUALITY_INTERPOLATION
 
 static force_inline void
@@ -1276,18 +1318,18 @@ scaled_bilinear_scanline_565_565_SRC (ui
 	uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
 	uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
 	uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
 	uint32_t d;
 	d = bilinear_interpolation(CONVERT_0565_TO_8888(tl),
 				   CONVERT_0565_TO_8888(tr),
 				   CONVERT_0565_TO_8888(bl),
 				   CONVERT_0565_TO_8888(br),
-				   interpolation_coord(vx),
-				   wb >> (8 - INTERPOLATION_PRECISION_BITS));
+				   pixman_fixed_to_bilinear_weight(vx),
+				   wb);
 	vx += unit_x;
 	*dst++ = CONVERT_8888_TO_0565(d);
     }
 }
 
 #else
 
 /* This is a clever low resolution bilinear interpolation inspired by the code
@@ -1347,17 +1389,19 @@ scaled_bilinear_scanline_565_565_SRC (ui
 {
     while ((w -= 1) >= 0)
     {
 	uint16_t tl = src_top [pixman_fixed_to_int (vx)];
 	uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
 	uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
 	uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
 
-        uint16_t d = bilinear_interpolation_565 (tl, tr, bl, br, (vx >> 12) & 0xf, wb >> 4);
+        uint16_t d = bilinear_interpolation_565 (tl, tr, bl, br,
+						 pixman_fixed_to_bilinear_weight(vx),
+						 wb);
         vx += unit_x;
         *dst++ = d;
     }
 }
 
 #endif
 
 FAST_BILINEAR_MAINLOOP_COMMON (565_565_cover_SRC,
@@ -1453,18 +1497,19 @@ fast_composite_tiled_repeat (pixman_impl
 	pixman_bool_t need_src_extension;
 	uint32_t *src_line;
 	int32_t src_stride;
 	int32_t src_bpp;
 	pixman_composite_info_t info2 = *info;
 
 	src_bpp = PIXMAN_FORMAT_BPP (src_image->bits.format);
 
-	if (src_image->bits.width < REPEAT_MIN_WIDTH &&
-	    (src_bpp == 32 || src_bpp == 16 || src_bpp == 8))
+	if (src_image->bits.width < REPEAT_MIN_WIDTH		&&
+	    (src_bpp == 32 || src_bpp == 16 || src_bpp == 8)	&&
+	    !src_image->bits.indexed)
 	{
 	    sx = src_x;
 	    sx = MOD (sx, src_image->bits.width);
 	    sx += width;
 	    src_width = 0;
 
 	    while (src_width < REPEAT_MIN_WIDTH && src_width <= sx)
 		src_width += src_image->bits.width;
@@ -2051,16 +2096,18 @@ static const pixman_fast_path_t c_fast_p
     PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888),
     PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888),
     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888),
     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888),
     PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565),
     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888),
     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888),
     PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565),
+    PIXMAN_STD_FAST_PATH (ADD, r5g6b5, null, r5g6b5, fast_composite_add_0565_0565),
+    PIXMAN_STD_FAST_PATH (ADD, b5g6r5, null, b5g6r5, fast_composite_add_0565_0565),
     PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888),
     PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888),
     PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8_8),
     PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1_1),
     PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca),
     PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8),
     PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill),
     PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill),
--- a/gfx/cairo/libpixman/src/pixman-general.c
+++ b/gfx/cairo/libpixman/src/pixman-general.c
@@ -105,17 +105,17 @@ general_composite_rect  (pixman_implemen
 {
     PIXMAN_COMPOSITE_ARGS (info);
     uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
     uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
     pixman_iter_t src_iter, mask_iter, dest_iter;
     pixman_combine_32_func_t compose;
     pixman_bool_t component_alpha;
-    iter_flags_t narrow, src_flags;
+    iter_flags_t narrow, src_iter_flags;
     iter_flags_t rgb16;
     int Bpp;
     int i;
 
     if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT)		    &&
 	(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
 	(dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
     {
@@ -150,46 +150,46 @@ general_composite_rect  (pixman_implemen
 	    return;
     }
 
     src_buffer = scanline_buffer;
     mask_buffer = src_buffer + width * Bpp;
     dest_buffer = mask_buffer + width * Bpp;
 
     /* src iter */
-    src_flags = narrow | op_flags[op].src | rgb16;
+    src_iter_flags = narrow | op_flags[op].src | rgb16;
 
     _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
 					  src_x, src_y, width, height,
-					  src_buffer, src_flags);
+					  src_buffer, src_iter_flags, info->src_flags);
 
     /* mask iter */
-    if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
+    if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
 	(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
     {
 	/* If it doesn't matter what the source is, then it doesn't matter
 	 * what the mask is
 	 */
 	mask_image = NULL;
     }
 
     component_alpha =
         mask_image			      &&
         mask_image->common.type == BITS       &&
         mask_image->common.component_alpha    &&
         PIXMAN_FORMAT_RGB (mask_image->bits.format);
 
     _pixman_implementation_src_iter_init (
 	imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height,
-	mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB));
+	mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB), info->mask_flags);
 
     /* dest iter */
     _pixman_implementation_dest_iter_init (
 	imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
-	dest_buffer, narrow | op_flags[op].dst | rgb16);
+	dest_buffer, narrow | op_flags[op].dst | rgb16, info->dest_flags);
 
     compose = _pixman_implementation_lookup_combiner (
 	imp->toplevel, op, component_alpha, narrow, !!rgb16);
 
     if (!compose)
 	return;
 
     for (i = 0; i < height; ++i)
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/libpixman/src/pixman-glyph.c
@@ -0,0 +1,676 @@
+/*
+ * Copyright 2010, 2012, Soren Sandmann <sandmann@cs.au.dk>
+ * Copyright 2010, 2011, 2012, Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann@cs.au.dk>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "pixman-private.h"
+
+#include <stdlib.h>
+
+typedef struct glyph_metrics_t glyph_metrics_t;
+typedef struct glyph_t glyph_t;
+
+#define TOMBSTONE ((glyph_t *)0x1)
+
+/* XXX: These numbers are arbitrary---we've never done any measurements.
+ */
+#define N_GLYPHS_HIGH_WATER  (16384)
+#define N_GLYPHS_LOW_WATER   (8192)
+#define HASH_SIZE (2 * N_GLYPHS_HIGH_WATER)
+#define HASH_MASK (HASH_SIZE - 1)
+
+struct glyph_t
+{
+    void *		font_key;
+    void *		glyph_key;
+    int			origin_x;
+    int			origin_y;
+    pixman_image_t *	image;
+    pixman_link_t	mru_link;
+};
+
+struct pixman_glyph_cache_t
+{
+    int			n_glyphs;
+    int			n_tombstones;
+    int			freeze_count;
+    pixman_list_t	mru;
+    glyph_t *		glyphs[HASH_SIZE];
+};
+
+static void
+free_glyph (glyph_t *glyph)
+{
+    pixman_list_unlink (&glyph->mru_link);
+    pixman_image_unref (glyph->image);
+    free (glyph);
+}
+
+static unsigned int
+hash (const void *font_key, const void *glyph_key)
+{
+    size_t key = (size_t)font_key + (size_t)glyph_key;
+
+    /* This hash function is based on one found on Thomas Wang's
+     * web page at
+     *
+     *    http://www.concentric.net/~Ttwang/tech/inthash.htm
+     *
+     */
+    key = (key << 15) - key - 1;
+    key = key ^ (key >> 12);
+    key = key + (key << 2);
+    key = key ^ (key >> 4);
+    key = key + (key << 3) + (key << 11);
+    key = key ^ (key >> 16);
+
+    return key;
+}
+
+static glyph_t *
+lookup_glyph (pixman_glyph_cache_t *cache,
+	      void                 *font_key,
+	      void                 *glyph_key)
+{
+    unsigned idx;
+    glyph_t *g;
+
+    idx = hash (font_key, glyph_key);
+    while ((g = cache->glyphs[idx++ & HASH_MASK]))
+    {
+	if (g != TOMBSTONE			&&
+	    g->font_key == font_key		&&
+	    g->glyph_key == glyph_key)
+	{
+	    return g;
+	}
+    }
+
+    return NULL;
+}
+
+static void
+insert_glyph (pixman_glyph_cache_t *cache,
+	      glyph_t              *glyph)
+{
+    unsigned idx;
+    glyph_t **loc;
+
+    idx = hash (glyph->font_key, glyph->glyph_key);
+
+    /* Note: we assume that there is room in the table. If there isn't,
+     * this will be an infinite loop.
+     */
+    do
+    {
+	loc = &cache->glyphs[idx++ & HASH_MASK];
+    } while (*loc && *loc != TOMBSTONE);
+
+    if (*loc == TOMBSTONE)
+	cache->n_tombstones--;
+    cache->n_glyphs++;
+
+    *loc = glyph;
+}
+
+static void
+remove_glyph (pixman_glyph_cache_t *cache,
+	      glyph_t              *glyph)
+{
+    unsigned idx;
+
+    idx = hash (glyph->font_key, glyph->glyph_key);
+    while (cache->glyphs[idx & HASH_MASK] != glyph)
+	idx++;
+
+    cache->glyphs[idx & HASH_MASK] = TOMBSTONE;
+    cache->n_tombstones++;
+    cache->n_glyphs--;
+
+    /* Eliminate tombstones if possible */
+    if (cache->glyphs[(idx + 1) & HASH_MASK] == NULL)
+    {
+	while (cache->glyphs[idx & HASH_MASK] == TOMBSTONE)
+	{
+	    cache->glyphs[idx & HASH_MASK] = NULL;
+	    cache->n_tombstones--;
+	    idx--;
+	}
+    }
+}
+
+static void
+clear_table (pixman_glyph_cache_t *cache)
+{
+    int i;
+
+    for (i = 0; i < HASH_SIZE; ++i)
+    {
+	glyph_t *glyph = cache->glyphs[i];
+
+	if (glyph && glyph != TOMBSTONE)
+	    free_glyph (glyph);
+
+	cache->glyphs[i] = NULL;
+    }
+
+    cache->n_glyphs = 0;
+    cache->n_tombstones = 0;
+}
+
+PIXMAN_EXPORT pixman_glyph_cache_t *
+pixman_glyph_cache_create (void)
+{
+    pixman_glyph_cache_t *cache;
+
+    if (!(cache = malloc (sizeof *cache)))
+	return NULL;
+
+    memset (cache->glyphs, 0, sizeof (cache->glyphs));
+    cache->n_glyphs = 0;
+    cache->n_tombstones = 0;
+    cache->freeze_count = 0;
+
+    pixman_list_init (&cache->mru);
+
+    return cache;
+}
+
+PIXMAN_EXPORT void
+pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache)
+{
+    return_if_fail (cache->freeze_count == 0);
+
+    clear_table (cache);
+
+    free (cache);
+}
+
+PIXMAN_EXPORT void
+pixman_glyph_cache_freeze (pixman_glyph_cache_t  *cache)
+{
+    cache->freeze_count++;
+}
+
+PIXMAN_EXPORT void
+pixman_glyph_cache_thaw (pixman_glyph_cache_t  *cache)
+{
+    if (--cache->freeze_count == 0					&&
+	cache->n_glyphs + cache->n_tombstones > N_GLYPHS_HIGH_WATER)
+    {
+	if (cache->n_tombstones > N_GLYPHS_HIGH_WATER)
+	{
+	    /* More than half the entries are
+	     * tombstones. Just dump the whole table.
+	     */
+	    clear_table (cache);
+	}
+
+	while (cache->n_glyphs > N_GLYPHS_LOW_WATER)
+	{
+	    glyph_t *glyph = CONTAINER_OF (glyph_t, mru_link, cache->mru.tail);
+
+	    remove_glyph (cache, glyph);
+	    free_glyph (glyph);
+	}
+    }
+}
+
+PIXMAN_EXPORT const void *
+pixman_glyph_cache_lookup (pixman_glyph_cache_t  *cache,
+			   void                  *font_key,
+			   void                  *glyph_key)
+{
+    return lookup_glyph (cache, font_key, glyph_key);
+}
+
+PIXMAN_EXPORT const void *
+pixman_glyph_cache_insert (pixman_glyph_cache_t  *cache,
+			   void                  *font_key,
+			   void                  *glyph_key,
+			   int			  origin_x,
+			   int                    origin_y,
+			   pixman_image_t        *image)
+{
+    glyph_t *glyph;
+    int32_t width, height;
+
+    return_val_if_fail (cache->freeze_count > 0, NULL);
+    return_val_if_fail (image->type == BITS, NULL);
+
+    width = image->bits.width;
+    height = image->bits.height;
+
+    if (cache->n_glyphs >= HASH_SIZE)
+	return NULL;
+
+    if (!(glyph = malloc (sizeof *glyph)))
+	return NULL;
+
+    glyph->font_key = font_key;
+    glyph->glyph_key = glyph_key;
+    glyph->origin_x = origin_x;
+    glyph->origin_y = origin_y;
+
+    if (!(glyph->image = pixman_image_create_bits (
+	      image->bits.format, width, height, NULL, -1)))
+    {
+	free (glyph);
+	return NULL;
+    }
+
+    pixman_image_composite32 (PIXMAN_OP_SRC,
+			      image, NULL, glyph->image, 0, 0, 0, 0, 0, 0,
+			      width, height);
+
+    if (PIXMAN_FORMAT_A   (glyph->image->bits.format) != 0	&&
+	PIXMAN_FORMAT_RGB (glyph->image->bits.format) != 0)
+    {
+	pixman_image_set_component_alpha (glyph->image, TRUE);
+    }
+
+    pixman_list_prepend (&cache->mru, &glyph->mru_link);
+
+    _pixman_image_validate (glyph->image);
+    insert_glyph (cache, glyph);
+
+    return glyph;
+}
+
+PIXMAN_EXPORT void
+pixman_glyph_cache_remove (pixman_glyph_cache_t  *cache,
+			   void                  *font_key,
+			   void                  *glyph_key)
+{
+    glyph_t *glyph;
+
+    if ((glyph = lookup_glyph (cache, font_key, glyph_key)))
+    {
+	remove_glyph (cache, glyph);
+
+	free_glyph (glyph);
+    }
+}
+
+PIXMAN_EXPORT void
+pixman_glyph_get_extents (pixman_glyph_cache_t *cache,
+			  int                   n_glyphs,
+			  pixman_glyph_t       *glyphs,
+			  pixman_box32_t       *extents)
+{
+    int i;
+
+    extents->x1 = extents->y1 = INT32_MAX;
+    extents->x2 = extents->y2 = INT32_MIN;
+
+    for (i = 0; i < n_glyphs; ++i)
+    {
+	glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
+	int x1, y1, x2, y2;
+
+	x1 = glyphs[i].x - glyph->origin_x;
+	y1 = glyphs[i].y - glyph->origin_y;
+	x2 = glyphs[i].x - glyph->origin_x + glyph->image->bits.width;
+	y2 = glyphs[i].y - glyph->origin_y + glyph->image->bits.height;
+
+	if (x1 < extents->x1)
+	    extents->x1 = x1;
+	if (y1 < extents->y1)
+	    extents->y1 = y1;
+	if (x2 > extents->x2)
+	    extents->x2 = x2;
+	if (y2 > extents->y2)
+	    extents->y2 = y2;
+    }
+}
+
+/* This function returns a format that is suitable for use as a mask for the
+ * set of glyphs in question.
+ */
+PIXMAN_EXPORT pixman_format_code_t
+pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache,
+			      int		    n_glyphs,
+			      pixman_glyph_t *      glyphs)
+{
+    pixman_format_code_t format = PIXMAN_a1;
+    int i;
+
+    for (i = 0; i < n_glyphs; ++i)
+    {
+	const glyph_t *glyph = glyphs[i].glyph;
+	pixman_format_code_t glyph_format = glyph->image->bits.format;
+
+	if (PIXMAN_FORMAT_TYPE (glyph_format) == PIXMAN_TYPE_A)
+	{
+	    if (PIXMAN_FORMAT_A (glyph_format) > PIXMAN_FORMAT_A (format))
+		format = glyph_format;
+	}
+	else
+	{
+	    return PIXMAN_a8r8g8b8;
+	}
+    }
+
+    return format;
+}
+
+static pixman_bool_t
+box32_intersect (pixman_box32_t *dest,
+		 const pixman_box32_t *box1,
+		 const pixman_box32_t *box2)
+{
+    dest->x1 = MAX (box1->x1, box2->x1);
+    dest->y1 = MAX (box1->y1, box2->y1);
+    dest->x2 = MIN (box1->x2, box2->x2);
+    dest->y2 = MIN (box1->y2, box2->y2);
+
+    return dest->x2 > dest->x1 && dest->y2 > dest->y1;
+}
+
+PIXMAN_EXPORT void
+pixman_composite_glyphs_no_mask (pixman_op_t            op,
+				 pixman_image_t        *src,
+				 pixman_image_t        *dest,
+				 int32_t                src_x,
+				 int32_t                src_y,
+				 int32_t                dest_x,
+				 int32_t                dest_y,
+				 pixman_glyph_cache_t  *cache,
+				 int                    n_glyphs,
+				 pixman_glyph_t        *glyphs)
+{
+    pixman_region32_t region;
+    pixman_format_code_t glyph_format = PIXMAN_null;
+    uint32_t glyph_flags = 0;
+    pixman_format_code_t dest_format;
+    uint32_t dest_flags;
+    pixman_composite_func_t func = NULL;
+    pixman_implementation_t *implementation = NULL;
+    pixman_composite_info_t info;
+    int i;
+
+    _pixman_image_validate (src);
+    _pixman_image_validate (dest);
+    
+    dest_format = dest->common.extended_format_code;
+    dest_flags = dest->common.flags;
+    
+    pixman_region32_init (&region);
+    if (!_pixman_compute_composite_region32 (
+	    &region,
+	    src, NULL, dest,
+	    src_x - dest_x, src_y - dest_y, 0, 0, 0, 0,
+	    dest->bits.width, dest->bits.height))
+    {
+	goto out;
+    }
+
+    info.op = op;
+    info.src_image = src;
+    info.dest_image = dest;
+    info.src_flags = src->common.flags;
+    info.dest_flags = dest->common.flags;
+
+    for (i = 0; i < n_glyphs; ++i)
+    {
+	glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
+	pixman_image_t *glyph_img = glyph->image;
+	pixman_box32_t glyph_box;
+	pixman_box32_t *pbox;
+	uint32_t extra = FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
+	pixman_box32_t composite_box;
+	int n;
+
+	glyph_box.x1 = dest_x + glyphs[i].x - glyph->origin_x;
+	glyph_box.y1 = dest_y + glyphs[i].y - glyph->origin_y;
+	glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width;
+	glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height;
+	
+	pbox = pixman_region32_rectangles (&region, &n);
+	
+	info.mask_image = glyph_img;
+
+	while (n--)
+	{
+	    if (box32_intersect (&composite_box, pbox, &glyph_box))
+	    {
+		if (glyph_img->common.extended_format_code != glyph_format	||
+		    glyph_img->common.flags != glyph_flags)
+		{
+		    glyph_format = glyph_img->common.extended_format_code;
+		    glyph_flags = glyph_img->common.flags;
+		    
+		    _pixman_lookup_composite_function (
+			get_implementation(), op,
+			src->common.extended_format_code, src->common.flags,
+			glyph_format, glyph_flags | extra,
+			dest_format, dest_flags,
+			&implementation, &func);
+
+		    if (!func)
+			goto out;
+		}
+
+		info.src_x = src_x + composite_box.x1 - dest_x;
+		info.src_y = src_y + composite_box.y1 - dest_y;
+		info.mask_x = composite_box.x1 - (dest_x + glyphs[i].x - glyph->origin_x);
+		info.mask_y = composite_box.y1 - (dest_y + glyphs[i].y - glyph->origin_y);
+		info.dest_x = composite_box.x1;
+		info.dest_y = composite_box.y1;
+		info.width = composite_box.x2 - composite_box.x1;
+		info.height = composite_box.y2 - composite_box.y1;
+
+		info.mask_flags = glyph_flags;
+
+		func (implementation, &info);
+	    }
+
+	    pbox++;
+	}
+	pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
+    }
+
+out:
+    pixman_region32_fini (&region);
+}
+
+static void
+add_glyphs (pixman_glyph_cache_t *cache,
+	    pixman_image_t *dest,
+	    int off_x, int off_y,
+	    int n_glyphs, pixman_glyph_t *glyphs)
+{
+    pixman_format_code_t glyph_format = PIXMAN_null;
+    uint32_t glyph_flags = 0;
+    pixman_composite_func_t func = NULL;
+    pixman_implementation_t *implementation = NULL;
+    uint32_t dest_format;
+    uint32_t dest_flags;
+    pixman_box32_t dest_box;
+    pixman_composite_info_t info;
+    pixman_image_t *white_img = NULL;
+    pixman_bool_t white_src = FALSE;
+    int i;
+
+    _pixman_image_validate (dest);
+
+    dest_format = dest->common.extended_format_code;
+    dest_flags = dest->common.flags;
+
+    info.op = PIXMAN_OP_ADD;
+    info.dest_image = dest;
+    info.src_x = 0;
+    info.src_y = 0;
+    info.dest_flags = dest_flags;
+
+    dest_box.x1 = 0;
+    dest_box.y1 = 0;
+    dest_box.x2 = dest->bits.width;
+    dest_box.y2 = dest->bits.height;
+
+    for (i = 0; i < n_glyphs; ++i)
+    {
+	glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
+	pixman_image_t *glyph_img = glyph->image;
+	pixman_box32_t glyph_box;
+	pixman_box32_t composite_box;
+
+	if (glyph_img->common.extended_format_code != glyph_format	||
+	    glyph_img->common.flags != glyph_flags)
+	{
+	    pixman_format_code_t src_format, mask_format;
+
+	    glyph_format = glyph_img->common.extended_format_code;
+	    glyph_flags = glyph_img->common.flags;
+
+	    if (glyph_format == dest->bits.format)
+	    {
+		src_format = glyph_format;
+		mask_format = PIXMAN_null;
+		info.src_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
+		info.mask_flags = FAST_PATH_IS_OPAQUE;
+		info.mask_image = NULL;
+		white_src = FALSE;
+	    }
+	    else
+	    {
+		if (!white_img)
+		{
+		    pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
+
+		    if (!(white_img = pixman_image_create_solid_fill (&white)))
+			goto out;
+
+		    _pixman_image_validate (white_img);
+		}
+
+		src_format = PIXMAN_solid;
+		mask_format = glyph_format;
+		info.src_flags = white_img->common.flags;
+		info.mask_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
+		info.src_image = white_img;
+		white_src = TRUE;
+	    }
+
+	    _pixman_lookup_composite_function (
+		get_implementation(), PIXMAN_OP_ADD,
+		src_format, info.src_flags,
+		mask_format, info.mask_flags,
+		dest_format, dest_flags,
+		&implementation, &func);
+
+	    if (!func)
+		goto out;
+	}
+
+	glyph_box.x1 = glyphs[i].x - glyph->origin_x + off_x;
+	glyph_box.y1 = glyphs[i].y - glyph->origin_y + off_y;
+	glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width;
+	glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height;
+	
+	if (box32_intersect (&composite_box, &glyph_box, &dest_box))
+	{
+	    int src_x = composite_box.x1 - glyph_box.x1;
+	    int src_y = composite_box.y1 - glyph_box.y1;
+
+	    if (white_src)
+		info.mask_image = glyph_img;
+	    else
+		info.src_image = glyph_img;
+
+	    info.mask_x = info.src_x = src_x;
+	    info.mask_y = info.src_y = src_y;
+	    info.dest_x = composite_box.x1;
+	    info.dest_y = composite_box.y1;
+	    info.width = composite_box.x2 - composite_box.x1;
+	    info.height = composite_box.y2 - composite_box.y1;
+
+	    func (implementation, &info);
+
+	    pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
+	}
+    }
+
+out:
+    if (white_img)
+	pixman_image_unref (white_img);
+}
+
+/* Conceptually, for each glyph, (white IN glyph) is PIXMAN_OP_ADDed to an
+ * infinitely big mask image at the position such that the glyph origin point
+ * is positioned at the (glyphs[i].x, glyphs[i].y) point.
+ *
+ * Then (mask_x, mask_y) in the infinite mask and (src_x, src_y) in the source
+ * image are both aligned with (dest_x, dest_y) in the destination image. Then
+ * these three images are composited within the 
+ *
+ *       (dest_x, dest_y, dst_x + width, dst_y + height)
+ *
+ * rectangle.
+ *
+ * TODO:
+ *   - Trim the mask to the destination clip/image?
+ *   - Trim composite region based on sources, when the op ignores 0s.
+ */
+PIXMAN_EXPORT void
+pixman_composite_glyphs (pixman_op_t            op,
+			 pixman_image_t        *src,
+			 pixman_image_t        *dest,
+			 pixman_format_code_t   mask_format,
+			 int32_t                src_x,
+			 int32_t                src_y,
+			 int32_t		mask_x,
+			 int32_t		mask_y,
+			 int32_t                dest_x,
+			 int32_t                dest_y,
+			 int32_t                width,
+			 int32_t                height,
+			 pixman_glyph_cache_t  *cache,
+			 int			n_glyphs,
+			 pixman_glyph_t        *glyphs)
+{
+    pixman_image_t *mask;
+
+    if (!(mask = pixman_image_create_bits (mask_format, width, height, NULL, -1)))
+	return;
+
+    if (PIXMAN_FORMAT_A   (mask_format) != 0 &&
+	PIXMAN_FORMAT_RGB (mask_format) != 0)
+    {
+	pixman_image_set_component_alpha (mask, TRUE);
+    }
+
+    add_glyphs (cache, mask, - mask_x, - mask_y, n_glyphs, glyphs);
+
+    pixman_image_composite32 (op, src, mask, dest,
+			      src_x, src_y,
+			      0, 0,
+			      dest_x, dest_y,
+			      width, height);
+
+    pixman_image_unref (mask);
+}
--- a/gfx/cairo/libpixman/src/pixman-image.c
+++ b/gfx/cairo/libpixman/src/pixman-image.c
@@ -878,26 +878,48 @@ pixman_image_get_format (pixman_image_t 
 }
 
 uint32_t
 _pixman_image_get_solid (pixman_implementation_t *imp,
 			 pixman_image_t *         image,
                          pixman_format_code_t     format)
 {
     uint32_t result;
-    pixman_iter_t iter;
 
-    _pixman_implementation_src_iter_init (
-	imp, &iter, image, 0, 0, 1, 1,
-	(uint8_t *)&result, ITER_NARROW);
+    if (image->type == SOLID)
+    {
+	result = image->solid.color_32;
+    }
+    else if (image->type == BITS)
+    {
+	if (image->bits.format == PIXMAN_a8r8g8b8)
+	    result = image->bits.bits[0];
+	else if (image->bits.format == PIXMAN_x8r8g8b8)
+	    result = image->bits.bits[0] | 0xff000000;
+	else if (image->bits.format == PIXMAN_a8)
+	    result = (*(uint8_t *)image->bits.bits) << 24;
+	else
+	    goto otherwise;
+    }
+    else
+    {
+	pixman_iter_t iter;
 
-    result = *iter.get_scanline (&iter, NULL);
+    otherwise:
+	_pixman_implementation_src_iter_init (
+	    imp, &iter, image, 0, 0, 1, 1,
+	    (uint8_t *)&result,
+	    ITER_NARROW, image->common.flags);
+	
+	result = *iter.get_scanline (&iter, NULL);
+    }
 
     /* If necessary, convert RGB <--> BGR. */
-    if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
+    if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB
+	&& PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB_SRGB)
     {
 	result = (((result & 0xff000000) >>  0) |
 	          ((result & 0x00ff0000) >> 16) |
 	          ((result & 0x0000ff00) >>  0) |
 	          ((result & 0x000000ff) << 16));
     }
 
     return result;
--- a/gfx/cairo/libpixman/src/pixman-implementation.c
+++ b/gfx/cairo/libpixman/src/pixman-implementation.c
@@ -186,42 +186,97 @@ void
 _pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
 				      pixman_iter_t             *iter,
 				      pixman_image_t		*image,
 				      int			 x,
 				      int			 y,
 				      int			 width,
 				      int			 height,
 				      uint8_t			*buffer,
-				      iter_flags_t		 flags)
+				      iter_flags_t		 iter_flags,
+				      uint32_t                   image_flags)
 {
     iter->image = image;
     iter->buffer = (uint32_t *)buffer;
     iter->x = x;
     iter->y = y;
     iter->width = width;
     iter->height = height;
-    iter->flags = flags;
+    iter->iter_flags = iter_flags;
+    iter->image_flags = image_flags;
 
     (*imp->src_iter_init) (imp, iter);
 }
 
 void
 _pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
 				       pixman_iter_t            *iter,
 				       pixman_image_t		*image,
 				       int			 x,
 				       int			 y,
 				       int			 width,
 				       int			 height,
 				       uint8_t			*buffer,
-				       iter_flags_t		 flags)
+				       iter_flags_t		 iter_flags,
+				       uint32_t                  image_flags)
 {
     iter->image = image;
     iter->buffer = (uint32_t *)buffer;
     iter->x = x;
     iter->y = y;
     iter->width = width;
     iter->height = height;
-    iter->flags = flags;
+    iter->iter_flags = iter_flags;
+    iter->image_flags = image_flags;
 
     (*imp->dest_iter_init) (imp, iter);
 }
+
+pixman_bool_t
+_pixman_disabled (const char *name)
+{
+    const char *env;
+
+    if ((env = getenv ("PIXMAN_DISABLE")))
+    {
+	do
+	{
+	    const char *end;
+	    int len;
+
+	    if ((end = strchr (env, ' ')))
+		len = end - env;
+	    else
+		len = strlen (env);
+
+	    if (strlen (name) == len && strncmp (name, env, len) == 0)
+	    {
+		printf ("pixman: Disabled %s implementation\n", name);
+		return TRUE;
+	    }
+
+	    env += len;
+	}
+	while (*env++);
+    }
+
+    return FALSE;
+}
+
+pixman_implementation_t *
+_pixman_choose_implementation (void)
+{
+    pixman_implementation_t *imp;
+
+    imp = _pixman_implementation_create_general();
+
+    if (!_pixman_disabled ("fast"))
+	imp = _pixman_implementation_create_fast_path (imp);
+
+    imp = _pixman_x86_get_implementations (imp);
+    imp = _pixman_arm_get_implementations (imp);
+    imp = _pixman_ppc_get_implementations (imp);
+    imp = _pixman_mips_get_implementations (imp);
+
+    imp = _pixman_implementation_create_noop (imp);
+
+    return imp;
+}
--- a/gfx/cairo/libpixman/src/pixman-inlines.h
+++ b/gfx/cairo/libpixman/src/pixman-inlines.h
@@ -76,48 +76,37 @@ repeat (pixman_repeat_t repeat, int *c, 
     {
 	*c = MOD (*c, size * 2);
 	if (*c >= size)
 	    *c = size * 2 - *c - 1;
     }
     return TRUE;
 }
 
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-#define LOW_QUALITY_INTERPOLATION
-#define LOWER_QUALITY_INTERPOLATION
-#endif
-
-#ifdef LOW_QUALITY_INTERPOLATION
-#define INTERPOLATION_PRECISION_BITS 4
-#else
-#define INTERPOLATION_PRECISION_BITS 8
-#endif
-static force_inline int32_t
-interpolation_coord(pixman_fixed_t t)
+static force_inline int
+pixman_fixed_to_bilinear_weight (pixman_fixed_t x)
 {
-#ifdef LOW_QUALITY_INTERPOLATION
-    return (t >> 12) & 0xf;
-#else
-    return (t >> 8) & 0xff;
-#endif
+    return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) &
+	   ((1 << BILINEAR_INTERPOLATION_BITS) - 1);
 }
 
-
 #if SIZEOF_LONG > 4
 
 static force_inline uint32_t
 bilinear_interpolation (uint32_t tl, uint32_t tr,
 			uint32_t bl, uint32_t br,
 			int distx, int disty)
 {
     uint64_t distxy, distxiy, distixy, distixiy;
     uint64_t tl64, tr64, bl64, br64;
     uint64_t f, r;
 
+    distx <<= (8 - BILINEAR_INTERPOLATION_BITS);
+    disty <<= (8 - BILINEAR_INTERPOLATION_BITS);
+
     distxy = distx * disty;
     distxiy = distx * (256 - disty);
     distixy = (256 - distx) * disty;
     distixiy = (256 - distx) * (256 - disty);
 
     /* Alpha and Blue */
     tl64 = tl & 0xff0000ff;
     tr64 = tr & 0xff0000ff;
@@ -179,16 +168,19 @@ bilinear_interpolation(uint32_t a00, uin
 static force_inline uint32_t
 bilinear_interpolation (uint32_t tl, uint32_t tr,
 			uint32_t bl, uint32_t br,
 			int distx, int disty)
 {
     int distxy, distxiy, distixy, distixiy;
     uint32_t f, r;
 
+    distx <<= (8 - BILINEAR_INTERPOLATION_BITS);
+    disty <<= (8 - BILINEAR_INTERPOLATION_BITS);
+
     distxy = distx * disty;
     distxiy = (distx << 8) - distxy;	/* distx * (256 - disty) */
     distixy = (disty << 8) - distxy;	/* disty * (256 - distx) */
     distixiy =
 	256 * 256 - (disty << 8) -
 	(distx << 8) + distxy;		/* (256 - distx) * (256 - disty) */
 
     /* Blue */
@@ -809,22 +801,24 @@ bilinear_pad_repeat_get_scanline_bounds 
  *  unit_x              - position increment needed to move to the next pair
  *                        of pixels
  *  max_vx              - image size as a fixed point value, can be used for
  *                        implementing NORMAL repeat (when it is supported)
  *  zero_src            - boolean hint variable, which is set to TRUE when
  *                        all source pixels are fetched from zero padding
  *                        zone for NONE repeat
  *
- * Note: normally the sum of 'weight_top' and 'weight_bottom' is equal to 256,
- *       but sometimes it may be less than that for NONE repeat when handling
- *       fuzzy antialiased top or bottom image edges. Also both top and
- *       bottom weight variables are guaranteed to have value in 0-255
- *       range and can fit into unsigned byte or be used with 8-bit SIMD
- *       multiplication instructions.
+ * Note: normally the sum of 'weight_top' and 'weight_bottom' is equal to
+ *       BILINEAR_INTERPOLATION_RANGE, but sometimes it may be less than that
+ *       for NONE repeat when handling fuzzy antialiased top or bottom image
+ *       edges. Also both top and bottom weight variables are guaranteed to
+ *       have value, which is less than BILINEAR_INTERPOLATION_RANGE.
+ *       For example, the weights can fit into unsigned byte or be used
+ *       with 8-bit SIMD multiplication instructions for 8-bit interpolation
+ *       precision.
  */
 
 /* Replace a single "scanline_func" with "fetch_func" & "op_func" to allow optional
  * two stage processing (bilinear fetch to a temp buffer, followed by unscaled
  * combine), "op_func" may be NULL, in this case we keep old behavior.
  * This is ugly and gcc issues some warnings, but works.
  *
  * An advice: clang has much better error reporting than gcc for deeply nested macros.
@@ -969,28 +963,28 @@ fast_composite_scaled_bilinear ## scale_
 	vx = v.vector[0];									\
 	if (flags & FLAG_HAVE_NON_SOLID_MASK)							\
 	{											\
 	    mask = mask_line;									\
 	    mask_line += mask_stride;								\
 	}											\
 												\
 	y1 = pixman_fixed_to_int (vy);								\
-	weight2 = (vy >> 8) & 0xff;								\
+	weight2 = pixman_fixed_to_bilinear_weight (vy);						\
 	if (weight2)										\
 	{											\
-	    /* normal case, both row weights are in 0-255 range and fit unsigned byte */	\
+	    /* both weight1 and weight2 are smaller than BILINEAR_INTERPOLATION_RANGE */	\
 	    y2 = y1 + 1;									\
-	    weight1 = 256 - weight2;								\
+	    weight1 = BILINEAR_INTERPOLATION_RANGE - weight2;					\
 	}											\
 	else											\
 	{											\
-	    /* set both top and bottom row to the same scanline, and weights to 128+128 */	\
+	    /* set both top and bottom row to the same scanline and tweak weights */		\
 	    y2 = y1;										\
-	    weight1 = weight2 = 128;								\
+	    weight1 = weight2 = BILINEAR_INTERPOLATION_RANGE / 2;				\
 	}											\
 	vy += unit_y;										\
 	if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD)					\
 	{											\
 	    src_type_t *src1, *src2;								\
 	    src_type_t buf1[2];									\
 	    src_type_t buf2[2];									\
 	    repeat (PIXMAN_REPEAT_PAD, &y1, src_image->bits.height);				\
--- a/gfx/cairo/libpixman/src/pixman-linear-gradient.c
+++ b/gfx/cairo/libpixman/src/pixman-linear-gradient.c
@@ -393,30 +393,30 @@ linear_get_scanline_wide (pixman_iter_t 
 
 void
 _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t  *iter)
 {
     // XXX: we can't use this optimization when dithering
     if (0 && linear_gradient_is_horizontal (
 	    iter->image, iter->x, iter->y, iter->width, iter->height))
     {
-	if (iter->flags & ITER_16)
+	if (iter->iter_flags & ITER_16)
 	    linear_get_scanline_16 (iter, NULL);
-	else if (iter->flags & ITER_NARROW)
+	else if (iter->iter_flags & ITER_NARROW)
 	    linear_get_scanline_narrow (iter, NULL);
 	else
 	    linear_get_scanline_wide (iter, NULL);
 
 	iter->get_scanline = _pixman_iter_get_scanline_noop;
     }
     else
     {
-	if (iter->flags & ITER_16)
+	if (iter->iter_flags & ITER_16)
 	    iter->get_scanline = linear_get_scanline_16;
-	else if (iter->flags & ITER_NARROW)
+	else if (iter->iter_flags & ITER_NARROW)
 	    iter->get_scanline = linear_get_scanline_narrow;
 	else
 	    iter->get_scanline = linear_get_scanline_wide;
     }
 }
 
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_linear_gradient (pixman_point_fixed_t *        p1,
--- a/gfx/cairo/libpixman/src/pixman-matrix.c
+++ b/gfx/cairo/libpixman/src/pixman-matrix.c
@@ -20,17 +20,17 @@
  * OF THIS SOFTWARE.
  */
 
 /*
  * Matrix interfaces
  */
 
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <math.h>
 #include <string.h>
 #include "pixman-private.h"
 
 #define F(x)    pixman_int_to_fixed (x)
 
@@ -466,18 +466,18 @@ pixman_transform_from_pixman_f_transform
 }
 
 PIXMAN_EXPORT pixman_bool_t
 pixman_f_transform_invert (struct pixman_f_transform *      dst,
                            const struct pixman_f_transform *src)
 {
     double det;
     int i, j;
-    static int a[3] = { 2, 2, 1 };
-    static int b[3] = { 1, 0, 0 };
+    static const int a[3] = { 2, 2, 1 };
+    static const int b[3] = { 1, 0, 0 };
 
     det = 0;
     for (i = 0; i < 3; i++)
     {
 	double p;
 	int ai = a[i];
 	int bi = b[i];
 	p = src->m[i][0] * (src->m[ai][2] * src->m[bi][1] -
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/libpixman/src/pixman-mips-dspr2-asm.S
@@ -0,0 +1,1521 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, 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.
+ *
+ * Author:  Nemanja Lukic (nlukic@mips.com)
+ */
+
+#include "pixman-private.h"
+#include "pixman-mips-dspr2-asm.h"
+
+LEAF_MIPS_DSPR2(pixman_fill_buff16_mips)
+/*
+ * a0 - *dest
+ * a1 - count (bytes)
+ * a2 - value to fill buffer with
+ */
+
+    beqz     a1, 3f
+     andi    t1, a0, 0x0002
+    beqz     t1, 0f          /* check if address is 4-byte aligned */
+     nop
+    sh       a2, 0(a0)
+    addiu    a0, a0, 2
+    addiu    a1, a1, -2
+0:
+    srl      t1, a1, 5       /* t1 how many multiples of 32 bytes */
+    replv.ph a2, a2          /* replicate fill value (16bit) in a2 */
+    beqz     t1, 2f
+     nop
+1:
+    addiu    t1, t1, -1
+    beqz     t1, 11f
+     addiu   a1, a1, -32
+    pref     30, 32(a0)
+    sw       a2, 0(a0)
+    sw       a2, 4(a0)
+    sw       a2, 8(a0)
+    sw       a2, 12(a0)
+    sw       a2, 16(a0)
+    sw       a2, 20(a0)
+    sw       a2, 24(a0)
+    sw       a2, 28(a0)
+    b        1b
+     addiu   a0, a0, 32
+11:
+    sw       a2, 0(a0)
+    sw       a2, 4(a0)
+    sw       a2, 8(a0)
+    sw       a2, 12(a0)
+    sw       a2, 16(a0)
+    sw       a2, 20(a0)
+    sw       a2, 24(a0)
+    sw       a2, 28(a0)
+    addiu    a0, a0, 32
+2:
+    blez     a1, 3f
+     addiu   a1, a1, -2
+    sh       a2, 0(a0)
+    b        2b
+     addiu   a0, a0, 2
+3:
+    jr       ra
+     nop
+
+END(pixman_fill_buff16_mips)
+
+LEAF_MIPS32R2(pixman_fill_buff32_mips)
+/*
+ * a0 - *dest
+ * a1 - count (bytes)
+ * a2 - value to fill buffer with
+ */
+
+    beqz     a1, 3f
+     nop
+    srl      t1, a1, 5 /* t1 how many multiples of 32 bytes */
+    beqz     t1, 2f
+     nop
+1:
+    addiu    t1, t1, -1
+    beqz     t1, 11f
+     addiu   a1, a1, -32
+    pref     30, 32(a0)
+    sw       a2, 0(a0)
+    sw       a2, 4(a0)
+    sw       a2, 8(a0)
+    sw       a2, 12(a0)
+    sw       a2, 16(a0)
+    sw       a2, 20(a0)
+    sw       a2, 24(a0)
+    sw       a2, 28(a0)
+    b        1b
+     addiu   a0, a0, 32
+11:
+    sw       a2, 0(a0)
+    sw       a2, 4(a0)
+    sw       a2, 8(a0)
+    sw       a2, 12(a0)
+    sw       a2, 16(a0)
+    sw       a2, 20(a0)
+    sw       a2, 24(a0)
+    sw       a2, 28(a0)
+    addiu    a0, a0, 32
+2:
+    blez     a1, 3f
+     addiu   a1, a1, -4
+    sw       a2, 0(a0)
+    b        2b
+     addiu   a0, a0, 4
+3:
+    jr       ra
+     nop
+
+END(pixman_fill_buff32_mips)
+
+LEAF_MIPS_DSPR2(pixman_composite_src_8888_0565_asm_mips)
+/*
+ * a0 - dst (r5g6b5)
+ * a1 - src (a8r8g8b8)
+ * a2 - w
+ */
+
+    beqz     a2, 3f
+     nop
+    addiu    t1, a2, -1
+    beqz     t1, 2f
+     nop
+    li       t4, 0xf800f800
+    li       t5, 0x07e007e0
+    li       t6, 0x001f001f
+1:
+    lw       t0, 0(a1)
+    lw       t1, 4(a1)
+    addiu    a1, a1, 8
+    addiu    a2, a2, -2
+
+    CONVERT_2x8888_TO_2x0565 t0, t1, t2, t3, t4, t5, t6, t7, t8
+
+    sh       t2, 0(a0)
+    sh       t3, 2(a0)
+
+    addiu    t2, a2, -1
+    bgtz     t2, 1b
+     addiu   a0, a0, 4
+2:
+    beqz     a2, 3f
+     nop
+    lw       t0, 0(a1)
+
+    CONVERT_1x8888_TO_1x0565 t0, t1, t2, t3
+
+    sh       t1, 0(a0)
+3:
+    j        ra
+     nop
+
+END(pixman_composite_src_8888_0565_asm_mips)
+
+LEAF_MIPS_DSPR2(pixman_composite_src_0565_8888_asm_mips)
+/*
+ * a0 - dst (a8r8g8b8)
+ * a1 - src (r5g6b5)
+ * a2 - w
+ */
+
+    beqz     a2, 3f
+     nop
+    addiu    t1, a2, -1
+    beqz     t1, 2f
+     nop
+    li       t4, 0x07e007e0
+    li       t5, 0x001F001F
+1:
+    lhu      t0, 0(a1)
+    lhu      t1, 2(a1)
+    addiu    a1, a1, 4
+    addiu    a2, a2, -2
+
+    CONVERT_2x0565_TO_2x8888 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9
+
+    sw       t2, 0(a0)
+    sw       t3, 4(a0)
+
+    addiu    t2, a2, -1
+    bgtz     t2, 1b
+     addiu   a0, a0, 8
+2:
+    beqz     a2, 3f
+     nop
+    lhu      t0, 0(a1)
+
+    CONVERT_1x0565_TO_1x8888 t0, t1, t2, t3
+
+    sw       t1, 0(a0)
+3:
+    j        ra
+     nop
+
+END(pixman_composite_src_0565_8888_asm_mips)
+
+LEAF_MIPS_DSPR2(pixman_composite_src_x888_8888_asm_mips)
+/*
+ * a0 - dst (a8r8g8b8)
+ * a1 - src (x8r8g8b8)
+ * a2 - w
+ */
+
+    beqz     a2, 4f
+     nop
+    li       t9, 0xff000000
+    srl      t8, a2, 3    /* t1 = how many multiples of 8 src pixels */
+    beqz     t8, 3f       /* branch if less than 8 src pixels */
+     nop
+1:
+    addiu    t8, t8, -1
+    beqz     t8, 2f
+     addiu   a2, a2, -8
+    pref     0, 32(a1)
+    lw       t0, 0(a1)
+    lw       t1, 4(a1)
+    lw       t2, 8(a1)
+    lw       t3, 12(a1)
+    lw       t4, 16(a1)
+    lw       t5, 20(a1)
+    lw       t6, 24(a1)
+    lw       t7, 28(a1)
+    addiu    a1, a1, 32
+    or       t0, t0, t9
+    or       t1, t1, t9
+    or       t2, t2, t9
+    or       t3, t3, t9
+    or       t4, t4, t9
+    or       t5, t5, t9
+    or       t6, t6, t9
+    or       t7, t7, t9
+    pref     30, 32(a0)
+    sw       t0, 0(a0)
+    sw       t1, 4(a0)
+    sw       t2, 8(a0)
+    sw       t3, 12(a0)
+    sw       t4, 16(a0)
+    sw       t5, 20(a0)
+    sw       t6, 24(a0)
+    sw       t7, 28(a0)
+    b        1b
+     addiu   a0, a0, 32
+2:
+    lw       t0, 0(a1)
+    lw       t1, 4(a1)
+    lw       t2, 8(a1)
+    lw       t3, 12(a1)
+    lw       t4, 16(a1)
+    lw       t5, 20(a1)
+    lw       t6, 24(a1)
+    lw       t7, 28(a1)
+    addiu    a1, a1, 32
+    or       t0, t0, t9
+    or       t1, t1, t9
+    or       t2, t2, t9
+    or       t3, t3, t9
+    or       t4, t4, t9
+    or       t5, t5, t9
+    or       t6, t6, t9
+    or       t7, t7, t9
+    sw       t0, 0(a0)
+    sw       t1, 4(a0)
+    sw       t2, 8(a0)
+    sw       t3, 12(a0)
+    sw       t4, 16(a0)
+    sw       t5, 20(a0)
+    sw       t6, 24(a0)
+    sw       t7, 28(a0)
+    beqz     a2, 4f
+     addiu   a0, a0, 32
+3:
+    lw       t0, 0(a1)
+    addiu    a1, a1, 4
+    addiu    a2, a2, -1
+    or       t1, t0, t9
+    sw       t1, 0(a0)
+    bnez     a2, 3b
+     addiu   a0, a0, 4
+4:
+    jr       ra
+     nop
+
+END(pixman_composite_src_x888_8888_asm_mips)
+
+LEAF_MIPS_DSPR2(pixman_composite_over_n_8888_8888_ca_asm_mips)
+/*
+ * a0 - dst  (a8r8g8b8)
+ * a1 - src  (32bit constant)
+ * a2 - mask (a8r8g8b8)
+ * a3 - w
+ */
+
+    SAVE_REGS_ON_STACK 8, s0, s1, s2, s3, s4, s5
+    beqz         a3, 4f
+     nop
+    li           t6, 0xff
+    addiu        t7, zero, -1 /* t7 = 0xffffffff */
+    srl          t8, a1, 24   /* t8 = srca */
+    li           t9, 0x00ff00ff
+    addiu        t1, a3, -1
+    beqz         t1, 3f       /* last pixel */
+     nop
+    beq          t8, t6, 2f   /* if (srca == 0xff) */
+     nop
+1:
+                              /* a1 = src */
+    lw           t0, 0(a2)    /* t0 = mask */
+    lw           t1, 4(a2)    /* t1 = mask */
+    or           t2, t0, t1
+    beqz         t2, 12f      /* if (t0 == 0) && (t1 == 0) */
+     addiu       a2, a2, 8
+    and          t3, t0, t1
+    move         t4, a1       /* t4 = src */
+    move         t5, a1       /* t5 = src */
+    lw           t2, 0(a0)    /* t2 = dst */
+    beq          t3, t7, 11f  /* if (t0 == 0xffffffff) && (t1 == 0xffffffff) */
+     lw          t3, 4(a0)    /* t3 = dst */
+    MIPS_2xUN8x4_MUL_2xUN8x4 a1, a1, t0, t1, t4, t5, t9, s0, s1, s2, s3, s4, s5
+    MIPS_2xUN8x4_MUL_2xUN8   t0, t1, t8, t8, t0, t1, t9, s0, s1, s2, s3, s4, s5
+11:
+    not          t0, t0
+    not          t1, t1
+    MIPS_2xUN8x4_MUL_2xUN8x4 t2, t3, t0, t1, t2, t3, t9, s0, s1, s2, s3, s4, s5
+    addu_s.qb    t2, t4, t2
+    addu_s.qb    t3, t5, t3
+    sw           t2, 0(a0)
+    sw           t3, 4(a0)
+12:
+    addiu        a3, a3, -2
+    addiu        t1, a3, -1
+    bgtz         t1, 1b
+     addiu       a0, a0, 8
+    b            3f
+     nop
+2:
+                              /* a1 = src */
+    lw           t0, 0(a2)    /* t0 = mask */
+    lw           t1, 4(a2)    /* t1 = mask */
+    or           t2, t0, t1
+    beqz         t2, 22f      /* if (t0 == 0) & (t1 == 0) */
+     addiu       a2, a2, 8
+    and          t2, t0, t1
+    move         t4, a1
+    beq          t2, t7, 21f  /* if (t0 == 0xffffffff) && (t1 == 0xffffffff) */
+     move        t5, a1
+    lw           t2, 0(a0)    /* t2 = dst */
+    lw           t3, 4(a0)    /* t3 = dst */
+    MIPS_2xUN8x4_MUL_2xUN8x4 a1, a1, t0, t1, t4, t5, t9, s0, s1, s2, s3, s4, s5
+    not          t0, t0
+    not          t1, t1
+    MIPS_2xUN8x4_MUL_2xUN8x4 t2, t3, t0, t1, t2, t3, t9, s0, s1, s2, s3, s4, s5
+    addu_s.qb    t4, t4, t2
+    addu_s.qb    t5, t5, t3
+21:
+    sw           t4, 0(a0)
+    sw           t5, 4(a0)
+22:
+    addiu        a3, a3, -2
+    addiu        t1, a3, -1
+    bgtz         t1, 2b
+     addiu       a0, a0, 8
+3:
+    blez         a3, 4f
+     nop
+                              /* a1 = src */
+    lw           t1, 0(a2)    /* t1 = mask */
+    beqz         t1, 4f
+     nop
+    move         t2, a1       /* t2 = src */
+    beq          t1, t7, 31f
+     lw          t0, 0(a0)    /* t0 = dst */
+
+    MIPS_UN8x4_MUL_UN8x4  a1, t1, t2, t9, t3, t4, t5, t6
+    MIPS_UN8x4_MUL_UN8    t1, t8, t1, t9, t3, t4, t5
+31:
+    not          t1, t1
+    MIPS_UN8x4_MUL_UN8x4  t0, t1, t0, t9, t3, t4, t5, t6
+    addu_s.qb    t0, t2, t0
+    sw           t0, 0(a0)
+4:
+    RESTORE_REGS_FROM_STACK 8, s0, s1, s2, s3, s4, s5
+    j            ra
+     nop
+
+END(pixman_composite_over_n_8888_8888_ca_asm_mips)
+
+LEAF_MIPS_DSPR2(pixman_composite_over_n_8888_0565_ca_asm_mips)
+/*
+ * a0 - dst  (r5g6b5)
+ * a1 - src  (32bit constant)
+ * a2 - mask (a8r8g8b8)
+ * a3 - w
+ */
+
+    SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7, s8
+    beqz         a3, 4f
+     nop
+    li           t5, 0xf800f800
+    li           t6, 0x07e007e0
+    li           t7, 0x001F001F
+    li           t9, 0x00ff00ff
+
+    srl          t8, a1, 24   /* t8 = srca */
+    addiu        t1, a3, -1
+    beqz         t1, 3f       /* last pixel */
+     nop
+    li           s0, 0xff     /* s0 = 0xff */
+    addiu        s1, zero, -1 /* s1 = 0xffffffff */
+
+    beq          t8, s0, 2f   /* if (srca == 0xff) */
+     nop
+1:
+                              /* a1 = src */
+    lw           t0, 0(a2)    /* t0 = mask */
+    lw           t1, 4(a2)    /* t1 = mask */
+    or           t2, t0, t1
+    beqz         t2, 12f      /* if (t0 == 0) && (t1 == 0) */
+     addiu       a2, a2, 8
+    and          t3, t0, t1
+    move         s2, a1       /* s2 = src */
+    move         s3, a1       /* s3 = src */
+    lhu          t2, 0(a0)    /* t2 = dst */
+    beq          t3, s1, 11f  /* if (t0 == 0xffffffff) && (t1 == 0xffffffff) */
+     lhu         t3, 2(a0)    /* t3 = dst */
+    MIPS_2xUN8x4_MUL_2xUN8x4 a1, a1, t0, t1, s2, s3, t9, t4, s4, s5, s6, s7, s8
+    MIPS_2xUN8x4_MUL_2xUN8   t0, t1, t8, t8, t0, t1, t9, t4, s4, s5, s6, s7, s8
+11:
+    not          t0, t0
+    not          t1, t1
+    CONVERT_2x0565_TO_2x8888 t2, t3, s4, s5, t6, t7, t4, s6, s7, s8
+    MIPS_2xUN8x4_MUL_2xUN8x4 s4, s5, t0, t1, s4, s5, t9, t4, s6, s7, s8, t0, t1
+    addu_s.qb    s2, s2, s4
+    addu_s.qb    s3, s3, s5
+    CONVERT_2x8888_TO_2x0565 s2, s3, t2, t3, t5, t6, t7, s4, s5
+    sh           t2, 0(a0)
+    sh           t3, 2(a0)
+12:
+    addiu        a3, a3, -2
+    addiu        t1, a3, -1
+    bgtz         t1, 1b
+     addiu       a0, a0, 4
+    b            3f
+     nop
+2:
+                              /* a1 = src */
+    lw           t0, 0(a2)    /* t0 = mask */
+    lw           t1, 4(a2)    /* t1 = mask */
+    or           t2, t0, t1
+    beqz         t2, 22f      /* if (t0 == 0) & (t1 == 0) */
+     addiu       a2, a2, 8
+    and          t3, t0, t1
+    move         t2, a1
+    beq          t3, s1, 21f  /* if (t0 == 0xffffffff) && (t1 == 0xffffffff) */
+     move        t3, a1
+    lhu          t2, 0(a0)    /* t2 = dst */
+    lhu          t3, 2(a0)    /* t3 = dst */