Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 15 Apr 2014 23:28:51 -0400
changeset 197269 025a433dd5eb133140b0ff7c46731d4c28c110b1
parent 197268 ae585238d9a8aadb4988dbfad25143075e67d99e (current diff)
parent 197225 dd50745d7f35796adf7b037c2e60c3f6809a7347 (diff)
child 197270 a253e0f43fe6c1bb52fb8dcbc0d057d92eb6ba79
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone31.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 m-c to fx-team.
--- a/accessible/src/jsat/Utils.jsm
+++ b/accessible/src/jsat/Utils.jsm
@@ -592,17 +592,17 @@ PivotContext.prototype = {
    */
   _getAncestry: function _getAncestry(aAccessible) {
     let ancestry = [];
     let parent = aAccessible;
     try {
       while (parent && (parent = parent.parent)) {
        ancestry.push(parent);
       }
-    } catch (e) {
+    } catch (x) {
       // A defunct accessible will raise an exception geting parent.
       Logger.debug('Failed to get parent:', x);
     }
     return ancestry.reverse();
   },
 
   /**
    * A list of the old accessible's ancestry.
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -269,17 +269,16 @@ pref("editor.singleLine.pasteNewlines", 
 pref("ui.dragThresholdX", 25);
 pref("ui.dragThresholdY", 25);
 
 // Layers Acceleration.  We can only have nice things on gonk, because
 // they're not maintained anywhere else.
 pref("layers.offmainthreadcomposition.enabled", true);
 #ifndef MOZ_WIDGET_GONK
 pref("dom.ipc.tabs.disabled", true);
-pref("layers.acceleration.disabled", true);
 pref("layers.offmainthreadcomposition.async-animations", false);
 pref("layers.async-video.enabled", false);
 #else
 pref("dom.ipc.tabs.disabled", false);
 pref("layers.acceleration.disabled", false);
 pref("layers.offmainthreadcomposition.async-animations", true);
 pref("layers.async-video.enabled", true);
 pref("layers.async-pan-zoom.enabled", true);
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="99a67a75855d8ca077018c819aedd90bf0447d9b"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e6383e6e785cc3ea237e902beb1092f9aa88e29d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
@@ -123,14 +123,14 @@
   <project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/>
   <project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/>
   <default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/>
   <!-- Emulator specific things -->
   <project name="android-development" path="development" remote="b2g" revision="dab55669da8f48b6e57df95d5af9f16b4a87b0b1"/>
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="09485b73629856b21b2ed6073e327ab0e69a1189"/>
   <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
-  <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a3467d423c2ed54f2b4efbc5b47c06af85c3bdc3"/>
+  <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="f8e49f3837230cfbb2d6fbcf239d1f25b57b39a7"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="72e3a520e3c700839f07ba0113fd527b923c3330"/>
   <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="3b002889eca9e47f77ef10af44619c8c56df069b"/>
   <project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
 </manifest>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="52c909ccead537f8f9dbf634f3e6639078a8b0bd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="99a67a75855d8ca077018c819aedd90bf0447d9b"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame/config.json
+++ b/b2g/config/flame/config.json
@@ -1,13 +1,13 @@
 {
     "config_version": 2,
     "tooltool_manifest": "releng-flame.tt",
-    "mock_target": "mozilla-centos6-i386",
-    "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel", "git"],
+    "mock_target": "mozilla-centos6-x86_64",
+    "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
     "build_targets": [],
     "upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
@@ -25,17 +25,17 @@
     ],
     "env": {
         "VARIANT": "user",
         "MOZILLA_OFFICIAL": "1"
     },
     "b2g_manifest": "flame.xml",
     "b2g_manifest_branch": "master",
     "b2g_manifest_intree": true,
-    "additional_source_tarballs": [],
+    "additional_source_tarballs": ["backup-flame.tar.xz"],
     "gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
     "gaia": {
         "l10n": {
             "vcs": "hgtool",
             "root": "https://hg.mozilla.org/gaia-l10n"
         }
     }
 }
--- a/b2g/config/flame/releng-flame.tt
+++ b/b2g/config/flame/releng-flame.tt
@@ -1,2 +1,7 @@
 [
+{"size": 169226356,
+"digest": "f9456848fd661b8be05d6a30607fad4787bcecfe676b53f9a4074653fdda6a377c961038c866c5d83355e3afd89f1a3bd947a142aeaf7dd7d81b6c376185badd",
+"filename": "backup-flame.tar.xz",
+"algorithm": "sha512"
+}
 ]
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -13,17 +13,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e6383e6e785cc3ea237e902beb1092f9aa88e29d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "c766bc0d49af19f18788ad8ed0542b82db81f1d8", 
+    "revision": "b43fa272b6a254e7b15a79bb7771133a6d950c49", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e6383e6e785cc3ea237e902beb1092f9aa88e29d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/mozconfigs/macosx64_gecko/debug
+++ b/b2g/config/mozconfigs/macosx64_gecko/debug
@@ -1,8 +1,9 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
 . $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-signmar
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
--- a/b2g/config/mozconfigs/macosx64_gecko/nightly
+++ b/b2g/config/mozconfigs/macosx64_gecko/nightly
@@ -1,8 +1,9 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
 . $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-signmar
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d47c0627017ef77b1adf179792c6543a349af72"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3d4b4b06475d2376bad23ac46da185cd48a68d17"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -748,27 +748,29 @@ nsWindowsShellService::SetShouldCheckDef
   return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
 }
 
 static nsresult
 WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
 {
   nsresult rv;
 
-  nsRefPtr<gfxASurface> thebesSurface =
+  RefPtr<SourceSurface> surface =
     aImage->GetFrame(imgIContainer::FRAME_FIRST,
                      imgIContainer::FLAG_SYNC_DECODE);
-  NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
-  nsRefPtr<gfxImageSurface> thebesImageSurface =
-    thebesSurface->GetAsReadableARGB32ImageSurface();
-  NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
+  // For either of the following formats we want to set the biBitCount member
+  // of the BITMAPINFOHEADER struct to 32, below. For that value the bitmap
+  // format defines that the A8/X8 WORDs in the bitmap byte stream be ignored
+  // for the BI_RGB value we use for the biCompression member.
+  MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+             surface->GetFormat() == SurfaceFormat::B8G8R8X8);
 
-  RefPtr<DataSourceSurface> dataSurface =
-    thebesImageSurface->CopyToB8G8R8A8DataSourceSurface();
+  RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
   NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
 
   int32_t width = dataSurface->GetSize().width;
   int32_t height = dataSurface->GetSize().height;
   int32_t bytesPerPixel = 4 * sizeof(uint8_t);
   uint32_t bytesPerRow = bytesPerPixel * width;
 
   // initialize these bitmap structs which we will later
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -224,13 +224,14 @@ LOCAL_INCLUDES += [
     '/js/xpconnect/src',
     '/js/xpconnect/wrappers',
     '/layout/base',
     '/layout/generic',
     '/layout/style',
     '/layout/svg',
     '/layout/xul',
     '/netwerk/base/src',
+    '/xpcom/ds',
 ]
 
 if CONFIG['GNU_CC'] and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     # Work around bug 986928
     CXXFLAGS += ['-Wno-error=format']
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -119,16 +119,17 @@
 #include "nsIImageLoadingContent.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIIOService.h"
 #include "nsIJSRuntimeService.h"
 #include "nsILineBreaker.h"
 #include "nsILoadContext.h"
 #include "nsILoadGroup.h"
+#include "nsIMemoryReporter.h"
 #include "nsIMIMEService.h"
 #include "nsINode.h"
 #include "nsINodeInfo.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIParser.h"
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -95,19 +95,21 @@
 #include "nsGlobalWindow.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "SVGContentUtils.h"
 #include "nsIScreenManager.h"
 
 #undef free // apparently defined by some windows header, clashing with a free()
             // method in SkTypes.h
+#ifdef USE_SKIA
 #include "SkiaGLGlue.h"
 #include "SurfaceStream.h"
 #include "SurfaceTypes.h"
+#endif
 
 using mozilla::gl::GLContext;
 using mozilla::gl::SkiaGLGlue;
 using mozilla::gl::GLContextProvider;
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
@@ -895,25 +897,27 @@ CanvasRenderingContext2D::EnsureTarget()
      if (layerManager) {
       if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
           !mForceSoftware &&
           CheckSizeForSkiaGL(size)) {
         DemoteOldestContextIfNecessary();
 
         SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
 
+#if USE_SKIA
         if (glue && glue->GetGrContext() && glue->GetGLContext()) {
           mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
           if (mTarget) {
             mStream = gfx::SurfaceStream::CreateForType(SurfaceStreamType::TripleBuffer, glue->GetGLContext());
             AddDemotableContext(this);
           } else {
             printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
           }
         }
+#endif
         if (!mTarget) {
           mTarget = layerManager->CreateDrawTarget(size, format);
         }
       } else
         mTarget = layerManager->CreateDrawTarget(size, format);
      } else {
         mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
      }
@@ -4239,22 +4243,24 @@ CanvasRenderingContext2D::GetCanvasLayer
 
   if (!mResetLayer && aOldLayer) {
     CanvasRenderingContext2DUserData* userData =
       static_cast<CanvasRenderingContext2DUserData*>(
         aOldLayer->GetUserData(&g2DContextLayerUserData));
 
     CanvasLayer::Data data;
     if (mStream) {
+#ifdef USE_SKIA
       SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
 
       if (glue) {
         data.mGLContext = glue->GetGLContext();
         data.mStream = mStream.get();
       }
+#endif
     } else {
       data.mDrawTarget = mTarget;
     }
 
     if (userData && userData->IsForContext(this) && aOldLayer->IsDataValid(data)) {
       nsRefPtr<CanvasLayer> ret = aOldLayer;
       return ret.forget();
     }
@@ -4287,17 +4293,19 @@ CanvasRenderingContext2D::GetCanvasLayer
 
   CanvasLayer::Data data;
   if (mStream) {
     SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
 
     if (glue) {
       canvasLayer->SetPreTransactionCallback(
               CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
+#if USE_SKIA
       data.mGLContext = glue->GetGLContext();
+#endif
       data.mStream = mStream.get();
       data.mTexID = (uint32_t)((uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE));
     }
   } else {
     data.mDrawTarget = mTarget;
   }
 
   data.mSize = nsIntSize(mWidth, mHeight);
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -4669,34 +4669,25 @@ HTMLInputElement::GetValueAsDate(const n
  * -The day must be exactly 2 digit long, and 01 <= day <= maxday
  *  Where maxday is the number of days in the month 'month' and year 'year'
  */
 
   if (aValue.Length() < 10) {
     return false;
   }
 
-  uint32_t endOfYearOffset = 0;
-  for (; NS_IsAsciiDigit(aValue[endOfYearOffset]); ++endOfYearOffset);
-
-  // The year must be at least 4 digits long.
-  if (aValue[endOfYearOffset] != '-' || endOfYearOffset < 4) {
+  uint32_t endOfYearOffset = aValue.Length() - 6;
+  
+  if (aValue[endOfYearOffset]     != '-' ||
+      aValue[endOfYearOffset + 3] != '-') {
     return false;
   }
 
-  // Now, we know where is the next '-' and what should be the size of the
-  // string.
-  if (aValue[endOfYearOffset + 3] != '-' ||
-      aValue.Length() != 10 + (endOfYearOffset - 4)) {
-    return false;
-  }
-
-  nsresult ec;
-  *aYear = PromiseFlatString(StringHead(aValue, endOfYearOffset)).ToInteger(&ec);
-  if (NS_FAILED(ec) || *aYear == 0) {
+  if (!DigitSubStringToNumber(aValue, 0, endOfYearOffset, aYear) ||
+      *aYear < 1) {
     return false;
   }
 
   if (!DigitSubStringToNumber(aValue, endOfYearOffset + 1, 2, aMonth) ||
       *aMonth < 1 || *aMonth > 12) {
     return false;
   }
 
--- a/content/media/Latency.h
+++ b/content/media/Latency.h
@@ -8,17 +8,17 @@
 #define MOZILLA_LATENCY_H
 
 #include "mozilla/TimeStamp.h"
 #include "prlog.h"
 #include "nsCOMPtr.h"
 #include "nsIThread.h"
 #include "mozilla/Monitor.h"
 #include "nsISupportsImpl.h"
-#include "nsObserverService.h"
+#include "nsIObserver.h"
 
 class AsyncLatencyLogger;
 class LogEvent;
 
 PRLogModuleInfo* GetLatencyLog();
 
 // This class is a singleton. It is refcounted.
 class AsyncLatencyLogger : public nsIObserver
--- a/content/media/MediaTaskQueue.h
+++ b/content/media/MediaTaskQueue.h
@@ -18,21 +18,23 @@ namespace mozilla {
 
 class SharedThreadPool;
 
 // Abstracts executing runnables in order in a thread pool. The runnables
 // dispatched to the MediaTaskQueue will be executed in the order in which
 // they're received, and are guaranteed to not be executed concurrently.
 // They may be executed on different threads, and a memory barrier is used
 // to make this threadsafe for objects that aren't already threadsafe.
-class MediaTaskQueue : public AtomicRefCounted<MediaTaskQueue> {
+class MediaTaskQueue MOZ_FINAL {
+  ~MediaTaskQueue();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaTaskQueue)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTaskQueue)
+
   MediaTaskQueue(TemporaryRef<SharedThreadPool> aPool);
-  ~MediaTaskQueue();
 
   nsresult Dispatch(nsIRunnable* aRunnable);
 
   // Removes all pending tasks from the task queue, and blocks until
   // the currently running task (if any) finishes.
   void Flush();
 
   // Blocks until all tasks finish executing, then shuts down the task queue
--- a/content/media/fmp4/PlatformDecoderModule.h
+++ b/content/media/fmp4/PlatformDecoderModule.h
@@ -138,20 +138,22 @@ public:
 //
 // All functions must be threadsafe, and be able to be called on an
 // arbitrary thread.
 //
 // Decoding is done asynchronously. Any async work can be done on the
 // MediaTaskQueue passed into the PlatformDecoderModules's Create*Decoder()
 // function. This may not be necessary for platforms with async APIs
 // for decoding.
-class MediaDataDecoder : public AtomicRefCounted<MediaDataDecoder> {
+class MediaDataDecoder {
+protected:
+  virtual ~MediaDataDecoder() {};
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaDataDecoder)
-  virtual ~MediaDataDecoder() {};
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDecoder)
 
   // Initialize the decoder. The decoder should be ready to decode after
   // this returns. The decoder should do any initialization here, rather
   // than in its constructor or PlatformDecoderModule::Create*Decoder(),
   // so that if the MP4Reader needs to shutdown during initialization,
   // it can call Shutdown() to cancel this operation. Any initialization
   // that requires blocking the calling thread in this function *must*
   // be done here so that it can be canceled by calling Shutdown()!
--- a/content/media/fmp4/wmf/MFTDecoder.h
+++ b/content/media/fmp4/wmf/MFTDecoder.h
@@ -9,21 +9,23 @@
 
 #include "WMF.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsIThread.h"
 
 namespace mozilla {
 
-class MFTDecoder : public AtomicRefCounted<MFTDecoder> {
+class MFTDecoder MOZ_FINAL {
+  ~MFTDecoder();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(MTFDecoder)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MFTDecoder)
+
   MFTDecoder();
-  ~MFTDecoder();
 
   // Creates the MFT. First thing to do as part of setup.
   //
   // Params:
   //  - aMFTClsID the clsid used by CoCreateInstance to instantiate the
   //    decoder MFT.
   HRESULT Create(const GUID& aMFTClsID);
 
new file mode 100644
--- /dev/null
+++ b/content/media/gtest/TestVideoTrackEncoder.cpp
@@ -0,0 +1,296 @@
+/* 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 "gtest/gtest.h"
+#include <algorithm>
+
+#include "mozilla/ArrayUtils.h"
+#include "VP8TrackEncoder.h"
+#include "ImageContainer.h"
+#include "MediaStreamGraph.h"
+#include "WebMWriter.h" // TODO: it's weird to include muxer header to get the class definition of VP8 METADATA
+
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+using namespace mozilla::layers;
+using namespace mozilla;
+
+// A helper object to generate of different YUV planes.
+class YUVBufferGenerator {
+public:
+  YUVBufferGenerator() {}
+
+  void Init(const mozilla::gfx::IntSize &aSize)
+  {
+    mImageSize = aSize;
+
+    int yPlaneLen = aSize.width * aSize.height;
+    int cbcrPlaneLen = (yPlaneLen + 1) / 2;
+    int frameLen = yPlaneLen + cbcrPlaneLen;
+
+    // Generate source buffer.
+    mSourceBuffer.SetLength(frameLen);
+
+    // Fill Y plane.
+    memset(mSourceBuffer.Elements(), 0x10, yPlaneLen);
+
+    // Fill Cb/Cr planes.
+    memset(mSourceBuffer.Elements() + yPlaneLen, 0x80, cbcrPlaneLen);
+  }
+
+  mozilla::gfx::IntSize GetSize() const
+  {
+    return mImageSize;
+  }
+
+  void Generate(nsTArray<nsRefPtr<Image> > &aImages)
+  {
+    aImages.AppendElement(CreateI420Image());
+    aImages.AppendElement(CreateNV12Image());
+    aImages.AppendElement(CreateNV21Image());
+  }
+
+private:
+  Image *CreateI420Image()
+  {
+    PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
+    PlanarYCbCrData data;
+
+    const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
+    const uint32_t halfWidth = (mImageSize.width + 1) / 2;
+    const uint32_t halfHeight = (mImageSize.height + 1) / 2;
+    const uint32_t uvPlaneSize = halfWidth * halfHeight;
+
+    // Y plane.
+    uint8_t *y = mSourceBuffer.Elements();
+    data.mYChannel = y;
+    data.mYSize.width = mImageSize.width;
+    data.mYSize.height = mImageSize.height;
+    data.mYStride = mImageSize.width;
+    data.mYSkip = 0;
+
+    // Cr plane.
+    uint8_t *cr = y + yPlaneSize + uvPlaneSize;
+    data.mCrChannel = cr;
+    data.mCrSkip = 0;
+
+    // Cb plane
+    uint8_t *cb = y + yPlaneSize;
+    data.mCbChannel = cb;
+    data.mCbSkip = 0;
+
+    // CrCb plane vectors.
+    data.mCbCrStride = halfWidth;
+    data.mCbCrSize.width = halfWidth;
+    data.mCbCrSize.height = halfHeight;
+
+    image->SetData(data);
+    return image;
+  }
+
+  Image *CreateNV12Image()
+  {
+    PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
+    PlanarYCbCrData data;
+
+    const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
+    const uint32_t halfWidth = (mImageSize.width + 1) / 2;
+    const uint32_t halfHeight = (mImageSize.height + 1) / 2;
+
+    // Y plane.
+    uint8_t *y = mSourceBuffer.Elements();
+    data.mYChannel = y;
+    data.mYSize.width = mImageSize.width;
+    data.mYSize.height = mImageSize.height;
+    data.mYStride = mImageSize.width;
+    data.mYSkip = 0;
+
+    // Cr plane.
+    uint8_t *cr = y + yPlaneSize;
+    data.mCrChannel = cr;
+    data.mCrSkip = 1;
+
+    // Cb plane
+    uint8_t *cb = y + yPlaneSize + 1;
+    data.mCbChannel = cb;
+    data.mCbSkip = 1;
+
+    // 4:2:0.
+    data.mCbCrStride = mImageSize.width;
+    data.mCbCrSize.width = halfWidth;
+    data.mCbCrSize.height = halfHeight;
+
+    image->SetData(data);
+    return image;
+  }
+
+  Image *CreateNV21Image()
+  {
+    PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
+    PlanarYCbCrData data;
+
+    const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
+    const uint32_t halfWidth = (mImageSize.width + 1) / 2;
+    const uint32_t halfHeight = (mImageSize.height + 1) / 2;
+
+    // Y plane.
+    uint8_t *y = mSourceBuffer.Elements();
+    data.mYChannel = y;
+    data.mYSize.width = mImageSize.width;
+    data.mYSize.height = mImageSize.height;
+    data.mYStride = mImageSize.width;
+    data.mYSkip = 0;
+
+    // Cr plane.
+    uint8_t *cr = y + yPlaneSize + 1;
+    data.mCrChannel = cr;
+    data.mCrSkip = 1;
+
+    // Cb plane
+    uint8_t *cb = y + yPlaneSize;
+    data.mCbChannel = cb;
+    data.mCbSkip = 1;
+
+    // 4:2:0.
+    data.mCbCrStride = mImageSize.width;
+    data.mCbCrSize.width = halfWidth;
+    data.mCbCrSize.height = halfHeight;
+
+    image->SetData(data);
+    return image;
+  }
+
+private:
+  mozilla::gfx::IntSize mImageSize;
+  nsTArray<uint8_t> mSourceBuffer;
+};
+
+struct InitParam {
+  bool mShouldSucceed;  // This parameter should cause success or fail result
+  int  mWidth;          // frame width
+  int  mHeight;         // frame height
+  mozilla::TrackRate mTrackRate; // track rate. 90K is the most commond track rate.
+};
+
+class TestVP8TrackEncoder: public VP8TrackEncoder
+{
+public:
+  ::testing::AssertionResult TestInit(const InitParam &aParam)
+  {
+    nsresult result = Init(aParam.mWidth, aParam.mHeight, aParam.mWidth, aParam.mHeight, aParam.mTrackRate);
+
+    if (((NS_FAILED(result) && aParam.mShouldSucceed)) || (NS_SUCCEEDED(result) && !aParam.mShouldSucceed))
+    {
+      return ::testing::AssertionFailure()
+                << " width = " << aParam.mWidth
+                << " height = " << aParam.mHeight
+                << " TrackRate = " << aParam.mTrackRate << ".";
+    }
+    else
+    {
+      return ::testing::AssertionSuccess();
+    }
+  }
+};
+
+// Init test
+TEST(VP8VideoTrackEncoder, Initialization)
+{
+  InitParam params[] = {
+    // Failure cases.
+    { false, 640, 480, 0 },      // Trackrate should be larger than 1.
+    { false, 640, 480, -1 },     // Trackrate should be larger than 1.
+    { false, 0, 0, 90000 },      // Height/ width should be larger than 1.
+    { false, 0, 1, 90000 },      // Height/ width should be larger than 1.
+    { false, 1, 0, 90000},       // Height/ width should be larger than 1.
+
+    // Success cases
+    { true, 640, 480, 90000},    // Standard VGA
+    { true, 800, 480, 90000},    // Standard WVGA
+    { true, 960, 540, 90000},    // Standard qHD
+    { true, 1280, 720, 90000}    // Standard HD
+  };
+
+  for (size_t i = 0; i < ArrayLength(params); i++)
+  {
+    TestVP8TrackEncoder encoder;
+    EXPECT_TRUE(encoder.TestInit(params[i]));
+  }
+}
+
+// Get MetaData test
+TEST(VP8VideoTrackEncoder, FetchMetaData)
+{
+  InitParam params[] = {
+    // Success cases
+    { true, 640, 480, 90000},    // Standard VGA
+    { true, 800, 480, 90000},    // Standard WVGA
+    { true, 960, 540, 90000},    // Standard qHD
+    { true, 1280, 720, 90000}    // Standard HD
+  };
+
+  for (size_t i = 0; i < ArrayLength(params); i++)
+  {
+    TestVP8TrackEncoder encoder;
+    EXPECT_TRUE(encoder.TestInit(params[i]));
+
+    nsRefPtr<TrackMetadataBase> meta = encoder.GetMetadata();
+    nsRefPtr<VP8Metadata> vp8Meta(static_cast<VP8Metadata*>(meta.get()));
+
+    // METADATA should be depend on how to initiate encoder.
+    EXPECT_TRUE(vp8Meta->mWidth == params[i].mWidth);
+    EXPECT_TRUE(vp8Meta->mHeight == params[i].mHeight);
+  }
+}
+
+// Encode test
+TEST(VP8VideoTrackEncoder, FrameEncode)
+{
+  // Initiate VP8 encoder
+  TestVP8TrackEncoder encoder;
+  InitParam param = {true, 640, 480, 90000};
+  encoder.TestInit(param);
+
+  // Create YUV images as source.
+  nsTArray<nsRefPtr<Image>> images;
+  YUVBufferGenerator generator;
+  generator.Init(mozilla::gfx::IntSize(640, 480));
+  generator.Generate(images);
+
+  // Put generated YUV frame into video segment.
+  // Duration of each frame is 1 second.
+  VideoSegment segment;
+  for (nsTArray<nsRefPtr<Image>>::size_type i = 0; i < images.Length(); i++)
+  {
+    nsRefPtr<Image> image = images[i];
+    segment.AppendFrame(image.forget(), mozilla::TrackTicks(90000), generator.GetSize());
+  }
+
+  // track change notification.
+  encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, 0, segment);
+
+  // Pull Encoded Data back from encoder.
+  EncodedFrameContainer container;
+  EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
+}
+
+// EOS test
+TEST(VP8VideoTrackEncoder, EncodeComplete)
+{
+  // Initiate VP8 encoder
+  TestVP8TrackEncoder encoder;
+  InitParam param = {true, 640, 480, 90000};
+  encoder.TestInit(param);
+
+  // track end notification.
+  VideoSegment segment;
+  encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, MediaStreamListener::TRACK_EVENT_ENDED, segment);
+
+  // Pull Encoded Data back from encoder. Since we have sent
+  // EOS to encoder, encoder.GetEncodedTrack should return
+  // NS_OK immidiately.
+  EncodedFrameContainer container;
+  EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
+}
--- a/content/media/gtest/moz.build
+++ b/content/media/gtest/moz.build
@@ -6,16 +6,20 @@
 
 LIBRARY_NAME = 'media_gtest'
 
 UNIFIED_SOURCES += [
     'TestAudioCompactor.cpp',
     'TestTrackEncoder.cpp',
 ]
 
+if CONFIG['MOZ_WEBM_ENCODER']:
+    UNIFIED_SOURCES += ['TestVideoTrackEncoder.cpp',
+]
+
 EXPORT_LIBRARY = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/content/media/encoder',
 ]
 
--- a/content/svg/content/src/SVGFEImageElement.cpp
+++ b/content/svg/content/src/SVGFEImageElement.cpp
@@ -3,16 +3,18 @@
  * 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 "mozilla/dom/SVGFEImageElement.h"
 
 #include "mozilla/EventStates.h"
 #include "mozilla/dom/SVGFEImageElementBinding.h"
 #include "mozilla/dom/SVGFilterElement.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsSVGUtils.h"
 #include "nsNetUtil.h"
 #include "imgIContainer.h"
 #include "gfx2DGlue.h"
 
 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEImage)
@@ -206,32 +208,26 @@ SVGFEImageElement::GetPrimitiveDescripti
   GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
              getter_AddRefs(currentRequest));
 
   nsCOMPtr<imgIContainer> imageContainer;
   if (currentRequest) {
     currentRequest->GetImage(getter_AddRefs(imageContainer));
   }
 
-  nsRefPtr<gfxASurface> currentFrame;
+  RefPtr<SourceSurface> image;
   if (imageContainer) {
-    currentFrame =
-      imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
-                               imgIContainer::FLAG_SYNC_DECODE);
+    image = imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
+                                     imgIContainer::FLAG_SYNC_DECODE);
   }
 
-  if (!currentFrame) {
+  if (!image) {
     return FilterPrimitiveDescription(PrimitiveType::Empty);
   }
 
-  gfxPlatform* platform = gfxPlatform::GetPlatform();
-  DrawTarget* dt = platform->ScreenReferenceDrawTarget();
-  RefPtr<SourceSurface> image =
-    platform->GetSourceSurfaceForSurface(dt, currentFrame);
-
   IntSize nativeSize;
   imageContainer->GetWidth(&nativeSize.width);
   imageContainer->GetHeight(&nativeSize.height);
 
   Matrix viewBoxTM =
     SVGContentUtils::GetViewBoxTransform(aFilterSubregion.width, aFilterSubregion.height,
                                          0, 0, nativeSize.width, nativeSize.height,
                                          mPreserveAspectRatio);
--- a/dom/apps/src/AppsUtils.jsm
+++ b/dom/apps/src/AppsUtils.jsm
@@ -4,27 +4,27 @@
 
 "use strict";
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
-Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/osfile.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/WebappOSUtils.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 
-XPCOMUtils.defineLazyServiceGetter(this, "NetworkUtil",
-                                   "@mozilla.org/network/util;1",
-                                   "nsINetUtil");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+  "resource://gre/modules/FileUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "WebappOSUtils",
+  "resource://gre/modules/WebappOSUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
   "resource://gre/modules/NetUtil.jsm");
 
 // Shared code for AppsServiceChild.jsm, Webapps.jsm and Webapps.js
 
 this.EXPORTED_SYMBOLS = ["AppsUtils", "ManifestHelper", "isAbsoluteURI"];
 
@@ -337,17 +337,18 @@ this.AppsUtils = {
     }
     return true;
   },
 
   checkManifestContentType: function
      checkManifestContentType(aInstallOrigin, aWebappOrigin, aContentType) {
     let hadCharset = { };
     let charset = { };
-    let contentType = NetworkUtil.parseContentType(aContentType, charset, hadCharset);
+    let netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
+    let contentType = netutil.parseContentType(aContentType, charset, hadCharset);
     if (aInstallOrigin != aWebappOrigin &&
         contentType != "application/x-web-app-manifest+json") {
       return false;
     }
     return true;
   },
 
   /**
--- a/dom/bluetooth/BluetoothProfileController.h
+++ b/dom/bluetooth/BluetoothProfileController.h
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_bluetooth_bluetoothprofilecontroller_h__
 #define mozilla_dom_bluetooth_bluetoothprofilecontroller_h__
 
 #include "BluetoothUuid.h"
-#include "mozilla/RefPtr.h"
+#include "nsISupportsImpl.h"
 #include "nsAutoPtr.h"
 #include "nsITimer.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 /*
  * Class of Device(CoD): 32-bit unsigned integer
  *
@@ -52,20 +52,22 @@ BEGIN_BLUETOOTH_NAMESPACE
 
 // Pointing device: sub-field of minor device class (Bit 7)
 #define IS_POINTING_DEVICE(cod)      ((GET_MINOR_DEVICE_CLASS(cod) & 0x20) >> 5)
 
 class BluetoothProfileManagerBase;
 class BluetoothReplyRunnable;
 typedef void (*BluetoothProfileControllerCallback)();
 
-class BluetoothProfileController : public RefCounted<BluetoothProfileController>
+class BluetoothProfileController MOZ_FINAL
 {
+  ~BluetoothProfileController();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(BluetoothProfileController)
+  NS_INLINE_DECL_REFCOUNTING(BluetoothProfileController)
   /**
    * @param aConnect:       If it's a connect request, the value should be set
    *                        to true. For disconnect request, set it to false.
    * @param aDeviceAddress: The address of remote device.
    * @param aRunnable:      Once the controller has done, the runnable will be
    *                        replied. When all connection/disconnection attemps
    *                        have failed, an error is fired. In other words,
    *                        reply a success if any attemp successes.
@@ -78,17 +80,16 @@ public:
    *                        aCod or disconnect all connected profiles.
    */
   BluetoothProfileController(bool aConnect,
                              const nsAString& aDeviceAddress,
                              BluetoothReplyRunnable* aRunnable,
                              BluetoothProfileControllerCallback aCallback,
                              uint16_t aServiceUuid,
                              uint32_t aCod = 0);
-  ~BluetoothProfileController();
 
   /**
    * The controller starts connecting/disconnecting profiles one by one
    * according to the order in array mProfiles.
    */
   void StartSession();
 
   /**
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -86,19 +86,49 @@ class mozilla::dom::bluetooth::DroidSock
 {
 public:
   DroidSocketImpl(BluetoothSocket* aConsumer, int aFd)
     : mConsumer(aConsumer)
     , mReadMsgForClientFd(false)
     , mIOLoop(nullptr)
     , mFd(aFd)
     , mShuttingDownOnIOThread(false)
+    , mChannel(0)
+    , mAuth(false)
+    , mEncrypt(false)
   {
   }
 
+  DroidSocketImpl(BluetoothSocket* aConsumer,
+                  int aChannel, bool aAuth, bool aEncrypt)
+    : mConsumer(aConsumer)
+    , mReadMsgForClientFd(false)
+    , mIOLoop(nullptr)
+    , mFd(-1)
+    , mShuttingDownOnIOThread(false)
+    , mChannel(aChannel)
+    , mAuth(aAuth)
+    , mEncrypt(aEncrypt)
+  { }
+
+  DroidSocketImpl(BluetoothSocket* aConsumer, const nsAString& aDeviceAddress,
+                  int aChannel, bool aAuth, bool aEncrypt)
+    : mConsumer(aConsumer)
+    , mReadMsgForClientFd(false)
+    , mIOLoop(nullptr)
+    , mFd(-1)
+    , mShuttingDownOnIOThread(false)
+    , mDeviceAddress(aDeviceAddress)
+    , mChannel(aChannel)
+    , mAuth(aAuth)
+    , mEncrypt(aEncrypt)
+  {
+    MOZ_ASSERT(!mDeviceAddress.IsEmpty());
+  }
+
   ~DroidSocketImpl()
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
   void QueueWriteData(UnixSocketRawData* aData)
   {
     mOutgoingQ.AppendElement(aData);
@@ -129,16 +159,19 @@ public:
     MOZ_ASSERT(!mShuttingDownOnIOThread);
 
     mReadWatcher.StopWatchingFileDescriptor();
     mWriteWatcher.StopWatchingFileDescriptor();
 
     mShuttingDownOnIOThread = true;
   }
 
+  void Connect();
+  void Listen();
+
   void SetUpIO(bool aWrite)
   {
     MOZ_ASSERT(!mIOLoop);
     MOZ_ASSERT(mFd >= 0);
     mIOLoop = MessageLoopForIO::current();
 
     // Set up a read watch
     mIOLoop->WatchFileDescriptor(mFd,
@@ -231,16 +264,21 @@ private:
    * thread. Read/write/close happens on IO thread.
    */
   mozilla::ScopedClose mFd;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
+
+  nsString mDeviceAddress;
+  int mChannel;
+  bool mAuth;
+  bool mEncrypt;
 };
 
 template<class T>
 class DeleteInstanceRunnable : public nsRunnable
 {
 public:
   DeleteInstanceRunnable(T* aInstance)
   : mInstance(aInstance)
@@ -363,44 +401,157 @@ public:
   }
 
 private:
   nsRefPtr<BluetoothSocket> mConsumer;
   DroidSocketImpl* mImpl;
   UnixSocketRawData* mData;
 };
 
-class SocketSetUpIOTask : public Task
+class DroidSocketImplTask : public CancelableTask
 {
-  virtual void Run()
+public:
+  DroidSocketImpl* GetDroidSocketImpl() const
+  {
+    return mDroidSocketImpl;
+  }
+  void Cancel() MOZ_OVERRIDE
+  {
+    mDroidSocketImpl = nullptr;
+  }
+  bool IsCanceled() const
+  {
+    return !mDroidSocketImpl;
+  }
+protected:
+  DroidSocketImplTask(DroidSocketImpl* aDroidSocketImpl)
+  : mDroidSocketImpl(aDroidSocketImpl)
+  {
+    MOZ_ASSERT(mDroidSocketImpl);
+  }
+private:
+  DroidSocketImpl* mDroidSocketImpl;
+};
+
+class SocketConnectTask : public DroidSocketImplTask
+{
+public:
+  SocketConnectTask(DroidSocketImpl* aDroidSocketImpl)
+  : DroidSocketImplTask(aDroidSocketImpl)
+  { }
+
+  void Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread());
-    mImpl->SetUpIO(mWrite);
+    MOZ_ASSERT(!IsCanceled());
+    GetDroidSocketImpl()->Connect();
   }
+};
 
-  DroidSocketImpl* mImpl;
-  bool mWrite;
+class SocketListenTask : public DroidSocketImplTask
+{
 public:
-  SocketSetUpIOTask(DroidSocketImpl* aImpl, bool aWrite)
-  : mImpl(aImpl), mWrite(aWrite) { }
+  SocketListenTask(DroidSocketImpl* aDroidSocketImpl)
+  : DroidSocketImplTask(aDroidSocketImpl)
+  { }
+
+  void Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+    if (!IsCanceled()) {
+      GetDroidSocketImpl()->Listen();
+    }
+  }
 };
 
 class SocketConnectClientFdTask : public Task
 {
   virtual void Run()
   {
     MOZ_ASSERT(!NS_IsMainThread());
     mImpl->ConnectClientFd();
   }
 
   DroidSocketImpl* mImpl;
 public:
   SocketConnectClientFdTask(DroidSocketImpl* aImpl) : mImpl(aImpl) { }
 };
 
+void
+DroidSocketImpl::Connect()
+{
+  MOZ_ASSERT(sBluetoothSocketInterface);
+
+  bt_bdaddr_t remoteBdAddress;
+  StringToBdAddressType(mDeviceAddress, &remoteBdAddress);
+
+  // TODO: uuid as argument
+  int fd = -1;
+  bt_status_t status =
+    sBluetoothSocketInterface->connect(&remoteBdAddress,
+                                       BTSOCK_RFCOMM,
+                                       UUID_OBEX_OBJECT_PUSH,
+                                       mChannel,
+                                       &fd,
+                                       (BTSOCK_FLAG_ENCRYPT * mEncrypt) |
+                                       (BTSOCK_FLAG_AUTH * mAuth));
+  NS_ENSURE_TRUE_VOID(status == BT_STATUS_SUCCESS);
+  NS_ENSURE_TRUE_VOID(fd >= 0);
+
+  mFd = fd;
+
+  MOZ_ASSERT(!mIOLoop);
+  mIOLoop = MessageLoopForIO::current();
+
+  // Set up a read watch
+  mIOLoop->WatchFileDescriptor(mFd.get(),
+                               true,
+                               MessageLoopForIO::WATCH_READ,
+                               &mReadWatcher,
+                               this);
+  // Set up a write watch
+  mIOLoop->WatchFileDescriptor(mFd.get(),
+                               false,
+                               MessageLoopForIO::WATCH_WRITE,
+                               &mWriteWatcher,
+                               this);
+}
+
+void
+DroidSocketImpl::Listen()
+{
+  MOZ_ASSERT(sBluetoothSocketInterface);
+
+  // TODO: uuid and service name as arguments
+
+  int fd = -1;
+  bt_status_t status =
+    sBluetoothSocketInterface->listen(BTSOCK_RFCOMM,
+                                      "OBEX Object Push",
+                                      UUID_OBEX_OBJECT_PUSH,
+                                      mChannel,
+                                      &fd,
+                                      (BTSOCK_FLAG_ENCRYPT * mEncrypt) |
+                                      (BTSOCK_FLAG_AUTH * mAuth));
+  NS_ENSURE_TRUE_VOID(status == BT_STATUS_SUCCESS);
+  NS_ENSURE_TRUE_VOID(fd >= 0);
+
+  mFd = fd;
+
+  MOZ_ASSERT(!mIOLoop);
+  mIOLoop = MessageLoopForIO::current();
+
+  // Set up a read watch
+  mIOLoop->WatchFileDescriptor(mFd.get(),
+                               true,
+                               MessageLoopForIO::WATCH_READ,
+                               &mReadWatcher,
+                               this);
+}
+
 ssize_t
 DroidSocketImpl::ReadMsg(int aFd, void *aBuffer, size_t aLength)
 {
   ssize_t ret;
   struct msghdr msg;
   struct iovec iv;
   struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
 
@@ -575,75 +726,40 @@ BluetoothSocket::CloseDroidSocket()
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                    new ShutdownSocketTask(mImpl));
   mImpl = nullptr;
 
   OnDisconnect();
 }
 
 bool
-BluetoothSocket::CreateDroidSocket(int aFd)
+BluetoothSocket::Connect(const nsAString& aDeviceAddress, int aChannel)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_FALSE(mImpl, false);
 
-  mImpl = new DroidSocketImpl(this, aFd);
+  mIsServer = false;
+  mImpl = new DroidSocketImpl(this, aDeviceAddress, aChannel, mAuth, mEncrypt);
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new SocketSetUpIOTask(mImpl, !mIsServer));
+                                   new SocketConnectTask(mImpl));
 
   return true;
 }
 
 bool
-BluetoothSocket::Connect(const nsAString& aDeviceAddress, int aChannel)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!aDeviceAddress.IsEmpty());
-  NS_ENSURE_TRUE(sBluetoothSocketInterface, false);
-
-  bt_bdaddr_t remoteBdAddress;
-  StringToBdAddressType(aDeviceAddress, &remoteBdAddress);
-
-  // TODO: uuid as argument
-  int fd;
-  NS_ENSURE_TRUE(BT_STATUS_SUCCESS ==
-    sBluetoothSocketInterface->connect(&remoteBdAddress,
-                                       BTSOCK_RFCOMM,
-                                       UUID_OBEX_OBJECT_PUSH,
-                                       aChannel,
-                                       &fd,
-                                       (mAuth << 1) | mEncrypt),
-    false);
-  NS_ENSURE_TRUE(fd >= 0, false);
-
-  mIsServer = false;
-  return CreateDroidSocket(fd);
-}
-
-bool
 BluetoothSocket::Listen(int aChannel)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NS_ENSURE_TRUE(sBluetoothSocketInterface, false);
-
-  // TODO: uuid and service name as arguments
-  nsAutoCString serviceName("OBEX Object Push");
-  int fd;
-  NS_ENSURE_TRUE(BT_STATUS_SUCCESS ==
-    sBluetoothSocketInterface->listen(BTSOCK_RFCOMM,
-                                      serviceName.get(),
-                                      UUID_OBEX_OBJECT_PUSH,
-                                      aChannel,
-                                      &fd,
-                                      (mAuth << 1) | mEncrypt),
-    false);
-  NS_ENSURE_TRUE(fd >= 0, false);
+  NS_ENSURE_FALSE(mImpl, false);
 
   mIsServer = true;
-  return CreateDroidSocket(fd);
+  mImpl = new DroidSocketImpl(this, aChannel, mAuth, mEncrypt);
+  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
+                                   new SocketListenTask(mImpl));
+  return true;
 }
 
 bool
 BluetoothSocket::SendDroidSocketData(UnixSocketRawData* aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE(mImpl, false);
 
--- a/dom/bluetooth/bluedroid/BluetoothSocket.h
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.h
@@ -72,15 +72,14 @@ private:
   BluetoothSocketObserver* mObserver;
   DroidSocketImpl* mImpl;
   nsString mDeviceAddress;
   bool mAuth;
   bool mEncrypt;
   bool mIsServer;
   int mReceivedSocketInfoLength;
 
-  bool CreateDroidSocket(int aFd);
   bool ReceiveSocketInfo(nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage);
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/browser-element/BrowserElementPanning.js
+++ b/dom/browser-element/BrowserElementPanning.js
@@ -24,16 +24,37 @@ const ContentPanning = {
   // Are we listening to touch or mouse events?
   watchedEventsType: '',
 
   // Are mouse events being delivered to this content along with touch
   // events, in violation of spec?
   hybridEvents: false,
 
   init: function cp_init() {
+    // If APZ is enabled, we do active element handling in C++
+    // (see widget/xpwidgets/ActiveElementManager.h), and panning
+    // itself in APZ, so we don't need to handle any touch events here.
+    if (docShell.asyncPanZoomEnabled === false) {
+      this._setupListenersForPanning();
+    }
+
+    addEventListener("unload",
+		     this._unloadHandler.bind(this),
+		     /* useCapture = */ false,
+		     /* wantsUntrusted = */ false);
+
+    addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
+    addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
+    addEventListener("visibilitychange", this._handleVisibilityChange.bind(this));
+    kObservedEvents.forEach((topic) => {
+      Services.obs.addObserver(this, topic, false);
+    });
+  },
+
+  _setupListenersForPanning: function cp_setupListenersForPanning() {
     var events;
     try {
       content.document.createEvent('TouchEvent');
       events = ['touchstart', 'touchend', 'touchmove'];
       this.watchedEventsType = 'touch';
 #ifdef MOZ_WIDGET_GONK
       // The gonk widget backend does not deliver mouse events per
       // spec.  Third-party content isn't exposed to this behavior,
@@ -55,28 +76,16 @@ const ContentPanning = {
 
     events.forEach(function(type) {
       // Using the system group for mouse/touch events to avoid
       // missing events if .stopPropagation() has been called.
       els.addSystemEventListener(global, type,
                                  this.handleEvent.bind(this),
                                  /* useCapture = */ false);
     }.bind(this));
-
-    addEventListener("unload",
-		     this._unloadHandler.bind(this),
-		     /* useCapture = */ false,
-		     /* wantsUntrusted = */ false);
-
-    addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
-    addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
-    addEventListener("visibilitychange", this._handleVisibilityChange.bind(this));
-    kObservedEvents.forEach((topic) => {
-      Services.obs.addObserver(this, topic, false);
-    });
   },
 
   handleEvent: function cp_handleEvent(evt) {
     // Ignore events targeting a <iframe mozbrowser> since those will be
     // handle by the BrowserElementPanning.js instance of it.
     if (evt.target instanceof Ci.nsIMozBrowserFrame) {
       return;
     }
@@ -190,18 +199,17 @@ const ContentPanning = {
     }
 
     this.position.set(screenX, screenY);
     KineticPanning.reset();
     KineticPanning.record(new Point(0, 0), evt.timeStamp);
 
     // We prevent start events to avoid sending a focus event at the end of this
     // touch series. See bug 889717.
-    if (docShell.asyncPanZoomEnabled === false &&
-        (this.panning || this.preventNextClick)) {
+    if ((this.panning || this.preventNextClick)) {
       evt.preventDefault();
     }
   },
 
   onTouchEnd: function cp_onTouchEnd(evt) {
     let touch = null;
     if (!this.dragging ||
         (this.watchedEventsType == 'touch' &&
@@ -230,17 +238,17 @@ const ContentPanning = {
     }
 
     if (this.target && click && (this.panning || this.preventNextClick)) {
       if (this.hybridEvents) {
         let target = this.target;
         let view = target.ownerDocument ? target.ownerDocument.defaultView
                                         : target;
         view.addEventListener('click', this, true, true);
-      } else if (docShell.asyncPanZoomEnabled === false) {
+      } else {
         // We prevent end events to avoid sending a focus event. See bug 889717.
         evt.preventDefault();
       }
     } else if (this.target && click && !this.panning) {
       this.notify(this._activationTimer);
     }
 
     this._finishPanning();
@@ -279,28 +287,25 @@ const ContentPanning = {
       this._resetActive();
     }
 
     // There's no possibility of us panning anything.
     if (!this.scrollCallback) {
       return;
     }
 
-    // If the application is not managed by the AsyncPanZoomController, then
-    // scroll manually.
-    if (docShell.asyncPanZoomEnabled === false) {
-      this.scrollCallback(delta.scale(-1));
-    }
+    // Scroll manually.
+    this.scrollCallback(delta.scale(-1));
 
     if (!this.panning && isPan) {
       this.panning = true;
       this._activationTimer.cancel();
     }
 
-    if (this.panning && docShell.asyncPanZoomEnabled === false) {
+    if (this.panning) {
       // Only do this when we're actually executing a pan gesture.
       // Otherwise synthetic mouse events will be canceled.
       evt.stopPropagation();
       evt.preventDefault();
     }
   },
 
   // nsITimerCallback
@@ -587,19 +592,18 @@ const ContentPanning = {
     return (showing > 0.9 && (ratioW > 0.9 || ratioH > 0.9)); 
   },
 
   _finishPanning: function() {
     this.dragging = false;
     delete this.primaryPointerId;
     this._activationTimer.cancel();
 
-    // If there is a scroll action but the application is not managed by
-    // the AsyncPanZoom controller, let's do a manual kinetic panning action.
-    if (this.panning && docShell.asyncPanZoomEnabled === false) {
+    // If there is a scroll action, let's do a manual kinetic panning action.
+    if (this.panning) {
       KineticPanning.start(this);
     }
   },
 
   _unloadHandler: function() {
     kObservedEvents.forEach((topic) => {
       Services.obs.removeObserver(this, topic);
     });
--- a/dom/camera/CameraControlImpl.cpp
+++ b/dom/camera/CameraControlImpl.cpp
@@ -279,22 +279,25 @@ CameraControlImpl::OnError(CameraControl
     "set-picture-size-failed",
     "set-thumbnail-size-failed",
     "unknown"
   };
   const char* context[] = {
     "StartCamera",
     "StopCamera",
     "AutoFocus",
+    "StartFaceDetection",
+    "StopFaceDetection",
     "TakePicture",
     "StartRecording",
     "StopRecording",
     "SetConfiguration",
     "StartPreview",
     "StopPreview",
+    "ResumeContinuousFocus",
     "Unspecified"
   };
   if (static_cast<unsigned int>(aError) < sizeof(error) / sizeof(error[0]) &&
     static_cast<unsigned int>(aContext) < sizeof(context) / sizeof(context[0])) {
     DOM_CAMERA_LOGW("CameraControlImpl::OnError : aContext='%s' (%u), aError='%s' (%u)\n",
       context[aContext], aContext, error[aError], aError);
   } else {
     DOM_CAMERA_LOGE("CameraControlImpl::OnError : aContext=%u, aError=%d\n",
@@ -409,40 +412,35 @@ CameraControlImpl::SetConfiguration(cons
     Configuration mConfig;
   };
 
   return mCameraThread->Dispatch(
     new Message(this, CameraControlListener::kInSetConfiguration, aConfig), NS_DISPATCH_NORMAL);
 }
 
 nsresult
-CameraControlImpl::AutoFocus(bool aCancelExistingCall)
+CameraControlImpl::AutoFocus()
 {
   class Message : public ControlMessage
   {
   public:
     Message(CameraControlImpl* aCameraControl,
-            CameraControlListener::CameraErrorContext aContext,
-            bool aCancelExistingCall)
+            CameraControlListener::CameraErrorContext aContext)
       : ControlMessage(aCameraControl, aContext)
-      , mCancelExistingCall(aCancelExistingCall)
     { }
 
     nsresult
     RunImpl() MOZ_OVERRIDE
     {
-      return mCameraControl->AutoFocusImpl(mCancelExistingCall);
+      return mCameraControl->AutoFocusImpl();
     }
-
-  protected:
-    bool mCancelExistingCall;
   };
 
   return mCameraThread->Dispatch(
-    new Message(this, CameraControlListener::kInAutoFocus, aCancelExistingCall), NS_DISPATCH_NORMAL);
+    new Message(this, CameraControlListener::kInAutoFocus), NS_DISPATCH_NORMAL);
 }
 
 nsresult
 CameraControlImpl::StartFaceDetection()
 {
   class Message : public ControlMessage
   {
   public:
@@ -607,16 +605,38 @@ CameraControlImpl::StopPreview()
     }
   };
 
   return mCameraThread->Dispatch(
     new Message(this, CameraControlListener::kInStopPreview), NS_DISPATCH_NORMAL);
 }
 
 nsresult
+CameraControlImpl::ResumeContinuousFocus()
+{
+  class Message : public ControlMessage
+  {
+  public:
+    Message(CameraControlImpl* aCameraControl,
+            CameraControlListener::CameraErrorContext aContext)
+      : ControlMessage(aCameraControl, aContext)
+    { }
+
+    nsresult
+    RunImpl() MOZ_OVERRIDE
+    {
+      return mCameraControl->ResumeContinuousFocusImpl();
+    }
+  };
+
+  return mCameraThread->Dispatch(
+    new Message(this, CameraControlListener::kInResumeContinuousFocus), NS_DISPATCH_NORMAL);
+}
+
+nsresult
 CameraControlImpl::Stop()
 {
   class Message : public ControlMessage
   {
   public:
     Message(CameraControlImpl* aCameraControl,
             CameraControlListener::CameraErrorContext aContext)
       : ControlMessage(aCameraControl, aContext)
--- a/dom/camera/CameraControlImpl.h
+++ b/dom/camera/CameraControlImpl.h
@@ -14,18 +14,16 @@
 #include "AutoRwLock.h"
 #include "nsIDOMDeviceStorage.h"
 #include "ICameraControl.h"
 #include "CameraCommon.h"
 #include "DeviceStorage.h"
 #include "DeviceStorageFileDescriptor.h"
 #include "CameraControlListener.h"
 
-class DeviceStorageFileDescriptor;
-
 namespace mozilla {
 
 namespace layers {
   class Image;
 }
 
 class RecorderProfileManager;
 
@@ -37,23 +35,24 @@ public:
   virtual void RemoveListener(CameraControlListener* aListener) MOZ_OVERRIDE;
 
   virtual nsresult Start(const Configuration* aConfig = nullptr) MOZ_OVERRIDE;
   virtual nsresult Stop() MOZ_OVERRIDE;
 
   virtual nsresult SetConfiguration(const Configuration& aConfig) MOZ_OVERRIDE;
   virtual nsresult StartPreview() MOZ_OVERRIDE;
   virtual nsresult StopPreview() MOZ_OVERRIDE;
-  virtual nsresult AutoFocus(bool aCancelExistingCall) MOZ_OVERRIDE;
+  virtual nsresult AutoFocus() MOZ_OVERRIDE;
   virtual nsresult StartFaceDetection() MOZ_OVERRIDE;
   virtual nsresult StopFaceDetection() MOZ_OVERRIDE;
   virtual nsresult TakePicture() MOZ_OVERRIDE;
   virtual nsresult StartRecording(DeviceStorageFileDescriptor* aFileDescriptor,
                                   const StartRecordingOptions* aOptions) MOZ_OVERRIDE;
   virtual nsresult StopRecording() MOZ_OVERRIDE;
+  virtual nsresult ResumeContinuousFocus() MOZ_OVERRIDE;
 
   already_AddRefed<RecorderProfileManager> GetRecorderProfileManager();
   uint32_t GetCameraId() { return mCameraId; }
 
   virtual void Shutdown() MOZ_OVERRIDE;
 
   // Event handlers called directly from outside this class.
   void OnShutter();
@@ -97,23 +96,24 @@ protected:
   class ControlMessage;
   class ListenerMessage;
 
   virtual nsresult StartImpl(const Configuration* aConfig = nullptr) = 0;
   virtual nsresult StopImpl() = 0;
   virtual nsresult SetConfigurationImpl(const Configuration& aConfig) = 0;
   virtual nsresult StartPreviewImpl() = 0;
   virtual nsresult StopPreviewImpl() = 0;
-  virtual nsresult AutoFocusImpl(bool aCancelExistingCall) = 0;
+  virtual nsresult AutoFocusImpl() = 0;
   virtual nsresult StartFaceDetectionImpl() = 0;
   virtual nsresult StopFaceDetectionImpl() = 0;
   virtual nsresult TakePictureImpl() = 0;
   virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
                                       const StartRecordingOptions* aOptions) = 0;
   virtual nsresult StopRecordingImpl() = 0;
+  virtual nsresult ResumeContinuousFocusImpl() = 0;
   virtual nsresult PushParametersImpl() = 0;
   virtual nsresult PullParametersImpl() = 0;
   virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() = 0;
 
   void OnShutterInternal();
   void OnClosedInternal();
 
   uint32_t mCameraId;
--- a/dom/camera/CameraControlListener.h
+++ b/dom/camera/CameraControlListener.h
@@ -90,16 +90,17 @@ public:
     kInStartFaceDetection,
     kInStopFaceDetection,
     kInTakePicture,
     kInStartRecording,
     kInStopRecording,
     kInSetConfiguration,
     kInStartPreview,
     kInStopPreview,
+    kInResumeContinuousFocus,
     kInUnspecified
   };
   enum CameraError
   {
     kErrorApiFailed,
     kErrorInitFailed,
     kErrorInvalidConfiguration,
     kErrorServiceFailed,
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -839,43 +839,65 @@ nsDOMCameraControl::SetConfiguration(con
   mSetConfigurationOnErrorCb = nullptr;
   if (aOnError.WasPassed()) {
     mSetConfigurationOnErrorCb = &aOnError.Value();
   }
 
   aRv = mCameraControl->SetConfiguration(config);
 }
 
+class ImmediateErrorCallback : public nsRunnable
+{
+public:
+  ImmediateErrorCallback(CameraErrorCallback* aCallback, const nsAString& aMessage)
+    : mCallback(aCallback)
+    , mMessage(aMessage)
+  { }
+  
+  NS_IMETHODIMP
+  Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    ErrorResult ignored;
+    mCallback->Call(mMessage, ignored);
+    return NS_OK;
+  }
+
+protected:
+  nsRefPtr<CameraErrorCallback> mCallback;
+  nsString mMessage;
+};
+
+
 void
 nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback& aOnSuccess,
                               const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
                               ErrorResult& aRv)
 {
   MOZ_ASSERT(mCameraControl);
 
-  nsRefPtr<CameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb.forget();
-  bool cancel = false;
+  nsRefPtr<CameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb;
   if (cb) {
-    // we have a callback, which means we're already in the process of
-    // auto-focusing--cancel the old callback
-    nsRefPtr<CameraErrorCallback> ecb = mAutoFocusOnErrorCb.forget();
-    if (ecb) {
-      ErrorResult ignored;
-      ecb->Call(NS_LITERAL_STRING("Interrupted"), ignored);
+    if (aOnError.WasPassed()) {
+      // There is already a call to AutoFocus() in progress, abort this new one
+      // and invoke the error callback (if one was passed in).
+      NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
+                              NS_LITERAL_STRING("AutoFocusAlreadyInProgress")));
     }
-    cancel = true;
+    aRv = NS_ERROR_FAILURE;
+    return;
   }
 
   mAutoFocusOnSuccessCb = &aOnSuccess;
   mAutoFocusOnErrorCb = nullptr;
   if (aOnError.WasPassed()) {
     mAutoFocusOnErrorCb = &aOnError.Value();
   }
 
-  aRv = mCameraControl->AutoFocus(cancel);
+  aRv = mCameraControl->AutoFocus();
 }
 
 void
 nsDOMCameraControl::StartFaceDetection(ErrorResult& aRv)
 {
   MOZ_ASSERT(mCameraControl);
   aRv = mCameraControl->StartFaceDetection();
 }
@@ -892,21 +914,21 @@ nsDOMCameraControl::TakePicture(const Ca
                                 CameraTakePictureCallback& aOnSuccess,
                                 const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
                                 ErrorResult& aRv)
 {
   MOZ_ASSERT(mCameraControl);
 
   nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
   if (cb) {
-    // There is already a call to TakePicture() in progress, abort this one and
-    //  invoke the error callback (if one was passed in).
     if (aOnError.WasPassed()) {
-      ErrorResult ignored;
-      aOnError.Value().Call(NS_LITERAL_STRING("TakePictureAlreadyInProgress"), ignored);
+      // There is already a call to TakePicture() in progress, abort this new
+      // one and invoke the error callback (if one was passed in).
+      NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
+                              NS_LITERAL_STRING("TakePictureAlreadyInProgress")));
     }
     aRv = NS_ERROR_FAILURE;
     return;
   }
 
   {
     ICameraControlParameterSetAutoEnter batch(mCameraControl);
 
@@ -954,16 +976,23 @@ nsDOMCameraControl::ReleaseHardware(cons
   if (aOnError.WasPassed()) {
     mReleaseOnErrorCb = &aOnError.Value();
   }
 
   aRv = mCameraControl->Stop();
 }
 
 void
+nsDOMCameraControl::ResumeContinuousFocus(ErrorResult& aRv)
+{
+  MOZ_ASSERT(mCameraControl);
+  aRv = mCameraControl->ResumeContinuousFocus();
+}
+
+void
 nsDOMCameraControl::Shutdown()
 {
   DOM_CAMERA_LOGI("%s:%d\n", __func__, __LINE__);
   MOZ_ASSERT(mCameraControl);
 
   // Remove any pending solicited event handlers; these
   // reference our window object, which in turn references
   // us. If we don't remove them, we can leak DOM objects.
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -123,16 +123,17 @@ public:
                       dom::CameraStartRecordingCallback& aOnSuccess,
                       const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
                       ErrorResult& aRv);
   void StopRecording(ErrorResult& aRv);
   void ResumePreview(ErrorResult& aRv);
   void ReleaseHardware(const dom::Optional<dom::OwningNonNull<dom::CameraReleaseCallback> >& aOnSuccess,
                        const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
                        ErrorResult& aRv);
+  void ResumeContinuousFocus(ErrorResult& aRv);
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsDOMCameraControl();
 
   class DOMCameraConfiguration MOZ_FINAL : public dom::CameraConfiguration
   {
--- a/dom/camera/DOMCameraManager.cpp
+++ b/dom/camera/DOMCameraManager.cpp
@@ -4,17 +4,17 @@
 
 #include "DOMCameraManager.h"
 #include "nsDebug.h"
 #include "jsapi.h"
 #include "Navigator.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/Services.h"
 #include "nsContentPermissionHelper.h"
-#include "nsObserverService.h"
+#include "nsIObserverService.h"
 #include "nsIPermissionManager.h"
 #include "DOMCameraControl.h"
 #include "nsDOMClassInfo.h"
 #include "CameraCommon.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/CameraManagerBinding.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/TabChild.h"
--- a/dom/camera/FallbackCameraControl.cpp
+++ b/dom/camera/FallbackCameraControl.cpp
@@ -53,26 +53,27 @@ public:
   virtual nsresult Get(uint32_t aKey, nsTArray<double>& aValues) MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
 
   nsresult PushParameters() { return NS_ERROR_FAILURE; }
   nsresult PullParameters() { return NS_ERROR_FAILURE; }
 
 protected:
   ~FallbackCameraControl();
 
-  virtual nsresult StartPreviewImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult StopPreviewImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult AutoFocusImpl(bool aCancelExistingCall) { return NS_ERROR_FAILURE; }
-  virtual nsresult StartFaceDetectionImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult StopFaceDetectionImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult TakePictureImpl() { return NS_ERROR_FAILURE; }
+  virtual nsresult StartPreviewImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult StopPreviewImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult AutoFocusImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult StartFaceDetectionImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult StopFaceDetectionImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult TakePictureImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
   virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
-                                      const StartRecordingOptions* aOptions = nullptr)
+                                      const StartRecordingOptions* aOptions = nullptr) MOZ_OVERRIDE
                                         { return NS_ERROR_FAILURE; }
-  virtual nsresult StopRecordingImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult PushParametersImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult PullParametersImpl() { return NS_ERROR_FAILURE; }
-  virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() { return nullptr; }
+  virtual nsresult StopRecordingImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult PushParametersImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult PullParametersImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE { return nullptr; }
 
 private:
   FallbackCameraControl(const FallbackCameraControl&) MOZ_DELETE;
   FallbackCameraControl& operator=(const FallbackCameraControl&) MOZ_DELETE;
 };
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -559,25 +559,22 @@ nsGonkCameraControl::PausePreview()
   DOM_CAMERA_LOGI("Pausing preview (this=%p)\n", this);
 
   mCameraHw->StopPreview();
   OnPreviewStateChange(CameraControlListener::kPreviewPaused);
   return NS_OK;
 }
 
 nsresult
-nsGonkCameraControl::AutoFocusImpl(bool aCancelExistingCall)
+nsGonkCameraControl::AutoFocusImpl()
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
   RETURN_IF_NO_CAMERA_HW();
-  if (aCancelExistingCall) {
-    if (mCameraHw.get()) {
-      mCameraHw->CancelAutoFocus();
-    }
-  }
+
+  DOM_CAMERA_LOGI("Starting auto focus\n");
 
   if (mCameraHw->AutoFocus() != OK) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
@@ -1040,16 +1037,33 @@ nsGonkCameraControl::StopRecordingImpl()
   if (mAutoFlashModeOverridden) {
     SetAndPush(CAMERA_PARAM_FLASHMODE, NS_LITERAL_STRING("auto"));
   }
 
   // notify DeviceStorage that the new video file is closed and ready
   return NS_DispatchToMainThread(new RecordingComplete(mVideoFile), NS_DISPATCH_NORMAL);
 }
 
+nsresult
+nsGonkCameraControl::ResumeContinuousFocusImpl()
+{
+  MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
+  RETURN_IF_NO_CAMERA_HW();
+
+  DOM_CAMERA_LOGI("Resuming continuous autofocus\n");
+
+  // see
+  // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_PICTURE
+  if (NS_WARN_IF(mCameraHw->CancelAutoFocus() != OK)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
 void
 nsGonkCameraControl::OnAutoFocusComplete(bool aSuccess)
 {
   class AutoFocusComplete : public nsRunnable
   {
   public:
     AutoFocusComplete(nsGonkCameraControl* aCameraControl, bool aSuccess)
       : mCameraControl(aCameraControl)
--- a/dom/camera/GonkCameraControl.h
+++ b/dom/camera/GonkCameraControl.h
@@ -100,23 +100,24 @@ protected:
   nsresult SetConfigurationInternal(const Configuration& aConfig);
   nsresult SetPictureConfiguration(const Configuration& aConfig);
   nsresult SetVideoConfiguration(const Configuration& aConfig);
 
   template<class T> nsresult SetAndPush(uint32_t aKey, const T& aValue);
 
   virtual nsresult StartPreviewImpl() MOZ_OVERRIDE;
   virtual nsresult StopPreviewImpl() MOZ_OVERRIDE;
-  virtual nsresult AutoFocusImpl(bool aCancelExistingCall) MOZ_OVERRIDE;
+  virtual nsresult AutoFocusImpl() MOZ_OVERRIDE;
   virtual nsresult StartFaceDetectionImpl() MOZ_OVERRIDE;
   virtual nsresult StopFaceDetectionImpl() MOZ_OVERRIDE;
   virtual nsresult TakePictureImpl() MOZ_OVERRIDE;
   virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
                                       const StartRecordingOptions* aOptions = nullptr) MOZ_OVERRIDE;
   virtual nsresult StopRecordingImpl() MOZ_OVERRIDE;
+  virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE;
   virtual nsresult PushParametersImpl() MOZ_OVERRIDE;
   virtual nsresult PullParametersImpl() MOZ_OVERRIDE;
   virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE;
   already_AddRefed<GonkRecorderProfileManager> GetGonkRecorderProfileManager();
 
   nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes,
                           int64_t aMaxVideoLengthMs);
   nsresult SetupRecordingFlash(bool aAutoEnableLowLightTorch);
--- a/dom/camera/GonkCameraHwMgr.cpp
+++ b/dom/camera/GonkCameraHwMgr.cpp
@@ -287,21 +287,21 @@ GonkCameraHardware::GetSensorOrientation
 
 int
 GonkCameraHardware::AutoFocus()
 {
   DOM_CAMERA_LOGI("%s\n", __func__);
   return mCamera->autoFocus();
 }
 
-void
+int
 GonkCameraHardware::CancelAutoFocus()
 {
   DOM_CAMERA_LOGI("%s\n", __func__);
-  mCamera->cancelAutoFocus();
+  return mCamera->cancelAutoFocus();
 }
 
 int
 GonkCameraHardware::StartFaceDetection()
 {
   DOM_CAMERA_LOGI("%s\n", __func__);
   int rv = INVALID_OPERATION;
 
--- a/dom/camera/GonkCameraHwMgr.h
+++ b/dom/camera/GonkCameraHwMgr.h
@@ -73,17 +73,17 @@ public:
    */
   enum {
     RAW_SENSOR_ORIENTATION,
     OFFSET_SENSOR_ORIENTATION
   };
   virtual int      GetSensorOrientation(uint32_t aType = RAW_SENSOR_ORIENTATION);
 
   virtual int      AutoFocus();
-  virtual void     CancelAutoFocus();
+  virtual int      CancelAutoFocus();
   virtual int      StartFaceDetection();
   virtual int      StopFaceDetection();
   virtual int      TakePicture();
   virtual void     CancelTakePicture();
   virtual int      StartPreview();
   virtual void     StopPreview();
   virtual int      PushParameters(const mozilla::GonkCameraParameters& aParams);
   virtual int      PushParameters(const CameraParameters& aParams);
--- a/dom/camera/ICameraControl.h
+++ b/dom/camera/ICameraControl.h
@@ -5,17 +5,17 @@
 #ifndef DOM_CAMERA_ICAMERACONTROL_H
 #define DOM_CAMERA_ICAMERACONTROL_H
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "nsISupportsImpl.h"
 
-class DeviceStorageFileDescriptor;
+struct DeviceStorageFileDescriptor;
 
 class nsIFile;
 
 namespace mozilla {
 
 class CameraControlListener;
 class RecorderProfileManager;
 
@@ -147,23 +147,24 @@ public:
 
   virtual nsresult SetConfiguration(const Configuration& aConfig) = 0;
 
   virtual void AddListener(CameraControlListener* aListener) = 0;
   virtual void RemoveListener(CameraControlListener* aListener) = 0;
 
   virtual nsresult StartPreview() = 0;
   virtual nsresult StopPreview() = 0;
-  virtual nsresult AutoFocus(bool aCancelExistingCall) = 0;
+  virtual nsresult AutoFocus() = 0;
   virtual nsresult TakePicture() = 0;
   virtual nsresult StartRecording(DeviceStorageFileDescriptor *aFileDescriptor,
                                   const StartRecordingOptions* aOptions = nullptr) = 0;
   virtual nsresult StopRecording() = 0;
   virtual nsresult StartFaceDetection() = 0;
   virtual nsresult StopFaceDetection() = 0;
+  virtual nsresult ResumeContinuousFocus() = 0;
 
   virtual nsresult Set(uint32_t aKey, const nsAString& aValue) = 0;
   virtual nsresult Get(uint32_t aKey, nsAString& aValue) = 0;
   virtual nsresult Set(uint32_t aKey, double aValue) = 0;
   virtual nsresult Get(uint32_t aKey, double& aValue) = 0;
   virtual nsresult Set(uint32_t aKey, int32_t aValue) = 0;
   virtual nsresult Get(uint32_t aKey, int32_t& aValue) = 0;
   virtual nsresult Set(uint32_t aKey, int64_t aValue) = 0;
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -316,23 +316,17 @@ private:
   bool mIsWatchingFile;
   bool mAllowedToWatchFile;
 
   nsresult Notify(const char* aReason, class DeviceStorageFile* aFile);
 
   friend class WatchFileEvent;
   friend class DeviceStorageRequest;
 
-  class VolumeNameCache : public mozilla::RefCounted<VolumeNameCache>
-  {
-  public:
-    MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeNameCache)
-    nsTArray<nsString>  mVolumeNames;
-  };
-  static mozilla::StaticRefPtr<VolumeNameCache> sVolumeNameCache;
+  static mozilla::StaticAutoPtr<nsTArray<nsString>> sVolumeNameCache;
 
 #ifdef MOZ_WIDGET_GONK
   nsString mLastStatus;
   void DispatchMountChangeEvent(nsAString& aVolumeStatus);
 #endif
 
   // nsIDOMDeviceStorage.type
   enum {
--- a/dom/devicestorage/DeviceStorageFileDescriptor.h
+++ b/dom/devicestorage/DeviceStorageFileDescriptor.h
@@ -4,18 +4,16 @@
  * 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 DeviceStorageFileDescriptor_h
 #define DeviceStorageFileDescriptor_h
 
 #include "mozilla/ipc/FileDescriptor.h"
 
-class DeviceStorageFileDescriptor MOZ_FINAL
-  : public mozilla::RefCounted<DeviceStorageFileDescriptor>
+struct DeviceStorageFileDescriptor MOZ_FINAL
 {
-public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(DeviceStorageFileDescriptor)
+  NS_INLINE_DECL_REFCOUNTING(DeviceStorageFileDescriptor)
   nsRefPtr<DeviceStorageFile> mDSFile;
   mozilla::ipc::FileDescriptor mFileDescriptor;
 };
 
 #endif
--- a/dom/devicestorage/DeviceStorageRequestChild.h
+++ b/dom/devicestorage/DeviceStorageRequestChild.h
@@ -4,17 +4,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_devicestorage_DeviceStorageRequestChild_h
 #define mozilla_dom_devicestorage_DeviceStorageRequestChild_h
 
 #include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
 
 class DeviceStorageFile;
-class DeviceStorageFileDescriptor;
+struct DeviceStorageFileDescriptor;
 
 namespace mozilla {
 namespace dom {
 
 class DOMRequest;
 
 namespace devicestorage {
 
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -110,25 +110,26 @@ DeviceStorageUsedSpaceCache::CreateOrGet
 
   MOZ_ASSERT(NS_IsMainThread());
 
   sDeviceStorageUsedSpaceCache = new DeviceStorageUsedSpaceCache();
   ClearOnShutdown(&sDeviceStorageUsedSpaceCache);
   return sDeviceStorageUsedSpaceCache;
 }
 
-TemporaryRef<DeviceStorageUsedSpaceCache::CacheEntry>
+already_AddRefed<DeviceStorageUsedSpaceCache::CacheEntry>
 DeviceStorageUsedSpaceCache::GetCacheEntry(const nsAString& aStorageName)
 {
-  nsTArray<RefPtr<CacheEntry> >::size_type numEntries = mCacheEntries.Length();
-  nsTArray<RefPtr<CacheEntry> >::index_type i;
+  nsTArray<nsRefPtr<CacheEntry>>::size_type numEntries = mCacheEntries.Length();
+  nsTArray<nsRefPtr<CacheEntry>>::index_type i;
   for (i = 0; i < numEntries; i++) {
-    RefPtr<CacheEntry> cacheEntry = mCacheEntries[i];
+    nsRefPtr<CacheEntry>& cacheEntry = mCacheEntries[i];
     if (cacheEntry->mStorageName.Equals(aStorageName)) {
-      return cacheEntry;
+      nsRefPtr<CacheEntry> addRefedCacheEntry = cacheEntry;
+      return addRefedCacheEntry.forget();
     }
   }
   return nullptr;
 }
 
 static int64_t
 GetFreeBytes(const nsAString& aStorageName)
 {
@@ -144,17 +145,17 @@ GetFreeBytes(const nsAString& aStorageNa
 
 nsresult
 DeviceStorageUsedSpaceCache::AccumUsedSizes(const nsAString& aStorageName,
                                             uint64_t* aPicturesSoFar,
                                             uint64_t* aVideosSoFar,
                                             uint64_t* aMusicSoFar,
                                             uint64_t* aTotalSoFar)
 {
-  RefPtr<CacheEntry> cacheEntry = GetCacheEntry(aStorageName);
+  nsRefPtr<CacheEntry> cacheEntry = GetCacheEntry(aStorageName);
   if (!cacheEntry || cacheEntry->mDirty) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   int64_t freeBytes = GetFreeBytes(cacheEntry->mStorageName);
   if (freeBytes != cacheEntry->mFreeBytes) {
     // Free space changed, so our cached results are no longer valid.
     return NS_ERROR_NOT_AVAILABLE;
   }
@@ -169,35 +170,35 @@ DeviceStorageUsedSpaceCache::AccumUsedSi
 
 void
 DeviceStorageUsedSpaceCache::SetUsedSizes(const nsAString& aStorageName,
                                           uint64_t aPictureSize,
                                           uint64_t aVideosSize,
                                           uint64_t aMusicSize,
                                           uint64_t aTotalUsedSize)
 {
-  RefPtr<CacheEntry> cacheEntry = GetCacheEntry(aStorageName);
+  nsRefPtr<CacheEntry> cacheEntry = GetCacheEntry(aStorageName);
   if (!cacheEntry) {
     cacheEntry = new CacheEntry;
     cacheEntry->mStorageName = aStorageName;
     mCacheEntries.AppendElement(cacheEntry);
   }
   cacheEntry->mFreeBytes = GetFreeBytes(cacheEntry->mStorageName);
 
   cacheEntry->mPicturesUsedSize = aPictureSize;
   cacheEntry->mVideosUsedSize = aVideosSize;
   cacheEntry->mMusicUsedSize = aMusicSize;
   cacheEntry->mTotalUsedSize = aTotalUsedSize;
   cacheEntry->mDirty = false;
 }
 
-class GlobalDirs : public RefCounted<GlobalDirs>
+class GlobalDirs
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(GlobalDirs)
+  NS_INLINE_DECL_REFCOUNTING(GlobalDirs)
 #if !defined(MOZ_WIDGET_GONK)
   nsCOMPtr<nsIFile> pictures;
   nsCOMPtr<nsIFile> videos;
   nsCOMPtr<nsIFile> music;
   nsCOMPtr<nsIFile> sdcard;
 #endif
   nsCOMPtr<nsIFile> apps;
   nsCOMPtr<nsIFile> crashes;
@@ -3174,26 +3175,25 @@ nsDOMDeviceStorage::Shutdown()
     UnregisterForSDCardChanges(this);
   }
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   obs->RemoveObserver(this, "file-watcher-update");
   obs->RemoveObserver(this, "disk-space-watcher");
 }
 
-StaticRefPtr<nsDOMDeviceStorage::VolumeNameCache>
-  nsDOMDeviceStorage::sVolumeNameCache;
+StaticAutoPtr<nsTArray<nsString>> nsDOMDeviceStorage::sVolumeNameCache;
 
 // static
 void
 nsDOMDeviceStorage::GetOrderedVolumeNames(
   nsDOMDeviceStorage::VolumeNameArray &aVolumeNames)
 {
-  if (sVolumeNameCache && sVolumeNameCache->mVolumeNames.Length() > 0) {
-    aVolumeNames.AppendElements(sVolumeNameCache->mVolumeNames);
+  if (sVolumeNameCache && sVolumeNameCache->Length() > 0) {
+    aVolumeNames.AppendElements(*sVolumeNameCache);
     return;
   }
 #ifdef MOZ_WIDGET_GONK
   nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
   if (vs) {
     vs->GetVolumeNames(aVolumeNames);
 
     // If the volume sdcard exists, then we want it to be first.
@@ -3204,18 +3204,18 @@ nsDOMDeviceStorage::GetOrderedVolumeName
       aVolumeNames.RemoveElementAt(sdcardIndex);
       aVolumeNames.InsertElementAt(0, NS_LITERAL_STRING("sdcard"));
     }
   }
 #endif
   if (aVolumeNames.IsEmpty()) {
     aVolumeNames.AppendElement(EmptyString());
   }
-  sVolumeNameCache = new VolumeNameCache;
-  sVolumeNameCache->mVolumeNames.AppendElements(aVolumeNames);
+  sVolumeNameCache = new nsTArray<nsString>;
+  sVolumeNameCache->AppendElements(aVolumeNames);
 }
 
 // static
 void
 nsDOMDeviceStorage::CreateDeviceStorageFor(nsPIDOMWindow* aWin,
                                            const nsAString &aType,
                                            nsDOMDeviceStorage** aStore)
 {
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -24,17 +24,16 @@ class nsPIDOMWindow;
 #include "nsWeakPtr.h"
 #include "nsIDOMEventListener.h"
 #include "nsIObserver.h"
 #include "nsIStringBundle.h"
 #include "mozilla/Mutex.h"
 #include "prtime.h"
 #include "DeviceStorage.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
-#include "mozilla/RefPtr.h"
 #include "mozilla/StaticPtr.h"
 
 namespace mozilla {
 class ErrorResult;
 } // namespace mozilla
 
 #define POST_ERROR_EVENT_FILE_EXISTS                 "NoModificationAllowedError"
 #define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST         "NotFoundError"
@@ -75,17 +74,17 @@ public:
                          const nsAString& aStorageName)
         : mCache(aCache)
         , mStorageName(aStorageName) {}
 
       ~InvalidateRunnable() {}
 
       NS_IMETHOD Run() MOZ_OVERRIDE
       {
-        mozilla::RefPtr<DeviceStorageUsedSpaceCache::CacheEntry> cacheEntry;
+        nsRefPtr<DeviceStorageUsedSpaceCache::CacheEntry> cacheEntry;
         cacheEntry = mCache->GetCacheEntry(mStorageName);
         if (cacheEntry) {
           cacheEntry->mDirty = true;
         }
         return NS_OK;
       }
     private:
       DeviceStorageUsedSpaceCache* mCache;
@@ -115,31 +114,31 @@ public:
 
   void SetUsedSizes(const nsAString& aStorageName,
                     uint64_t aPictureSize, uint64_t aVideosSize,
                     uint64_t aMusicSize, uint64_t aTotalSize);
 
 private:
   friend class InvalidateRunnable;
 
-  class CacheEntry : public mozilla::RefCounted<CacheEntry> 
+  struct CacheEntry
   {
-  public:
-    MOZ_DECLARE_REFCOUNTED_TYPENAME(DeviceStorageUsedSpaceCache::CacheEntry)
+    NS_INLINE_DECL_REFCOUNTING(DeviceStorageUsedSpaceCache::CacheEntry)
+
     bool mDirty;
     nsString mStorageName;
     int64_t  mFreeBytes;
     uint64_t mPicturesUsedSize;
     uint64_t mVideosUsedSize;
     uint64_t mMusicUsedSize;
     uint64_t mTotalUsedSize;
   };
-  mozilla::TemporaryRef<CacheEntry> GetCacheEntry(const nsAString& aStorageName);
+  already_AddRefed<CacheEntry> GetCacheEntry(const nsAString& aStorageName);
 
-  nsTArray<mozilla::RefPtr<CacheEntry> > mCacheEntries;
+  nsTArray<nsRefPtr<CacheEntry>> mCacheEntries;
 
   nsCOMPtr<nsIThread> mIOThread;
 
   static mozilla::StaticAutoPtr<DeviceStorageUsedSpaceCache> sDeviceStorageUsedSpaceCache;
 };
 
 class DeviceStorageTypeChecker MOZ_FINAL
 {
--- a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
+++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
@@ -7,17 +7,17 @@
 interface nsIDOMBlob;
 interface nsIDOMDOMRequest;
 interface nsIDOMDOMCursor;
 interface nsIDOMDeviceStorageChangeEvent;
 interface nsIDOMEventListener;
 interface nsIFile;
 
 %{C++
-class DeviceStorageFileDescriptor;
+struct DeviceStorageFileDescriptor;
 %}
 [ptr] native DeviceStorageFdPtr(DeviceStorageFileDescriptor);
 
 [scriptable, uuid(8b724547-3c78-4244-969a-f00a1f4ae0c3), builtinclass]
 interface nsIDOMDeviceStorage : nsIDOMEventTarget
 {
     [implicit_jscontext] attribute jsval onchange;
     nsIDOMDOMRequest add(in nsIDOMBlob aBlob);
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -45,16 +45,17 @@ using class mozilla::WidgetSelectionEven
 using class mozilla::WidgetTextEvent from "ipc/nsGUIEventIPC.h";
 using class mozilla::WidgetTouchEvent from "ipc/nsGUIEventIPC.h";
 using struct mozilla::dom::RemoteDOMEvent from "mozilla/dom/TabMessageUtils.h";
 using mozilla::dom::ScreenOrientation from "mozilla/dom/ScreenOrientation.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
 using mozilla::CSSPoint from "Units.h";
 using mozilla::CSSToScreenScale from "Units.h";
 using mozilla::CommandInt from "mozilla/EventForwards.h";
+using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h";
 
 namespace mozilla {
 namespace dom {
 
 struct NativeKeyBinding
 {
   CommandInt[] singleLineCommands;
   CommandInt[] multiLineCommands;
@@ -405,21 +406,20 @@ child:
      * relative to the current scroll offset. In the case the "contextmenu"
      * event generated by the preceding HandleLongTap call was not handled,
      * this message is expected to generate a "mousedown" and "mouseup"
      * series of events
      */
     HandleLongTapUp(CSSPoint point, ScrollableLayerGuid aGuid);
 
     /**
-     * Notifies the child that the parent has begun or finished transforming
-     * the visible child content area. Useful for showing/hiding scrollbars.
+     * Notifies the child about various APZ state changes.
+     * See GeckoContentController::NotifyAPZStateChange() for details.
      */
-    NotifyTransformBegin(ViewID aViewId);
-    NotifyTransformEnd(ViewID aViewId);
+    NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
 
     /**
      * Sending an activate message moves focus to the child.
      */
     Activate();
 
     Deactivate();
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -69,16 +69,17 @@
 #include "nsViewportInfo.h"
 #include "JavaScriptChild.h"
 #include "APZCCallbackHelper.h"
 #include "nsILoadContext.h"
 #include "ipc/nsGUIEventIPC.h"
 #include "mozilla/gfx/Matrix.h"
 #include "UnitTransforms.h"
 #include "ClientLayerManager.h"
+#include "ActiveElementManager.h"
 
 #include "nsColorPickerProxy.h"
 
 #ifdef DEBUG
 #include "PCOMContentPermissionRequestChild.h"
 #endif /* DEBUG */
 
 #define BROWSER_ELEMENT_CHILD_SCRIPT \
@@ -682,16 +683,17 @@ TabChild::TabChild(ContentChild* aManage
   , mDidFakeShow(false)
   , mNotified(false)
   , mTriedBrowserInit(false)
   , mOrientation(eScreenOrientation_PortraitPrimary)
   , mUpdateHitRegion(false)
   , mContextMenuHandled(false)
   , mWaitingTouchListeners(false)
   , mIgnoreKeyPressEvent(false)
+  , mActiveElementManager(new ActiveElementManager())
 {
   if (!sActiveDurationMsSet) {
     Preferences::AddIntVarCache(&sActiveDurationMs,
                                 "ui.touch_activation.duration_ms",
                                 sActiveDurationMs);
     sActiveDurationMsSet = true;
   }
 }
@@ -1725,33 +1727,59 @@ TabChild::RecvHandleLongTapUp(const CSSP
     return true;
   }
 
   RecvHandleSingleTap(aPoint, aGuid);
   return true;
 }
 
 bool
-TabChild::RecvNotifyTransformBegin(const ViewID& aViewId)
+TabChild::RecvNotifyAPZStateChange(const ViewID& aViewId,
+                                   const APZStateChange& aChange,
+                                   const int& aArg)
 {
-  nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId);
-  nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf);
-  if (scrollbarOwner) {
-    scrollbarOwner->ScrollbarActivityStarted();
+  switch (aChange)
+  {
+  case APZStateChange::TransformBegin:
+  {
+    nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId);
+    nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf);
+    if (scrollbarOwner) {
+      scrollbarOwner->ScrollbarActivityStarted();
+    }
+    break;
   }
-  return true;
-}
-
-bool
-TabChild::RecvNotifyTransformEnd(const ViewID& aViewId)
-{
-  nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId);
-  nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf);
-  if (scrollbarOwner) {
-    scrollbarOwner->ScrollbarActivityStopped();
+  case APZStateChange::TransformEnd:
+  {
+    nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId);
+    nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf);
+    if (scrollbarOwner) {
+      scrollbarOwner->ScrollbarActivityStopped();
+    }
+    break;
+  }
+  case APZStateChange::StartTouch:
+  {
+    mActiveElementManager->HandleTouchStart(aArg);
+    break;
+  }
+  case APZStateChange::StartPanning:
+  {
+    mActiveElementManager->HandlePanStart();
+    break;
+  }
+  case APZStateChange::EndTouch:
+  {
+    mActiveElementManager->HandleTouchEnd(aArg);
+    break;
+  }
+  default:
+    // APZStateChange has a 'sentinel' value, and the compiler complains
+    // if an enumerator is not handled and there is no 'default' case.
+    break;
   }
   return true;
 }
 
 bool
 TabChild::RecvActivate()
 {
   nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation());
@@ -1946,16 +1974,20 @@ TabChild::RecvRealTouchEvent(const Widge
 
   nsEventStatus status = DispatchWidgetEvent(localEvent);
 
   if (!IsAsyncPanZoomEnabled()) {
     UpdateTapState(localEvent, status);
     return true;
   }
 
+  if (aEvent.message == NS_TOUCH_START && localEvent.touches.Length() > 0) {
+    mActiveElementManager->SetTargetElement(localEvent.touches[0]->Target());
+  }
+
   nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(WebNavigation());
   nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
 
   if (!innerWindow || !innerWindow->HasTouchEventListeners()) {
     SendContentReceivedTouch(aGuid, false);
     return true;
   }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -37,16 +37,20 @@
 class nsICachedFileDescriptorListener;
 class nsIDOMWindowUtils;
 
 namespace mozilla {
 namespace layout {
 class RenderFrameChild;
 }
 
+namespace widget {
+class ActiveElementManager;
+}
+
 namespace dom {
 
 class TabChild;
 class ClonedMessageData;
 class TabChildBase;
 
 class TabChildGlobal : public DOMEventTargetHelper,
                        public nsIContentFrameMessageManager,
@@ -223,16 +227,17 @@ class TabChild : public PBrowserChild,
                  public nsIObserver,
                  public TabContext,
                  public nsITooltipListener,
                  public TabChildBase
 {
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
     typedef mozilla::layout::RenderFrameChild RenderFrameChild;
     typedef mozilla::layout::ScrollingBehavior ScrollingBehavior;
+    typedef mozilla::widget::ActiveElementManager ActiveElementManager;
 
 public:
     /** 
      * This is expected to be called off the critical path to content
      * startup.  This is an opportunity to load things that are slow
      * on the critical path.
      */
     static void PreloadSlowThings();
@@ -291,18 +296,19 @@ public:
     virtual bool RecvHandleDoubleTap(const CSSPoint& aPoint,
                                      const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
     virtual bool RecvHandleSingleTap(const CSSPoint& aPoint,
                                      const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
     virtual bool RecvHandleLongTap(const CSSPoint& aPoint,
                                    const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
     virtual bool RecvHandleLongTapUp(const CSSPoint& aPoint,
                                      const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
-    virtual bool RecvNotifyTransformBegin(const ViewID& aViewId) MOZ_OVERRIDE;
-    virtual bool RecvNotifyTransformEnd(const ViewID& aViewId) MOZ_OVERRIDE;
+    virtual bool RecvNotifyAPZStateChange(const ViewID& aViewId,
+                                          const APZStateChange& aChange,
+                                          const int& aArg) MOZ_OVERRIDE;
     virtual bool RecvActivate() MOZ_OVERRIDE;
     virtual bool RecvDeactivate() MOZ_OVERRIDE;
     virtual bool RecvMouseEvent(const nsString& aType,
                                 const float&    aX,
                                 const float&    aY,
                                 const int32_t&  aButton,
                                 const int32_t&  aClickCount,
                                 const int32_t&  aModifiers,
@@ -539,16 +545,17 @@ private:
     bool mTriedBrowserInit;
     ScreenOrientation mOrientation;
     bool mUpdateHitRegion;
     bool mContextMenuHandled;
     bool mWaitingTouchListeners;
     void FireSingleTapEvent(LayoutDevicePoint aPoint);
 
     bool mIgnoreKeyPressEvent;
+    nsRefPtr<ActiveElementManager> mActiveElementManager;
 
     DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 }
 }
 
 #endif // mozilla_dom_TabChild_h
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -549,27 +549,22 @@ void TabParent::HandleLongTapUp(const CS
                                 int32_t aModifiers,
                                 const ScrollableLayerGuid &aGuid)
 {
   if (!mIsDestroyed) {
     unused << SendHandleLongTapUp(aPoint, aGuid);
   }
 }
 
-void TabParent::NotifyTransformBegin(ViewID aViewId)
+void TabParent::NotifyAPZStateChange(ViewID aViewId,
+                                     APZStateChange aChange,
+                                     int aArg)
 {
   if (!mIsDestroyed) {
-    unused << SendNotifyTransformBegin(aViewId);
-  }
-}
-
-void TabParent::NotifyTransformEnd(ViewID aViewId)
-{
-  if (!mIsDestroyed) {
-    unused << SendNotifyTransformEnd(aViewId);
+    unused << SendNotifyAPZStateChange(aViewId, aChange, aArg);
   }
 }
 
 void
 TabParent::Activate()
 {
   if (!mIsDestroyed) {
     unused << SendActivate();
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -207,18 +207,19 @@ public:
                          int32_t aModifiers,
                          const ScrollableLayerGuid& aGuid);
     void HandleLongTap(const CSSPoint& aPoint,
                        int32_t aModifiers,
                        const ScrollableLayerGuid& aGuid);
     void HandleLongTapUp(const CSSPoint& aPoint,
                          int32_t aModifiers,
                          const ScrollableLayerGuid& aGuid);
-    void NotifyTransformBegin(ViewID aViewId);
-    void NotifyTransformEnd(ViewID aViewId);
+    void NotifyAPZStateChange(ViewID aViewId,
+                              APZStateChange aChange,
+                              int aArg);
     void Activate();
     void Deactivate();
 
     bool MapEventCoordinatesForChildProcess(mozilla::WidgetEvent* aEvent);
     void MapEventCoordinatesForChildProcess(const LayoutDeviceIntPoint& aOffset,
                                             mozilla::WidgetEvent* aEvent);
 
     void SendMouseEvent(const nsAString& aType, float aX, float aY,
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -6,17 +6,17 @@
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "nsIMediaManager.h"
 
 #include "nsHashKeys.h"
 #include "nsGlobalWindow.h"
 #include "nsClassHashtable.h"
 #include "nsRefPtrHashtable.h"
-#include "nsObserverService.h"
+#include "nsIObserver.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsIDOMNavigatorUserMedia.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Preferences.h"
--- a/dom/system/gonk/AutoMounter.cpp
+++ b/dom/system/gonk/AutoMounter.cpp
@@ -158,22 +158,22 @@ protected:
 private:
     const static int kMaxErrorCount = 3; // Max number of errors before we give up
 
     int   mErrorCount;
 };
 
 /***************************************************************************/
 
-class AutoMounter : public RefCounted<AutoMounter>
+class AutoMounter
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(AutoMounter)
+  NS_INLINE_DECL_REFCOUNTING(AutoMounter)
 
-  typedef nsTArray<RefPtr<Volume> > VolumeArray;
+  typedef nsTArray<RefPtr<Volume>> VolumeArray;
 
   AutoMounter()
     : mResponseCallback(new AutoMounterResponseCallback),
       mMode(AUTOMOUNTER_DISABLE)
   {
     VolumeManager::RegisterStateObserver(&mVolumeManagerStateObserver);
     Volume::RegisterObserver(&mVolumeEventObserver);
 
@@ -687,31 +687,31 @@ UsbCableEventIOThread()
 *
 *   Public API
 *
 *   Since the AutoMounter runs in IO Thread context, we need to switch
 *   to IOThread context before we can do anything.
 *
 **************************************************************************/
 
-class UsbCableObserver : public SwitchObserver,
-                         public RefCounted<UsbCableObserver>
+class UsbCableObserver MOZ_FINAL : public SwitchObserver
 {
+  ~UsbCableObserver()
+  {
+    UnregisterSwitchObserver(SWITCH_USB, this);
+  }
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(UsbCableObserver)
+  NS_INLINE_DECL_REFCOUNTING(UsbCableObserver)
+
   UsbCableObserver()
   {
     RegisterSwitchObserver(SWITCH_USB, this);
   }
 
-  ~UsbCableObserver()
-  {
-    UnregisterSwitchObserver(SWITCH_USB, this);
-  }
-
   virtual void Notify(const SwitchEvent& aEvent)
   {
     DBG("UsbCable switch device: %d state: %s\n",
         aEvent.device(), SwitchStateStr(aEvent));
     XRE_GetIOMessageLoop()->PostTask(
         FROM_HERE,
         NewRunnableFunction(UsbCableEventIOThread));
   }
--- a/dom/system/gonk/Volume.h
+++ b/dom/system/gonk/Volume.h
@@ -4,35 +4,36 @@
 
 #ifndef mozilla_system_volume_h__
 #define mozilla_system_volume_h__
 
 #include "VolumeCommand.h"
 #include "nsIVolume.h"
 #include "nsString.h"
 #include "mozilla/Observer.h"
-#include "mozilla/RefPtr.h"
+#include "nsISupportsImpl.h"
 #include "nsWhitespaceTokenizer.h"
 
 namespace mozilla {
 namespace system {
 
 /***************************************************************************
 *
 *   There is an instance of the Volume class for each volume reported
 *   from vold.
 *
 *   Each volume originates from the /system/etv/vold.fstab file.
 *
 ***************************************************************************/
 
-class Volume : public RefCounted<Volume>
+class Volume MOZ_FINAL
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(Volume)
+  NS_INLINE_DECL_REFCOUNTING(Volume)
+
   Volume(const nsCSubstring& aVolumeName);
 
   typedef long STATE; // States are now defined in nsIVolume.idl
 
   static const char* StateStr(STATE aState) { return NS_VolumeStateStr(aState); }
   const char* StateStr() const  { return StateStr(mState); }
   STATE State() const           { return mState; }
 
--- a/dom/system/gonk/VolumeCommand.h
+++ b/dom/system/gonk/VolumeCommand.h
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_system_volumecommand_h__
 #define mozilla_system_volumecommand_h__
 
 #include "nsString.h"
+#include "nsISupportsImpl.h"
 #include "mozilla/RefPtr.h"
 #include <algorithm>
 #include <vold/ResponseCode.h>
 
 namespace mozilla {
 namespace system {
 
 class Volume;
@@ -27,25 +28,26 @@ class VolumeCommand;
 *   The responses from vold are all of the form:
 *
 *     <ResponseCode> <String>
 *
 *   Valid Response codes can be found in the vold/ResponseCode.h header.
 *
 ***************************************************************************/
 
-class VolumeResponseCallback : public RefCounted<VolumeResponseCallback>
+class VolumeResponseCallback
 {
+protected:
+  virtual ~VolumeResponseCallback() {}
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeResponseCallback)
+  NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback)
   VolumeResponseCallback()
     : mResponseCode(0), mPending(false) {}
 
-  virtual ~VolumeResponseCallback() {}
-
   bool Done() const
   {
     // Response codes from the 200, 400, and 500 series all indicated that
     // the command has completed.
 
     return (mResponseCode >= ResponseCode::CommandOkay)
         && (mResponseCode < ResponseCode::UnsolicitedInformational);
   }
@@ -101,36 +103,38 @@ private:
 *   Commands sent to vold need an explicit null character so we add one
 *   to the command to ensure that it's included in the length.
 *
 *   All of these commands are asynchronous in nature, and the
 *   ResponseReceived callback will be called when a response is available.
 *
 ***************************************************************************/
 
-class VolumeCommand : public RefCounted<VolumeCommand>
+class VolumeCommand
 {
+protected:
+  virtual ~VolumeCommand() {}
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeCommand)
+  NS_INLINE_DECL_REFCOUNTING(VolumeCommand)
+
   VolumeCommand(VolumeResponseCallback* aCallback)
     : mBytesConsumed(0),
       mCallback(aCallback)
   {
     SetCmd(NS_LITERAL_CSTRING(""));
   }
 
   VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback)
     : mBytesConsumed(0),
       mCallback(aCallback)
   {
     SetCmd(aCommand);
   }
 
-  virtual ~VolumeCommand() {}
-
   void SetCmd(const nsACString& aCommand)
   {
     mCmd.Truncate();
 #if ANDROID_VERSION >= 17
     // JB requires a sequence number at the beginning of messages.
     // It doesn't matter what we use, so we use 0.
     mCmd = "0 ";
 #endif
--- a/dom/system/gonk/VolumeManager.h
+++ b/dom/system/gonk/VolumeManager.h
@@ -6,17 +6,17 @@
 #define mozilla_system_volumemanager_h__
 
 #include <vector>
 #include <queue>
 
 #include "base/message_loop.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/Observer.h"
-#include "mozilla/RefPtr.h"
+#include "nsISupportsImpl.h"
 #include "nsString.h"
 #include "nsTArray.h"
 
 #include "Volume.h"
 #include "VolumeCommand.h"
 
 namespace mozilla {
 namespace system {
@@ -68,26 +68,26 @@ namespace system {
 *   There is also a command line tool called vdc, which can be used to send
 *   the above commands to vold.
 *
 *   Currently, only the volume list, share/unshare, and mount/unmount
 *   commands are being used.
 *
 ***************************************************************************/
 
-class VolumeManager : public MessageLoopForIO::LineWatcher,
-                      public RefCounted<VolumeManager>
+class VolumeManager MOZ_FINAL : public MessageLoopForIO::LineWatcher
 {
+  virtual ~VolumeManager();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeManager)
+  NS_INLINE_DECL_REFCOUNTING(VolumeManager)
 
-  typedef nsTArray<RefPtr<Volume> > VolumeArray;
+  typedef nsTArray<RefPtr<Volume>> VolumeArray;
 
   VolumeManager();
-  virtual ~VolumeManager();
 
   //-----------------------------------------------------------------------
   //
   // State related methods.
   //
   // The VolumeManager starts off in the STARTING state. Once a connection
   // is established with vold, it asks for a list of volumes, and once the
   // volume list has been received, then the VolumeManager enters the
--- a/dom/system/gonk/VolumeServiceIOThread.h
+++ b/dom/system/gonk/VolumeServiceIOThread.h
@@ -14,23 +14,24 @@ namespace system {
 
 class nsVolumeService;
 
 /***************************************************************************
 * The nsVolumeServiceIOThread is a companion class to the nsVolumeService
 * class, but whose methods are called from IOThread.
 */
 class VolumeServiceIOThread : public VolumeManager::StateObserver,
-                              public Volume::EventObserver,
-                              public RefCounted<VolumeServiceIOThread>
+                              public Volume::EventObserver
 {
+  ~VolumeServiceIOThread();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeServiceIOThread)
+  NS_INLINE_DECL_REFCOUNTING(VolumeServiceIOThread)
+
   VolumeServiceIOThread(nsVolumeService* aVolumeService);
-  ~VolumeServiceIOThread();
 
 private:
   void  UpdateAllVolumes();
 
   virtual void Notify(const VolumeManager::StateChangedEvent& aEvent);
   virtual void Notify(Volume* const & aVolume);
 
   RefPtr<nsVolumeService>   mVolumeService;
--- a/dom/webidl/CameraControl.webidl
+++ b/dom/webidl/CameraControl.webidl
@@ -329,16 +329,30 @@ interface CameraControl : MediaStream
      the WebIDL compiler throws: "WebIDL.WebIDLError: error: Dictionary
      argument or union argument containing a dictionary not followed by
      a required argument must be optional"
   */
   [Throws]
   void setConfiguration(optional CameraConfiguration configuration,
                         optional CameraSetConfigurationCallback onSuccess,
                         optional CameraErrorCallback onError);
+
+  /* if focusMode is set to either 'continuous-picture' or 'continuous-video',
+     then calling autoFocus() will trigger its onSuccess callback immediately
+     if the camera was either successfully focused, or if no focus could be
+     acquired; if the focus acquisition is still in progress, the onSuccess
+     callback will be invoked later, its argument indicating success or
+     failure.
+
+     once autoFocus() is called with a continuous autofocus mode set, the
+     continuous autofocus process is stopped and focus is locked in the
+     current state until this method is called.
+  */
+  [Throws]
+  void resumeContinuousFocus();
 };
 
 /* The coordinates of a point, relative to the camera sensor, of the center of
    detected facial features. As with CameraRegions:
      { x: -1000, y: -1000 } is the top-left corner
      { x:  1000, y:  1000 } is the bottom-right corner
    x and y can range from -1000 to 1000.
 */
--- a/dom/xbl/test/file_bug821850.xhtml
+++ b/dom/xbl/test/file_bug821850.xhtml
@@ -48,21 +48,22 @@ https://bugzilla.mozilla.org/show_bug.cg
              "Unexposed method should be visible to XBL");
           is(typeof bound.wrappedJSObject.unexposedMethod, 'undefined',
              "Unexposed method should not be defined in content");
           is(typeof bound.unexposedProperty, 'number',
              "Unexposed property should be visible to XBL");
           is(typeof bound.wrappedJSObject.unexposedProperty, 'undefined',
              "Unexposed property should not be defined in content");
 
-          // Check that here document.QueryInterface works
-          ok("QueryInterface" in document,
-             "Should have a document.QueryInterface here");
-          is(document.QueryInterface(Components.interfaces.nsIDOMDocument),
-             document, "Should be able to QI the document");
+          // Check that here HTMLImageElement.QueryInterface works
+          var img = document.querySelector("img");
+          ok("QueryInterface" in img,
+             "Should have a img.QueryInterface here");
+          is(img.QueryInterface(Components.interfaces.nsIImageLoadingContent),
+             img, "Should be able to QI the image");
 
           // Make sure standard constructors work right in the presence of
           // sandboxPrototype and Xray-resolved constructors.
           is(window.Function, XPCNativeWrapper(window.wrappedJSObject.Function),
              "window.Function comes from the window, not the global");
           ok(Function != window.Function, "Function constructors are distinct");
           is(Object.getPrototypeOf(Function.prototype), Object.getPrototypeOf({foo: 42}),
              "Function constructor is local");
@@ -284,13 +285,14 @@ https://bugzilla.mozilla.org/show_bug.cg
 </script>
 </head>
 <body onload="setup()">
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821850">Mozilla Bug 821850</a>
 <p id="display"></p>
 <div id="content">
   <div id="bound">Bound element</div>
   <div id="bound2">Bound element</div>
+  <img/>
 </div>
 <pre id="test">
 </pre>
 </body>
 </html>
--- a/editor/libeditor/html/tests/browserscope/lib/richtext2/richtext2/tests/insert.py
+++ b/editor/libeditor/html/tests/browserscope/lib/richtext2/richtext2/tests/insert.py
@@ -160,55 +160,55 @@ INSERT_TESTS = {
       ]
     },
 
     { 'desc':       'insert <img>',
       'command':    'insertimage',
       'tests':      [
         { 'id':         'IIMG:url_TEXT-1_SC',
           'rte1-id':    'a-insertimage-0',
-          'desc':       'Insert image with URL "http://goo.gl/bar.png"',
-          'value':      'http://goo.gl/bar.png',
+          'desc':       'Insert image with URL "bar.png"',
+          'value':      'bar.png',
           'checkAttrs':  True,
           'pad':        'foo^bar',
-          'expected':   [ 'foo<img src="http://goo.gl/bar.png">|bar',
-                          'foo<img src="http://goo.gl/bar.png">^bar' ] },
+          'expected':   [ 'foo<img src="bar.png">|bar',
+                          'foo<img src="bar.png">^bar' ] },
 
         { 'id':         'IIMG:url_IMG-1_SO',
           'desc':       'Change existing image to new URL, selection on <img>',
-          'value':      'http://baz.com/quz.png',
+          'value':      'quz.png',
           'checkAttrs':  True,
-          'pad':        '<span>foo{<img src="http://goo.gl/bar.png">}bar</span>',
-          'expected':   [ '<span>foo<img src="http://baz.com/quz.png"/>|bar</span>',
-                          '<span>foo<img src="http://baz.com/quz.png"/>^bar</span>' ] },
+          'pad':        '<span>foo{<img src="bar.png">}bar</span>',
+          'expected':   [ '<span>foo<img src="quz.png"/>|bar</span>',
+                          '<span>foo<img src="quz.png"/>^bar</span>' ] },
 
         { 'id':         'IIMG:url_SPAN-IMG-1_SO',
           'desc':       'Change existing image to new URL, selection in text surrounding <img>',
-          'value':      'http://baz.com/quz.png',
+          'value':      'quz.png',
           'checkAttrs':  True,
-          'pad':        'foo[<img src="http://goo.gl/bar.png">]bar',
-          'expected':   [ 'foo<img src="http://baz.com/quz.png"/>|bar',
-                          'foo<img src="http://baz.com/quz.png"/>^bar' ] },
+          'pad':        'foo[<img src="bar.png">]bar',
+          'expected':   [ 'foo<img src="quz.png"/>|bar',
+                          'foo<img src="quz.png"/>^bar' ] },
 
         { 'id':         'IIMG:._SPAN-IMG-1_SO',
           'desc':       'Remove existing image or URL, selection on <img>',
           'value':      '',
           'checkAttrs':  True,
-          'pad':        '<span>foo{<img src="http://goo.gl/bar.png">}bar</span>',
+          'pad':        '<span>foo{<img src="bar.png">}bar</span>',
           'expected':   [ '<span>foo^bar</span>',
                           '<span>foo<img>|bar</span>',
                           '<span>foo<img>^bar</span>',
                           '<span>foo<img src="">|bar</span>',
                           '<span>foo<img src="">^bar</span>' ] },
 
         { 'id':         'IIMG:._IMG-1_SO',
           'desc':       'Remove existing image or URL, selection in text surrounding <img>',
           'value':      '',
           'checkAttrs':  True,
-          'pad':        'foo[<img src="http://goo.gl/bar.png">]bar',
+          'pad':        'foo[<img src="bar.png">]bar',
           'expected':   [ 'foo^bar',
                           'foo<img>|bar',
                           'foo<img>^bar',
                           'foo<img src="">|bar',
                           'foo<img src="">^bar' ] }
       ]
     },
 
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -411,17 +411,17 @@ public:
   }
 
   /*
    * Returns a DataSourceSurface with the same data as this one, but
    * guaranteed to have surface->GetType() == SurfaceType::DATA.
    */
   virtual TemporaryRef<DataSourceSurface> GetDataSurface();
 
-  DebugOnly<bool> mIsMapped;
+  bool mIsMapped;
 };
 
 /* This is an abstract object that accepts path segments. */
 class PathSink : public RefCounted<PathSink>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink)
   virtual ~PathSink() {}
--- a/gfx/2d/DataSurfaceHelpers.h
+++ b/gfx/2d/DataSurfaceHelpers.h
@@ -20,27 +20,29 @@ ConvertBGRXToBGRA(uint8_t* aData, const 
  * contain |aSrcSize.width * aSrcSize.height * aBytesPerPixel| bytes.
  */
 void
 CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize,
                              int32_t aSrcStride, int32_t aBytesPerPixel);
 
 /**
  * Convert aSurface to a packed buffer in BGRA format. The pixel data is
- * returned in a buffer allocated with new uint8_t[].
+ * returned in a buffer allocated with new uint8_t[]. The caller then has
+ * ownership of the buffer and is responsible for delete[]'ing it.
  */
 uint8_t*
 SurfaceToPackedBGRA(DataSourceSurface *aSurface);
 
 /**
  * Convert aSurface to a packed buffer in BGR format. The pixel data is
- * returned in a buffer allocated with new uint8_t[].
+ * returned in a buffer allocated with new uint8_t[]. The caller then has
+ * ownership of the buffer and is responsible for delete[]'ing it.
  *
  * This function is currently only intended for use with surfaces of format
- * SurfaceFormat::B8G8R8X8 since the X components of the pixel data are simply
- * dropped (no attempt is made to un-pre-multiply alpha from the color
- * components).
+ * SurfaceFormat::B8G8R8X8 since the X components of the pixel data (if any)
+ * are simply dropped (no attempt is made to un-pre-multiply alpha from the
+ * color components).
  */
 uint8_t*
 SurfaceToPackedBGR(DataSourceSurface *aSurface);
 
 }
 }
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -19,16 +19,18 @@ namespace gl {
 // |src| must begin and end locked, though we may
 // temporarily unlock it if we need to.
 void
 SharedSurface_GL::ProdCopy(SharedSurface_GL* src, SharedSurface_GL* dest,
                            SurfaceFactory_GL* factory)
 {
     GLContext* gl = src->GL();
 
+    gl->MakeCurrent();
+
     if (src->AttachType() == AttachmentType::Screen &&
         dest->AttachType() == AttachmentType::Screen)
     {
         // Here, we actually need to blit through a temp surface, so let's make one.
         nsAutoPtr<SharedSurface_GLTexture> tempSurf(
             SharedSurface_GLTexture::Create(gl, gl,
                                             factory->Formats(),
                                             src->Size(),
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -21,16 +21,17 @@
 #include "gfxRect.h"
 #include "nsRect.h"
 #include "nsRegion.h"
 #include "gfxTypes.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "FrameMetrics.h"
 #include "FilterSupport.h"
+#include "mozilla/layers/GeckoContentController.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
 
 namespace mozilla {
 
 typedef gfxImageFormat PixelFormat;
@@ -1064,11 +1065,21 @@ struct ParamTraits<mozilla::gfx::FilterD
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     return (ReadParam(aMsg, aIter, &aResult->mFilterSpaceBounds) &&
             ReadParam(aMsg, aIter, &aResult->mPrimitives));
   }
 };
 
+typedef mozilla::layers::GeckoContentController::APZStateChange APZStateChange;
+
+template <>
+struct ParamTraits<APZStateChange>
+  : public ContiguousTypedEnumSerializer<
+             APZStateChange,
+             APZStateChange::TransformBegin,
+             APZStateChange::APZStateChangeSentinel>
+{};
+
 } /* namespace IPC */
 
 #endif /* __GFXMESSAGEUTILS_H__ */
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -132,28 +132,22 @@ enum SurfaceInitMode
 {
   INIT_MODE_NONE,
   INIT_MODE_CLEAR
 };
 
 /**
  * A base class for a platform-dependent helper for use by TextureHost.
  */
-class CompositorBackendSpecificData : public RefCounted<CompositorBackendSpecificData>
+class CompositorBackendSpecificData
 {
-public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositorBackendSpecificData)
-  CompositorBackendSpecificData()
-  {
-    MOZ_COUNT_CTOR(CompositorBackendSpecificData);
-  }
-  virtual ~CompositorBackendSpecificData()
-  {
-    MOZ_COUNT_DTOR(CompositorBackendSpecificData);
-  }
+  NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData)
+
+protected:
+  virtual ~CompositorBackendSpecificData() {}
 };
 
 /**
  * Common interface for compositor backends.
  *
  * Compositor provides a cross-platform interface to a set of operations for
  * compositing quads. Compositor knows nothing about the layer tree. It must be
  * told everything about each composited quad - contents, location, transform,
@@ -190,31 +184,30 @@ public:
  *
  * By default, the compositor will render to the screen, to render to a target,
  * call SetTargetContext or SetRenderTarget, the latter with a target created
  * by CreateRenderTarget or CreateRenderTargetFromSource.
  *
  * The target and viewport methods can be called before any DrawQuad call and
  * affect any subsequent DrawQuad calls.
  */
-class Compositor : public RefCounted<Compositor>
+class Compositor
 {
+protected:
+  virtual ~Compositor() {}
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(Compositor)
+  NS_INLINE_DECL_REFCOUNTING(Compositor)
+
   Compositor(PCompositorParent* aParent = nullptr)
     : mCompositorID(0)
     , mDiagnosticTypes(DIAGNOSTIC_NONE)
     , mParent(aParent)
     , mScreenRotation(ROTATION_0)
   {
-    MOZ_COUNT_CTOR(Compositor);
-  }
-  virtual ~Compositor()
-  {
-    MOZ_COUNT_DTOR(Compositor);
   }
 
   virtual TemporaryRef<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = 0) = 0;
   virtual bool Initialize() = 0;
   virtual void Destroy() = 0;
 
   /**
    * Return true if the effect type is supported.
--- a/gfx/layers/Effects.h
+++ b/gfx/layers/Effects.h
@@ -32,25 +32,28 @@ namespace layers {
  * - any way in which rendering can be changed, e.g., applying a mask layer.
  *
  * During the rendering process, an effect chain is created by the layer being
  * rendered and the primary effect is added by the compositable host. Secondary
  * effects may be added by the layer or compositable. The effect chain is passed
  * to the compositor by the compositable host as a parameter to DrawQuad.
  */
 
-struct Effect : public RefCounted<Effect>
+struct Effect
 {
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(Effect)
+  NS_INLINE_DECL_REFCOUNTING(Effect)
+
   Effect(EffectTypes aType) : mType(aType) {}
 
   EffectTypes mType;
 
+  virtual void PrintInfo(nsACString& aTo, const char* aPrefix) = 0;
+
+protected:
   virtual ~Effect() {}
-  virtual void PrintInfo(nsACString& aTo, const char* aPrefix) =0;
 };
 
 // Render from a texture
 struct TexturedEffect : public Effect
 {
   TexturedEffect(EffectTypes aType,
                  TextureSource *aTexture,
                  bool aPremultiplied,
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -63,24 +63,26 @@ class TextureClientData;
  * by this layer forwarder (the matching uses a global map on the compositor side,
  * see CompositableMap in ImageBridgeParent.cpp)
  *
  * Subclasses: Thebes layers use ContentClients, ImageLayers use ImageClients,
  * Canvas layers use CanvasClients (but ImageHosts). We have a different subclass
  * where we have a different way of interfacing with the textures - in terms of
  * drawing into the compositable and/or passing its contents to the compostior.
  */
-class CompositableClient : public AtomicRefCounted<CompositableClient>
+class CompositableClient
 {
+protected:
+  virtual ~CompositableClient();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableClient)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableClient)
+
   CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = 0);
 
-  virtual ~CompositableClient();
-
   virtual TextureInfo GetTextureInfo() const = 0;
 
   LayersBackend GetCompositorBackendType() const;
 
   TemporaryRef<BufferTextureClient>
   CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
                             TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT,
                             gfx::BackendType aMoz2dBackend = gfx::BackendType::NONE);
--- a/gfx/layers/client/SimpleTextureClientPool.h
+++ b/gfx/layers/client/SimpleTextureClientPool.h
@@ -14,31 +14,31 @@
 #include <stack>
 #include <list>
 
 namespace mozilla {
 namespace layers {
 
 class ISurfaceAllocator;
 
-class SimpleTextureClientPool : public RefCounted<SimpleTextureClientPool>
+class SimpleTextureClientPool
 {
-public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(SimpleTextureClientPool)
-
-  SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
-                          ISurfaceAllocator *aAllocator);
-
   ~SimpleTextureClientPool()
   {
     for (auto it = mOutstandingTextureClients.begin(); it != mOutstandingTextureClients.end(); ++it) {
       (*it)->ClearRecycleCallback();
     }
   }
 
+public:
+  NS_INLINE_DECL_REFCOUNTING(SimpleTextureClientPool)
+
+  SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
+                          ISurfaceAllocator *aAllocator);
+
   /**
    * If a TextureClient is AutoRecycled, when the last reference is
    * released this object will be automatically return to the pool as
    * soon as the compositor informs us it is done with it.
    */
   TemporaryRef<TextureClient> GetTextureClient(bool aAutoRecycle = false);
   TemporaryRef<TextureClient> GetTextureClientWithAutoRecycle() { return GetTextureClient(true); }
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -70,33 +70,27 @@ namespace layers {
  * TextureChild is used to synchronize a texture client and its corresponding
  * TextureHost if needed (a TextureClient that is not shared with the compositor
  * does not have a TextureChild)
  *
  * During the deallocation phase, a TextureChild may hold its recently destroyed
  * TextureClient's data until the compositor side confirmed that it is safe to
  * deallocte or recycle the it.
  */
-class TextureChild : public PTextureChild
-                   , public AtomicRefCounted<TextureChild>
+class TextureChild MOZ_FINAL : public PTextureChild
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureChild)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild)
+
   TextureChild()
   : mForwarder(nullptr)
   , mTextureData(nullptr)
   , mTextureClient(nullptr)
   , mIPCOpen(false)
   {
-    MOZ_COUNT_CTOR(TextureChild);
-  }
-
-  ~TextureChild()
-  {
-    MOZ_COUNT_DTOR(TextureChild);
   }
 
   bool Recv__delete__() MOZ_OVERRIDE;
 
   bool RecvCompositorRecycle(const MaybeFenceHandle& aFence)
   {
     RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
     if (aFence.type() != aFence.Tnull_t) {
--- a/gfx/layers/client/TextureClientPool.h
+++ b/gfx/layers/client/TextureClientPool.h
@@ -13,23 +13,25 @@
 #include "nsITimer.h"
 #include <stack>
 
 namespace mozilla {
 namespace layers {
 
 class ISurfaceAllocator;
 
-class TextureClientPool : public RefCounted<TextureClientPool>
+class TextureClientPool MOZ_FINAL
 {
+  ~TextureClientPool();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureClientPool)
+  NS_INLINE_DECL_REFCOUNTING(TextureClientPool)
+
   TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
                     ISurfaceAllocator *aAllocator);
-  ~TextureClientPool();
 
   /**
    * Gets an allocated TextureClient of size and format that are determined
    * by the initialisation parameters given to the pool. This will either be
    * a cached client that was returned to the pool, or a newly allocated
    * client if one isn't available.
    *
    * All clients retrieved by this method should be returned using the return
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -42,20 +42,22 @@ namespace mozilla {
 namespace layers {
 
 class BasicTileDescriptor;
 class ClientTiledThebesLayer;
 class ClientLayerManager;
 
 
 // A class to help implement copy-on-write semantics for shared tiles.
-class gfxSharedReadLock : public AtomicRefCounted<gfxSharedReadLock> {
+class gfxSharedReadLock {
+protected:
+  virtual ~gfxSharedReadLock() {}
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(gfxSharedReadLock)
-  virtual ~gfxSharedReadLock() {}
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxSharedReadLock)
 
   virtual int32_t ReadLock() = 0;
   virtual int32_t ReadUnlock() = 0;
   virtual int32_t GetReadCount() = 0;
   virtual bool IsValid() const = 0;
 
   enum gfxSharedReadLockType {
     TYPE_MEMORY,
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -774,17 +774,16 @@ APZCTreeManager::HandOffFling(AsyncPanZo
   ScreenPoint endPoint = startPoint + aVelocity;
   TransformDisplacement(this, aPrev, next, startPoint, endPoint);
   ScreenPoint transformedVelocity = endPoint - startPoint;
 
   // Tell |next| to start a fling with the transformed velocity.
   next->TakeOverFling(transformedVelocity);
 }
 
-
 bool
 APZCTreeManager::FlushRepaintsForOverscrollHandoffChain()
 {
   MonitorAutoLock lock(mTreeLock);  // to access mOverscrollHandoffChain
   if (mOverscrollHandoffChain.length() == 0) {
     return false;
   }
   for (uint32_t i = 0; i < mOverscrollHandoffChain.length(); i++) {
@@ -792,16 +791,40 @@ APZCTreeManager::FlushRepaintsForOverscr
     if (item) {
       item->FlushRepaintForOverscrollHandoff();
     }
   }
   return true;
 }
 
 bool
+APZCTreeManager::CanBePanned(AsyncPanZoomController* aApzc)
+{
+  MonitorAutoLock lock(mTreeLock);  // to access mOverscrollHandoffChain
+
+  // Find |aApzc| in the handoff chain.
+  uint32_t i;
+  for (i = 0; i < mOverscrollHandoffChain.length(); ++i) {
+    if (mOverscrollHandoffChain[i] == aApzc) {
+      break;
+    }
+  }
+
+  // See whether any APZC in the handoff chain starting from |aApzc|
+  // has room to be panned.
+  for (uint32_t j = i; j < mOverscrollHandoffChain.length(); ++j) {
+    if (mOverscrollHandoffChain[j]->IsPannable()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool
 APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint)
 {
   MonitorAutoLock lock(mTreeLock);
   nsRefPtr<AsyncPanZoomController> target;
   // The root may have siblings, so check those too
   gfxPoint point(aPoint.x, aPoint.y);
   for (AsyncPanZoomController* apzc = mRootApzc; apzc; apzc = apzc->GetPrevSibling()) {
     target = GetAPZCAtPoint(apzc, point);
--- a/gfx/layers/composite/APZCTreeManager.h
+++ b/gfx/layers/composite/APZCTreeManager.h
@@ -209,16 +209,17 @@ public:
    */
   void GetAllowedTouchBehavior(WidgetInputEvent* aEvent,
                                nsTArray<TouchBehaviorFlags>& aOutValues);
 
   /**
    * Sets allowed touch behavior values for current touch-session for specific apzc (determined by guid).
    * Should be invoked by the widget. Each value of the aValues arrays corresponds to the different
    * touch point that is currently active.
+   * Must be called after receiving the TOUCH_START event that starts the touch-session.
    */
   void SetAllowedTouchBehavior(const ScrollableLayerGuid& aGuid,
                                const nsTArray<TouchBehaviorFlags>& aValues);
 
   /**
    * This is a callback for AsyncPanZoomController to call when it wants to
    * scroll in response to a touch-move event, or when it needs to hand off
    * overscroll to the next APZC. Note that because of scroll grabbing, the
@@ -266,16 +267,23 @@ public:
    * @param aApzc the APZC that is handing off the fling
    * @param aVelocity the current velocity of the fling, in |aApzc|'s screen
    *                  pixels per millisecond
    */
   void HandOffFling(AsyncPanZoomController* aApzc, ScreenPoint aVelocity);
 
   bool FlushRepaintsForOverscrollHandoffChain();
 
+  /**
+   * Determine whether |aApzc|, or any APZC along its overscroll handoff chain,
+   * has room to be panned.
+   * Expects the overscroll handoff chain to already be built.
+   */
+  bool CanBePanned(AsyncPanZoomController* aApzc);
+
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~APZCTreeManager();
 
   /**
    * Debug-build assertion that can be called to ensure code is running on the
    * compositor thread.
    */
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -56,32 +56,31 @@ struct ViewTransform {
 /**
  * Manage async composition effects. This class is only used with OMTC and only
  * lives on the compositor thread. It is a layer on top of the layer manager
  * (LayerManagerComposite) which deals with elements of composition which are
  * usually dealt with by dom or layout when main thread rendering, but which can
  * short circuit that stuff to directly affect layers as they are composited,
  * for example, off-main thread animation, async video, async pan/zoom.
  */
-class AsyncCompositionManager MOZ_FINAL : public RefCounted<AsyncCompositionManager>
+class AsyncCompositionManager MOZ_FINAL
 {
   friend class AutoResolveRefLayers;
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(AsyncCompositionManager)
+  NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager)
+
   AsyncCompositionManager(LayerManagerComposite* aManager)
     : mLayerManager(aManager)
     , mIsFirstPaint(false)
     , mLayersUpdated(false)
     , mReadyForCompose(true)
   {
-    MOZ_COUNT_CTOR(AsyncCompositionManager);
   }
   ~AsyncCompositionManager()
   {
-    MOZ_COUNT_DTOR(AsyncCompositionManager);
   }
 
   /**
    * This forces the is-first-paint flag to true. This is intended to
    * be called by the widget code when it loses its viewport information
    * (or for whatever reason wants to refresh the viewport information).
    * The information refresh happens because the compositor will call
    * SetFirstPaintViewport on the next frame of composition.
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -51,28 +51,28 @@ class Compositor;
 class ISurfaceAllocator;
 class ThebesBufferData;
 class TiledLayerComposer;
 struct EffectChain;
 
 /**
  * A base class for doing CompositableHost and platform dependent task on TextureHost.
  */
-class CompositableBackendSpecificData : public RefCounted<CompositableBackendSpecificData>
+class CompositableBackendSpecificData
 {
+protected:
+  virtual ~CompositableBackendSpecificData() { }
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableBackendSpecificData)
+  NS_INLINE_DECL_REFCOUNTING(CompositableBackendSpecificData)
+
   CompositableBackendSpecificData()
   {
-    MOZ_COUNT_CTOR(CompositableBackendSpecificData);
   }
-  virtual ~CompositableBackendSpecificData()
-  {
-    MOZ_COUNT_DTOR(CompositableBackendSpecificData);
-  }
+
   virtual void SetCompositor(Compositor* aCompositor) {}
   virtual void ClearData()
   {
     mCurrentReleaseFenceTexture = nullptr;
     ClearPendingReleaseFenceTextureList();
   }
 
   /**
@@ -119,24 +119,25 @@ protected:
  * the layers transaction to update the Compositbale's textures from the
  * content side. The actual update (and any syncronous upload) is done by the
  * TextureHost, but it is coordinated by the CompositableHost.
  *
  * Composite is called by the owning layer when it is composited. CompositableHost
  * will use its TextureHost(s) and call Compositor::DrawQuad to do the actual
  * rendering.
  */
-class CompositableHost : public RefCounted<CompositableHost>
+class CompositableHost
 {
+protected:
+  virtual ~CompositableHost();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableHost)
+  NS_INLINE_DECL_REFCOUNTING(CompositableHost)
   CompositableHost(const TextureInfo& aTextureInfo);
 
-  virtual ~CompositableHost();
-
   static TemporaryRef<CompositableHost> Create(const TextureInfo& aTextureInfo);
 
   virtual CompositableType GetType() = 0;
 
   virtual CompositableBackendSpecificData* GetCompositableBackendSpecificData()
   {
     return mBackendData;
   }
--- a/gfx/layers/composite/TextRenderer.h
+++ b/gfx/layers/composite/TextRenderer.h
@@ -2,27 +2,29 @@
 /* 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 GFX_TextRenderer_H
 #define GFX_TextRenderer_H
 
 #include "mozilla/gfx/2D.h"
+#include "nsISupportsImpl.h"
 #include <string>
 
 namespace mozilla {
 namespace layers {
 
 class Compositor;
 
-class TextRenderer : public RefCounted<TextRenderer>
+class TextRenderer
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(TextRenderer)
+  NS_INLINE_DECL_REFCOUNTING(TextRenderer)
+
   TextRenderer(Compositor *aCompositor)
     : mCompositor(aCompositor)
   {
   }
 
   ~TextRenderer();
 
   void RenderText(const std::string& aText, const gfx::IntPoint& aOrigin,
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -75,22 +75,25 @@ public:
  * TextureSource is the interface for texture objects that can be composited
  * by a given compositor backend. Since the drawing APIs are different
  * between backends, the TextureSource interface is split into different
  * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
  * access to these interfaces.
  *
  * This class is used on the compositor side.
  */
-class TextureSource : public RefCounted<TextureSource>
+class TextureSource
 {
+protected:
+  virtual ~TextureSource();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureSource)
+  NS_INLINE_DECL_REFCOUNTING(TextureSource)
+
   TextureSource();
-  virtual ~TextureSource();
 
   /**
    * Return the size of the texture in texels.
    * If this is a tile iterator, GetSize must return the size of the current tile.
    */
   virtual gfx::IntSize GetSize() const = 0;
 
   /**
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -127,16 +127,17 @@ WidgetModifiersToDOMModifiers(mozilla::M
 }
 
 using namespace mozilla::css;
 
 namespace mozilla {
 namespace layers {
 
 typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
+typedef GeckoContentController::APZStateChange APZStateChange;
 
 /*
  * The following prefs are used to control the behaviour of the APZC.
  * The default values are provided in gfxPrefs.h.
  *
  * "apz.allow-checkerboarding"
  * Pref that allows or disallows checkerboarding
  *
@@ -415,19 +416,16 @@ AsyncPanZoomController::AsyncPanZoomCont
      mZoomConstraints(false, false, MIN_ZOOM, MAX_ZOOM),
      mLastSampleTime(GetFrameTime()),
      mState(NOTHING),
      mLastAsyncScrollTime(GetFrameTime()),
      mLastAsyncScrollOffset(0, 0),
      mCurrentAsyncScrollOffset(0, 0),
      mAsyncScrollTimeoutTask(nullptr),
      mHandlingTouchQueue(false),
-     mAllowedTouchBehaviorSet(false),
-     mPreventDefault(false),
-     mPreventDefaultSet(false),
      mTreeManager(aTreeManager),
      mScrollParentId(FrameMetrics::NULL_SCROLL_ID),
      mAPZCId(sAsyncPanZoomControllerCount++),
      mSharedFrameMetricsBuffer(nullptr),
      mSharedLock(nullptr)
 {
   MOZ_COUNT_CTOR(AsyncPanZoomController);
 
@@ -493,31 +491,33 @@ AsyncPanZoomController::GetTouchStartTol
 }
 
 /* static */AsyncPanZoomController::AxisLockMode AsyncPanZoomController::GetAxisLockMode()
 {
   return static_cast<AxisLockMode>(gfxPrefs::APZAxisLockMode());
 }
 
 nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent) {
+  if (aEvent.mInputType == MULTITOUCH_INPUT &&
+      aEvent.AsMultiTouchInput().mType == MultiTouchInput::MULTITOUCH_START) {
+    // Starting a new touch block, clear old touch block state.
+    mTouchBlockState = TouchBlockState();
+  }
+
   // If we may have touch listeners and touch action property is enabled, we
   // enable the machinery that allows touch listeners to preventDefault any touch inputs
   // and also waits for the allowed touch behavior values to be received from the outside.
   // This should not happen unless there are actually touch listeners and touch-action property
   // enable as it introduces potentially unbounded lag because it causes a round-trip through
   // content.  Usually, if content is responding in a timely fashion, this only introduces a
   // nearly constant few hundred ms of lag.
   if (mFrameMetrics.mMayHaveTouchListeners && aEvent.mInputType == MULTITOUCH_INPUT &&
       (mState == NOTHING || mState == TOUCHING || IsPanningState(mState))) {
     const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
     if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) {
-      mAllowedTouchBehaviors.Clear();
-      mAllowedTouchBehaviorSet = false;
-      mPreventDefault = false;
-      mPreventDefaultSet = false;
       SetState(WAITING_CONTENT_RESPONSE);
     }
   }
 
   if (mState == WAITING_CONTENT_RESPONSE || mHandlingTouchQueue) {
     if (aEvent.mInputType == MULTITOUCH_INPUT) {
       const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
       mTouchQueue.AppendElement(multiTouchInput);
@@ -610,21 +610,28 @@ nsEventStatus AsyncPanZoomController::On
         RequestContentRepaint();
         ScheduleComposite();
         UpdateSharedCompositorFrameMetrics();
       }
       // Fall through.
     case FLING:
       CancelAnimation();
       // Fall through.
-    case NOTHING:
+    case NOTHING: {
       mX.StartTouch(point.x);
       mY.StartTouch(point.y);
+      APZCTreeManager* treeManagerLocal = mTreeManager;
+      if (treeManagerLocal) {
+        bool touchCanBePan = treeManagerLocal->CanBePanned(this);
+        mGeckoContentController->NotifyAPZStateChange(
+            GetGuid(), APZStateChange::StartTouch, touchCanBePan);
+      }
       SetState(TOUCHING);
       break;
+    }
     case TOUCHING:
     case PANNING:
     case PANNING_LOCKED_X:
     case PANNING_LOCKED_Y:
     case CROSS_SLIDING_X:
     case CROSS_SLIDING_Y:
     case PINCHING:
     case WAITING_CONTENT_RESPONSE:
@@ -693,16 +700,18 @@ nsEventStatus AsyncPanZoomController::On
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) {
   APZC_LOG("%p got a touch-end in state %d\n", this, mState);
 
+  OnTouchEndOrCancel();
+
   // In case no touch behavior triggered previously we can avoid sending
   // scroll events or requesting content repaint. This condition is added
   // to make tests consistent - in case touch-action is NONE (and therefore
   // no pans/zooms can be performed) we expected neither scroll or repaint
   // events.
   if (mState != NOTHING) {
     ReentrantMonitorAutoEnter lock(mMonitor);
     SendAsyncScrollEvent();
@@ -759,16 +768,17 @@ nsEventStatus AsyncPanZoomController::On
     break;
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEvent) {
   APZC_LOG("%p got a touch-cancel in state %d\n", this, mState);
+  OnTouchEndOrCancel();
   SetState(NOTHING);
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) {
   APZC_LOG("%p got a scale-begin in state %d\n", this, mState);
 
   if (!TouchActionAllowZoom()) {
@@ -924,56 +934,56 @@ nsEventStatus AsyncPanZoomController::On
     if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
       controller->HandleLongTapUp(geckoScreenPoint, modifiers, GetGuid());
       return nsEventStatus_eConsumeNoDefault;
     }
   }
   return nsEventStatus_eIgnore;
 }
 
-nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
-  APZC_LOG("%p got a single-tap-up in state %d\n", this, mState);
+nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers) {
   nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
-  // If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before
-  // sending event to content
-  if (controller && !mZoomConstraints.mAllowDoubleTapZoom) {
-    int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
+  if (controller) {
     CSSPoint geckoScreenPoint;
-    if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
+    if (ConvertToGecko(aPoint, &geckoScreenPoint)) {
+      int32_t modifiers = WidgetModifiersToDOMModifiers(aModifiers);
       // Because this may be being running as part of APZCTreeManager::ReceiveInputEvent,
       // calling controller->HandleSingleTap directly might mean that content receives
       // the single tap message before the corresponding touch-up. To avoid that we
       // schedule the singletap message to run on the next spin of the event loop.
       // See bug 965381 for the issue this was causing.
       controller->PostDelayedTask(
         NewRunnableMethod(controller.get(), &GeckoContentController::HandleSingleTap,
                           geckoScreenPoint, modifiers, GetGuid()),
         0);
+      mTouchBlockState.mSingleTapOccurred = true;
       return nsEventStatus_eConsumeNoDefault;
     }
   }
   return nsEventStatus_eIgnore;
 }
 
+void AsyncPanZoomController::OnTouchEndOrCancel() {
+  mGeckoContentController->NotifyAPZStateChange(
+      GetGuid(), APZStateChange::EndTouch, mTouchBlockState.mSingleTapOccurred);
+}
+
+nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
+  APZC_LOG("%p got a single-tap-up in state %d\n", this, mState);
+  // If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before
+  // sending event to content
+  if (!mZoomConstraints.mAllowDoubleTapZoom) {
+    return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
+  }
+  return nsEventStatus_eIgnore;
+}
+
 nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput& aEvent) {
   APZC_LOG("%p got a single-tap-confirmed in state %d\n", this, mState);
-  nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
-  if (controller) {
-    int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
-    CSSPoint geckoScreenPoint;
-    if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
-      // See comment in OnSingleTapUp as to why we do this in PostDelayedTask.
-      controller->PostDelayedTask(
-        NewRunnableMethod(controller.get(), &GeckoContentController::HandleSingleTap,
-                          geckoScreenPoint, modifiers, GetGuid()),
-        0);
-      return nsEventStatus_eConsumeNoDefault;
-    }
-  }
-  return nsEventStatus_eIgnore;
+  return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
 }
 
 nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent) {
   APZC_LOG("%p got a double-tap in state %d\n", this, mState);
   nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
   if (controller) {
     if (mZoomConstraints.mAllowDoubleTapZoom) {
       int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
@@ -1087,25 +1097,27 @@ nsEventStatus AsyncPanZoomController::St
   double angle = atan2(dy, dx); // range [-pi, pi]
   angle = fabs(angle); // range [0, pi]
 
   if (mTouchActionPropertyEnabled) {
     HandlePanningWithTouchAction(angle, GetTouchBehavior(0));
   } else {
     if (GetAxisLockMode() == FREE) {
       SetState(PANNING);
-      return nsEventStatus_eConsumeNoDefault;
+    } else {
+      HandlePanning(angle);
     }
-
-    HandlePanning(angle);
   }
 
+  if (IsPanningState(mState)) {
+    mGeckoContentController->NotifyAPZStateChange(GetGuid(), APZStateChange::StartPanning);
+    return nsEventStatus_eConsumeNoDefault;
+  }
   // Don't consume an event that didn't trigger a panning.
-  return IsPanningState(mState) ? nsEventStatus_eConsumeNoDefault
-                                : nsEventStatus_eIgnore;
+  return nsEventStatus_eIgnore;
 }
 
 void AsyncPanZoomController::UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent) {
   ScreenIntPoint point = GetFirstTouchScreenPoint(aEvent);
   TimeDuration timeDelta = TimeDuration().FromMilliseconds(aEvent.mTime - mLastEventTime);
 
   // Probably a duplicate event, just throw it away.
   if (timeDelta.ToMilliseconds() <= EPSILON) {
@@ -1440,16 +1452,21 @@ void AsyncPanZoomController::ScheduleCom
 }
 
 void AsyncPanZoomController::FlushRepaintForOverscrollHandoff() {
   ReentrantMonitorAutoEnter lock(mMonitor);
   RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
+bool AsyncPanZoomController::IsPannable() const {
+  ReentrantMonitorAutoEnter lock(mMonitor);
+  return mX.HasRoomToPan() || mY.HasRoomToPan();
+}
+
 void AsyncPanZoomController::RequestContentRepaint() {
   RequestContentRepaint(mFrameMetrics);
 }
 
 void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics) {
   aFrameMetrics.SetDisplayPortMargins(
     CalculatePendingDisplayPort(aFrameMetrics,
                                 GetVelocityVector(),
@@ -1885,50 +1902,50 @@ void AsyncPanZoomController::ZoomToRect(
 
     // Schedule a repaint now, so the new displayport will be painted before the
     // animation finishes.
     RequestContentRepaint(endZoomToMetrics);
   }
 }
 
 void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
-  mPreventDefaultSet = true;
-  mPreventDefault = aPreventDefault;
+  mTouchBlockState.mPreventDefaultSet = true;
+  mTouchBlockState.mPreventDefault = aPreventDefault;
   CheckContentResponse();
 }
 
 void AsyncPanZoomController::CheckContentResponse() {
   bool canProceedToTouchState = true;
 
   if (mFrameMetrics.mMayHaveTouchListeners) {
-    canProceedToTouchState &= mPreventDefaultSet;
+    canProceedToTouchState &= mTouchBlockState.mPreventDefaultSet;
   }
 
   if (mTouchActionPropertyEnabled) {
-    canProceedToTouchState &= mAllowedTouchBehaviorSet;
+    canProceedToTouchState &= mTouchBlockState.mAllowedTouchBehaviorSet;
   }
 
   if (!canProceedToTouchState) {
     return;
   }
 
   if (mContentResponseTimeoutTask) {
     mContentResponseTimeoutTask->Cancel();
     mContentResponseTimeoutTask = nullptr;
   }
 
   if (mState == WAITING_CONTENT_RESPONSE) {
-    if (!mPreventDefault) {
+    if (!mTouchBlockState.mPreventDefault) {
       SetState(NOTHING);
     }
 
     mHandlingTouchQueue = true;
 
     while (!mTouchQueue.IsEmpty()) {
-      if (!mPreventDefault) {
+      if (!mTouchBlockState.mPreventDefault) {
         HandleInputEvent(mTouchQueue[0]);
       }
 
       if (mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_END ||
           mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_CANCEL) {
         mTouchQueue.RemoveElementAt(0);
         break;
       }
@@ -1942,66 +1959,66 @@ void AsyncPanZoomController::CheckConten
 
 bool AsyncPanZoomController::TouchActionAllowZoom() {
   if (!mTouchActionPropertyEnabled) {
     return true;
   }
 
   // Pointer events specification implies all touch points to allow zoom
   // to perform it.
-  for (size_t i = 0; i < mAllowedTouchBehaviors.Length(); i++) {
-    if (!(mAllowedTouchBehaviors[i] & AllowedTouchBehavior::ZOOM)) {
+  for (size_t i = 0; i < mTouchBlockState.mAllowedTouchBehaviors.Length(); i++) {
+    if (!(mTouchBlockState.mAllowedTouchBehaviors[i] & AllowedTouchBehavior::ZOOM)) {
       return false;
     }
   }
 
   return true;
 }
 
 AsyncPanZoomController::TouchBehaviorFlags
 AsyncPanZoomController::GetTouchBehavior(uint32_t touchIndex) {
-  if (touchIndex < mAllowedTouchBehaviors.Length()) {
-    return mAllowedTouchBehaviors[touchIndex];
+  if (touchIndex < mTouchBlockState.mAllowedTouchBehaviors.Length()) {
+    return mTouchBlockState.mAllowedTouchBehaviors[touchIndex];
   }
   return DefaultTouchBehavior;
 }
 
 AsyncPanZoomController::TouchBehaviorFlags
 AsyncPanZoomController::GetAllowedTouchBehavior(ScreenIntPoint& aPoint) {
   // Here we need to perform a hit testing over the touch-action regions attached to the
   // layer associated with current apzc.
   // Currently they are in progress, for more info see bug 928833.
   return AllowedTouchBehavior::UNKNOWN;
 }
 
 void AsyncPanZoomController::SetAllowedTouchBehavior(const nsTArray<TouchBehaviorFlags>& aBehaviors) {
-  mAllowedTouchBehaviors.Clear();
-  mAllowedTouchBehaviors.AppendElements(aBehaviors);
-  mAllowedTouchBehaviorSet = true;
+  mTouchBlockState.mAllowedTouchBehaviors.Clear();
+  mTouchBlockState.mAllowedTouchBehaviors.AppendElements(aBehaviors);
+  mTouchBlockState.mAllowedTouchBehaviorSet = true;
   CheckContentResponse();
 }
 
 void AsyncPanZoomController::SetState(PanZoomState aNewState) {
 
   PanZoomState oldState;
 
   // Intentional scoping for mutex
   {
     ReentrantMonitorAutoEnter lock(mMonitor);
     oldState = mState;
     mState = aNewState;
   }
 
   if (mGeckoContentController) {
     if (!IsTransformingState(oldState) && IsTransformingState(aNewState)) {
-      mGeckoContentController->NotifyTransformBegin(
-        ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.GetScrollId()));
+      mGeckoContentController->NotifyAPZStateChange(
+          GetGuid(), APZStateChange::TransformBegin);
     } else if (IsTransformingState(oldState) && !IsTransformingState(aNewState)) {
-      mGeckoContentController->NotifyTransformEnd(
-        ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.GetScrollId()));
+      mGeckoContentController->NotifyAPZStateChange(
+          GetGuid(), APZStateChange::TransformEnd);
     }
   }
 }
 
 bool AsyncPanZoomController::IsTransformingState(PanZoomState aState) {
   return !(aState == NOTHING || aState == TOUCHING || aState == WAITING_CONTENT_RESPONSE);
 }
 
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -310,16 +310,18 @@ public:
    * is done we should integrate its logic here.
    */
   TouchBehaviorFlags GetAllowedTouchBehavior(ScreenIntPoint& aPoint);
 
   /**
    * Sets allowed touch behavior for current touch session.
    * This method is invoked by the APZCTreeManager which in its turn invoked by
    * the widget after performing touch-action values retrieving.
+   * Must be called after receiving the TOUCH_START even that started the
+   * touch session.
    */
   void SetAllowedTouchBehavior(const nsTArray<TouchBehaviorFlags>& aBehaviors);
 
   /**
    * Returns whether this APZC is for an element marked with the 'scrollgrab'
    * attribute.
    */
   bool HasScrollgrab() const { return mFrameMetrics.mHasScrollgrab; }
@@ -327,16 +329,21 @@ public:
   /**
    * Set an extra offset for testing async scrolling.
    */
   void SetTestAsyncScrollOffset(const CSSPoint& aPoint)
   {
     mTestAsyncScrollOffset = aPoint;
   }
 
+  /**
+   * Returns whether this APZC has room to be panned (in any direction).
+   */
+  bool IsPannable() const;
+
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   ~AsyncPanZoomController();
 
   /**
    * Helper method for touches beginning. Sets everything up for panning and any
    * multitouch gestures.
    */
@@ -552,16 +559,46 @@ private:
     PINCHING,                 /* nth touch-start, where n > 1. this mode allows pan and zoom */
     ANIMATING_ZOOM,           /* animated zoom to a new rect */
     WAITING_CONTENT_RESPONSE, /* a state halfway between NOTHING and TOUCHING - the user has
                                  put a finger down, but we don't yet know if a touch listener has
                                  prevented the default actions yet and the allowed touch behavior
                                  was not set yet. we still need to abort animations. */
   };
 
+  // State related to a single touch block. Does not persist across touch blocks.
+  struct TouchBlockState {
+
+    TouchBlockState()
+      :  mAllowedTouchBehaviorSet(false),
+         mPreventDefault(false),
+         mPreventDefaultSet(false),
+         mSingleTapOccurred(false)
+    {}
+
+    // Values of allowed touch behavior for touch points of this touch block.
+    // Since there are maybe a few current active touch points per time (multitouch case)
+    // and each touch point should have its own value of allowed touch behavior- we're
+    // keeping an array of allowed touch behavior values, not the single value.
+    nsTArray<TouchBehaviorFlags> mAllowedTouchBehaviors;
+
+    // Specifies whether mAllowedTouchBehaviors is set for this touch events block.
+    bool mAllowedTouchBehaviorSet;
+
+    // Flag used to specify that content prevented the default behavior of this
+    // touch events block.
+    bool mPreventDefault;
+
+    // Specifies whether mPreventDefault property is set for this touch events block.
+    bool mPreventDefaultSet;
+
+    // Specifies whether a single tap event was generated during this touch block.
+    bool mSingleTapOccurred;
+  };
+
   /*
    * Returns whether current touch behavior values allow zooming.
    */
   bool TouchActionAllowZoom();
 
   /*
    * Returns allowed touch behavior from the mAllowedTouchBehavior array.
    * In case apzc didn't receive touch behavior values within the timeout
@@ -612,16 +649,22 @@ private:
   // coordinates but the composition bounds is in parent layer coordinates.
   ParentLayerPoint ToParentLayerCoords(const ScreenPoint& aPoint);
 
   // Update mFrameMetrics.mTransformScale. This should be called whenever
   // our CSS transform or the non-transient part of our async transform
   // changes, as it corresponds to the scale portion of those transforms.
   void UpdateTransformScale();
 
+  // Helper function for OnSingleTapUp() and OnSingleTapConfirmed().
+  nsEventStatus GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers);
+
+  // Common processing at the end of a touch block.
+  void OnTouchEndOrCancel();
+
   uint64_t mLayersId;
   nsRefPtr<CompositorParent> mCompositorParent;
   PCompositorParent* mCrossProcessCompositorParent;
   TaskThrottler mPaintThrottler;
 
   /* Access to the following two fields is protected by the mRefPtrMonitor,
      since they are accessed on the UI thread but can be cleared on the
      compositor thread. */
@@ -638,17 +681,19 @@ protected:
   // monitor. Do not read from or modify either of them without locking.
   FrameMetrics mFrameMetrics;
 
   // Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|.
   // Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
   // monitor should be held. When setting |mState|, either the SetState()
   // function can be used, or the monitor can be held and then |mState| updated.
   // IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
-  ReentrantMonitor mMonitor;
+  // This is mutable to allow entering it from 'const' methods; doing otherwise
+  // would significantly limit what methods could be 'const'.
+  mutable ReentrantMonitor mMonitor;
 
   // Specifies whether we should use touch-action css property. Initialized from
   // the preferences. This property (in comparison with the global one) simplifies
   // testing apzc with (and without) touch-action property enabled concurrently
   // (e.g. with the gtest framework).
   bool mTouchActionPropertyEnabled;
 
 private:
@@ -713,31 +758,18 @@ private:
   CancelableTask* mAsyncScrollTimeoutTask;
 
   // Flag used to determine whether or not we should try to enter the
   // WAITING_LISTENERS state. This is used in the case that we are processing a
   // queued up event block. If set, this means that we are handling this queue
   // and we don't want to queue the events back up again.
   bool mHandlingTouchQueue;
 
-  // Values of allowed touch behavior for current touch points.
-  // Since there are maybe a few current active touch points per time (multitouch case)
-  // and each touch point should have its own value of allowed touch behavior- we're
-  // keeping an array of allowed touch behavior values, not the single value.
-  nsTArray<TouchBehaviorFlags> mAllowedTouchBehaviors;
-
-  // Specifies whether mAllowedTouchBehaviors is set for current touch events block.
-  bool mAllowedTouchBehaviorSet;
-
-  // Flag used to specify that content prevented the default behavior of the current
-  // touch events block.
-  bool mPreventDefault;
-
-  // Specifies whether mPreventDefault property is set for current touch events block.
-  bool mPreventDefaultSet;
+  // Stores information about the current touch block.
+  TouchBlockState mTouchBlockState;
 
   // Extra offset to add in SampleContentTransformForFrame for testing
   CSSPoint mTestAsyncScrollOffset;
 
   RefPtr<AsyncPanZoomAnimation> mAnimation;
 
   friend class Axis;
   friend class FlingAnimation;
--- a/gfx/layers/ipc/Axis.cpp
+++ b/gfx/layers/ipc/Axis.cpp
@@ -202,89 +202,95 @@ float Axis::ScaleWillOverscrollAmount(fl
 float Axis::GetVelocity() {
   return mAxisLocked ? 0 : mVelocity;
 }
 
 void Axis::SetVelocity(float aVelocity) {
   mVelocity = aVelocity;
 }
 
-float Axis::GetCompositionEnd() {
+float Axis::GetCompositionEnd() const {
   return GetOrigin() + GetCompositionLength();
 }
 
-float Axis::GetPageEnd() {
+float Axis::GetPageEnd() const {
   return GetPageStart() + GetPageLength();
 }
 
-float Axis::GetOrigin() {
+float Axis::GetOrigin() const {
   CSSPoint origin = mAsyncPanZoomController->GetFrameMetrics().GetScrollOffset();
   return GetPointOffset(origin);
 }
 
-float Axis::GetCompositionLength() {
+float Axis::GetCompositionLength() const {
   const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
   return GetRectLength(metrics.CalculateCompositedRectInCssPixels());
 }
 
-float Axis::GetPageStart() {
+float Axis::GetPageStart() const {
   CSSRect pageRect = mAsyncPanZoomController->GetFrameMetrics().mScrollableRect;
   return GetRectOffset(pageRect);
 }
 
-float Axis::GetPageLength() {
+float Axis::GetPageLength() const {
   CSSRect pageRect = mAsyncPanZoomController->GetFrameMetrics().mScrollableRect;
   return GetRectLength(pageRect);
 }
 
 bool Axis::ScaleWillOverscrollBothSides(float aScale) {
   const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
 
   CSSToParentLayerScale scale(metrics.GetZoomToParent().scale * aScale);
   CSSRect cssCompositionBounds = metrics.mCompositionBounds / scale;
 
   return GetRectLength(metrics.mScrollableRect) < GetRectLength(cssCompositionBounds);
 }
 
+bool Axis::HasRoomToPan() const {
+  return GetOrigin() > GetPageStart()
+      || GetCompositionEnd() < GetPageEnd();
+}
+
+
 AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
   : Axis(aAsyncPanZoomController)
 {
 
 }
 
-float AxisX::GetPointOffset(const CSSPoint& aPoint)
+float AxisX::GetPointOffset(const CSSPoint& aPoint) const
 {
   return aPoint.x;
 }
 
-float AxisX::GetRectLength(const CSSRect& aRect)
+float AxisX::GetRectLength(const CSSRect& aRect) const
 {
   return aRect.width;
 }
 
-float AxisX::GetRectOffset(const CSSRect& aRect)
+float AxisX::GetRectOffset(const CSSRect& aRect) const
 {
   return aRect.x;
 }
 
 AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController)
   : Axis(aAsyncPanZoomController)
 {
 
 }
 
-float AxisY::GetPointOffset(const CSSPoint& aPoint)
+float AxisY::GetPointOffset(const CSSPoint& aPoint) const
 {
   return aPoint.y;
 }
 
-float AxisY::GetRectLength(const CSSRect& aRect)
+float AxisY::GetRectLength(const CSSRect& aRect) const
 {
   return aRect.height;
 }
 
-float AxisY::GetRectOffset(const CSSRect& aRect)
+float AxisY::GetRectOffset(const CSSRect& aRect) const
 {
   return aRect.y;
 }
 
 }
 }
--- a/gfx/layers/ipc/Axis.h
+++ b/gfx/layers/ipc/Axis.h
@@ -165,50 +165,55 @@ public:
    * Checks if an axis will overscroll in both directions by computing the
    * content rect and checking that its height/width (depending on the axis)
    * does not overextend past the viewport.
    *
    * This gets called by ScaleWillOverscroll().
    */
   bool ScaleWillOverscrollBothSides(float aScale);
 
-  float GetOrigin();
-  float GetCompositionLength();
-  float GetPageStart();
-  float GetPageLength();
-  float GetCompositionEnd();
-  float GetPageEnd();
+  /**
+   * Returns whether there is room to pan on this axis in either direction.
+   */
+  bool HasRoomToPan() const;
+
+  float GetOrigin() const;
+  float GetCompositionLength() const;
+  float GetPageStart() const;
+  float GetPageLength() const;
+  float GetCompositionEnd() const;
+  float GetPageEnd() const;
 
   int32_t GetPos() const { return mPos; }
 
-  virtual float GetPointOffset(const CSSPoint& aPoint) = 0;
-  virtual float GetRectLength(const CSSRect& aRect) = 0;
-  virtual float GetRectOffset(const CSSRect& aRect) = 0;
+  virtual float GetPointOffset(const CSSPoint& aPoint) const = 0;
+  virtual float GetRectLength(const CSSRect& aRect) const = 0;
+  virtual float GetRectOffset(const CSSRect& aRect) const = 0;
 
 protected:
   int32_t mPos;
   int32_t mStartPos;
   float mVelocity;
   bool mAxisLocked;     // Whether movement on this axis is locked.
   AsyncPanZoomController* mAsyncPanZoomController;
   nsTArray<float> mVelocityQueue;
 };
 
 class AxisX : public Axis {
 public:
   AxisX(AsyncPanZoomController* mAsyncPanZoomController);
-  virtual float GetPointOffset(const CSSPoint& aPoint);
-  virtual float GetRectLength(const CSSRect& aRect);
-  virtual float GetRectOffset(const CSSRect& aRect);
+  virtual float GetPointOffset(const CSSPoint& aPoint) const;
+  virtual float GetRectLength(const CSSRect& aRect) const;
+  virtual float GetRectOffset(const CSSRect& aRect) const;
 };
 
 class AxisY : public Axis {
 public:
   AxisY(AsyncPanZoomController* mAsyncPanZoomController);
-  virtual float GetPointOffset(const CSSPoint& aPoint);
-  virtual float GetRectLength(const CSSRect& aRect);
-  virtual float GetRectOffset(const CSSRect& aRect);
+  virtual float GetPointOffset(const CSSPoint& aPoint) const;
+  virtual float GetRectLength(const CSSRect& aRect) const;
+  virtual float GetRectOffset(const CSSRect& aRect) const;
 };
 
 }
 }
 
 #endif
--- a/gfx/layers/ipc/GeckoContentController.h
+++ b/gfx/layers/ipc/GeckoContentController.h
@@ -108,27 +108,58 @@ public:
    * APZ can then get the correct touch-sensitive region for each frame
    * directly from the layer.
    */
   virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion)
   {
     return false;
   }
 
+  MOZ_BEGIN_NESTED_ENUM_CLASS(APZStateChange, int8_t)
+    /**
+     * APZ started modifying the view (including panning, zooming, and fling).
+     */
+    TransformBegin,
+    /**
+     * APZ finished modifying the view.
+     */
+    TransformEnd,
+    /**
+     * APZ started a touch.
+     * |aArg| is 1 if touch can be a pan, 0 otherwise.
+     */
+    StartTouch,
+    /**
+     * APZ started a pan.
+     */
+    StartPanning,
+    /**
+     * APZ finished processing a touch.
+     * |aArg| is 1 if touch was a click, 0 otherwise.
+     */
+    EndTouch,
+    APZStateChangeSentinel
+  MOZ_END_NESTED_ENUM_CLASS(APZStateChange)
+
   /**
-   * General tranformation notices for consumers. These fire any time
-   * the apzc is modifying the view, including panning, zooming, and
-   * fling.
+   * General notices of APZ state changes for consumers.
+   * |aGuid| identifies the APZC originating the state change.
+   * |aChange| identifies the type of state change
+   * |aArg| is used by some state changes to pass extra information (see
+   *        the documentation for each state change above)
    */
-  virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid) {}
-  virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid) {}
+  virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+                                    APZStateChange aChange,
+                                    int aArg = 0) {}
 
   GeckoContentController() {}
 
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~GeckoContentController() {}
 };
 
+MOZ_FINISH_NESTED_ENUM_CLASS(GeckoContentController::APZStateChange)
+
 }
 }
 
 #endif // mozilla_layers_GeckoContentController_h
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -326,38 +326,30 @@ static void ReleaseImageClientNow(ImageC
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient)
 {
-  if (!IsCreated()) {
-    return;
-  }
-
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseImageClientNow, aClient));
 }
 
 static void ReleaseTextureClientNow(TextureClient* aClient)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
 {
-  if (!IsCreated()) {
-    return;
-  }
-
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
 static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContainer)
 {
   MOZ_ASSERT(aClient);
@@ -367,20 +359,16 @@ static void UpdateImageClientNow(ImageCl
   aClient->OnTransaction();
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 //static
 void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
                                                  ImageContainer* aContainer)
 {
-  if (!IsCreated()) {
-    return;
-  }
-
   if (InImageBridgeChildThread()) {
     UpdateImageClientNow(aClient, aContainer);
     return;
   }
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction<
       void (*)(ImageClient*, ImageContainer*),
@@ -395,20 +383,16 @@ static void FlushAllImagesSync(ImageClie
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
   *aDone = true;
   aBarrier->NotifyAll();
 }
 
 //static
 void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront)
 {
-  if (!IsCreated()) {
-    return;
-  }
-
   if (InImageBridgeChildThread()) {
     FlushAllImagesNow(aClient, aContainer, aExceptFront);
     return;
   }
 
   ReentrantMonitor barrier("CreateImageClient Lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
@@ -588,24 +572,25 @@ bool ImageBridgeChild::StartUpOnThread(T
     return true;
   } else {
     return false;
   }
 }
 
 void ImageBridgeChild::DestroyBridge()
 {
-  if (!IsCreated()) {
-    return;
-  }
   NS_ABORT_IF_FALSE(!InImageBridgeChildThread(),
                     "This method must not be called in this thread.");
   // ...because we are about to dispatch synchronous messages to the
   // ImageBridgeChild thread.
 
+  if (!IsCreated()) {
+    return;
+  }
+
   ReentrantMonitor barrier("ImageBridgeDestroyTask lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
 
   bool done = false;
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
                   NewRunnableFunction(&StopImageBridgeSync, &barrier, &done));
   while (!done) {
     barrier.Wait();
@@ -617,18 +602,17 @@ void ImageBridgeChild::DestroyBridge()
   while (!done) {
     barrier.Wait();
   }
 
 }
 
 bool InImageBridgeChildThread()
 {
-  return ImageBridgeChild::IsCreated() &&
-    sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
+  return sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
 }
 
 MessageLoop * ImageBridgeChild::GetMessageLoop() const
 {
   return sImageBridgeChildThread->message_loop();
 }
 
 void ImageBridgeChild::ConnectAsync(ImageBridgeParent* aParent)
--- a/gfx/layers/ipc/LayerTransactionChild.h
+++ b/gfx/layers/ipc/LayerTransactionChild.h
@@ -18,38 +18,35 @@ namespace mozilla {
 
 namespace layout {
 class RenderFrameChild;
 }
 
 namespace layers {
 
 class LayerTransactionChild : public PLayerTransactionChild
-                            , public AtomicRefCounted<LayerTransactionChild>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(LayerTransactionChild)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LayerTransactionChild)
   /**
    * Clean this up, finishing with Send__delete__().
    *
    * It is expected (checked with an assert) that all shadow layers
    * created by this have already been destroyed and
    * Send__delete__()d by the time this method is called.
    */
   void Destroy();
 
   bool IPCOpen() const { return mIPCOpen; }
 
 protected:
   LayerTransactionChild()
     : mIPCOpen(false)
   {}
   ~LayerTransactionChild() { }
-  friend class AtomicRefCounted<LayerTransactionChild>;
-  friend class detail::RefCounted<LayerTransactionChild, detail::AtomicRefCount>;
 
   virtual PGrallocBufferChild*
   AllocPGrallocBufferChild(const IntSize&,
                            const uint32_t&, const uint32_t&,
                            MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
   virtual bool
   DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
 
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -59,22 +59,23 @@ struct EffectChain;
  * Interface for pools of temporary gl textures for the compositor.
  * The textures are fully owned by the pool, so the latter is responsible
  * calling fDeleteTextures accordingly.
  * Users of GetTexture receive a texture that is only valid for the duration
  * of the current frame.
  * This is primarily intended for direct texturing APIs that need to attach
  * shared objects (such as an EGLImage) to a gl texture.
  */
-class CompositorTexturePoolOGL : public RefCounted<CompositorTexturePoolOGL>
+class CompositorTexturePoolOGL
 {
+protected:
+  virtual ~CompositorTexturePoolOGL() {}
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositorTexturePoolOGL)
-
-  virtual ~CompositorTexturePoolOGL() {}
+  NS_INLINE_DECL_REFCOUNTING(CompositorTexturePoolOGL)
 
   virtual void Clear() = 0;
 
   virtual GLuint GetTexture(GLenum aTarget, GLenum aEnum) = 0;
 
   virtual void EndFrame() = 0;
 };
 
--- a/gfx/src/FilterSupport.cpp
+++ b/gfx/src/FilterSupport.cpp
@@ -225,20 +225,20 @@ namespace FilterWrappers {
 // A class that wraps a FilterNode and handles conversion between different
 // color models. Create FilterCachedColorModels with your original filter and
 // the color model that this filter outputs in natively, and then call
 // ->ForColorModel(colorModel) in order to get a FilterNode which outputs to
 // the specified colorModel.
 // Internally, this is achieved by wrapping the original FilterNode with
 // conversion FilterNodes. These filter nodes are cached in such a way that no
 // repeated or back-and-forth conversions happen.
-class FilterCachedColorModels : public RefCounted<FilterCachedColorModels>
+class FilterCachedColorModels
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(FilterCachedColorModels)
+  NS_INLINE_DECL_REFCOUNTING(FilterCachedColorModels)
   // aFilter can be null. In that case, ForColorModel will return a non-null
   // completely transparent filter for all color models.
   FilterCachedColorModels(DrawTarget* aDT,
                           FilterNode* aFilter,
                           ColorModel aOriginalColorModel);
 
   // Get a FilterNode for the specified color model, guaranteed to be non-null.
   TemporaryRef<FilterNode> ForColorModel(ColorModel aColorModel);
--- a/gfx/src/nsRenderingContext.h
+++ b/gfx/src/nsRenderingContext.h
@@ -29,25 +29,24 @@ struct nsRect;
 
 typedef enum {
     nsLineStyle_kNone   = 0,
     nsLineStyle_kSolid  = 1,
     nsLineStyle_kDashed = 2,
     nsLineStyle_kDotted = 3
 } nsLineStyle;
 
-class nsRenderingContext
+class nsRenderingContext MOZ_FINAL
 {
     typedef mozilla::gfx::UserData UserData;
     typedef mozilla::gfx::UserDataKey UserDataKey;
     typedef mozilla::gfx::DrawTarget DrawTarget;
 
 public:
     nsRenderingContext() : mP2A(0.) {}
-    // ~nsRenderingContext() {}
 
     NS_INLINE_DECL_REFCOUNTING(nsRenderingContext)
 
     void Init(nsDeviceContext* aContext, gfxASurface* aThebesSurface);
     void Init(nsDeviceContext* aContext, gfxContext* aThebesContext);
     void Init(nsDeviceContext* aContext, DrawTarget* aDrawTarget);
 
     // These accessors will never return null.
@@ -125,17 +124,22 @@ public:
     }
     void *GetUserData(UserDataKey *key) {
       return mUserData.Get(key);
     }
     void *RemoveUserData(UserDataKey *key) {
       return mUserData.Remove(key);
     }
 
-protected:
+private:
+    // Private destructor, to discourage deletion outside of Release():
+    ~nsRenderingContext()
+    {
+    }
+
     int32_t GetMaxChunkLength();
 
     nsRefPtr<gfxContext> mThebes;
     nsRefPtr<nsDeviceContext> mDeviceContext;
     nsRefPtr<nsFontMetrics> mFontMetrics;
 
     double mP2A; // cached app units per device pixel value
 
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -163,17 +163,24 @@ FrameMetrics TestFrameMetrics() {
   return fm;
 }
 
 /*
  * Dispatches mock touch events to the apzc and checks whether apzc properly
  * consumed them and triggered scrolling behavior.
  */
 static
-void ApzcPan(AsyncPanZoomController* apzc, TestAPZCTreeManager* aTreeManager, int& aTime, int aTouchStartY, int aTouchEndY, bool expectIgnoredPan = false, bool hasTouchListeners = false) {
+void ApzcPan(AsyncPanZoomController* apzc,
+             TestAPZCTreeManager* aTreeManager,
+             int& aTime,
+             int aTouchStartY,
+             int aTouchEndY,
+             bool expectIgnoredPan = false,
+             bool hasTouchListeners = false,
+             nsTArray<uint32_t>* aAllowedTouchBehaviors = nullptr) {
 
   const int TIME_BETWEEN_TOUCH_EVENT = 100;
   const int OVERCOME_TOUCH_TOLERANCE = 100;
   MultiTouchInput mti;
   nsEventStatus status;
 
   // Since we're passing inputs directly to the APZC instead of going through
   // the tree manager, we need to build the overscroll handoff chain explicitly
@@ -193,16 +200,21 @@ void ApzcPan(AsyncPanZoomController* apz
   mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, aTime, 0);
   aTime += TIME_BETWEEN_TOUCH_EVENT;
   // Make sure the move is large enough to not be handled as a tap
   mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, aTouchStartY+OVERCOME_TOUCH_TOLERANCE), ScreenSize(0, 0), 0, 0));
   status = apzc->ReceiveInputEvent(mti);
   EXPECT_EQ(status, touchStartStatus);
   // APZC should be in TOUCHING state
 
+  // Allowed touch behaviours must be set after sending touch-start.
+  if (aAllowedTouchBehaviors) {
+    apzc->SetAllowedTouchBehavior(*aAllowedTouchBehaviors);
+  }
+
   nsEventStatus touchMoveStatus;
   if (expectIgnoredPan) {
     // APZC should ignore panning, be in TOUCHING state and therefore return eIgnore.
     // The same applies to all consequent touch move events.
     touchMoveStatus = nsEventStatus_eIgnore;
   } else {
     // APZC should go into the panning state and therefore consume the event.
     touchMoveStatus = nsEventStatus_eConsumeNoDefault;
@@ -249,35 +261,33 @@ void DoPanTest(bool aShouldTriggerScroll
   }
 
   int time = 0;
   int touchStart = 50;
   int touchEnd = 10;
   ScreenPoint pointOut;
   ViewTransform viewTransformOut;
 
-  nsTArray<uint32_t> values;
-  values.AppendElement(aBehavior);
+  nsTArray<uint32_t> allowedTouchBehaviors;
+  allowedTouchBehaviors.AppendElement(aBehavior);
 
   // Pan down
-  apzc->SetAllowedTouchBehavior(values);
-  ApzcPan(apzc, tm, time, touchStart, touchEnd, !aShouldTriggerScroll);
+  ApzcPan(apzc, tm, time, touchStart, touchEnd, !aShouldTriggerScroll, false, &allowedTouchBehaviors);
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
 
   if (aShouldTriggerScroll) {
     EXPECT_EQ(pointOut, ScreenPoint(0, -(touchEnd-touchStart)));
     EXPECT_NE(viewTransformOut, ViewTransform());
   } else {
     EXPECT_EQ(pointOut, ScreenPoint());
     EXPECT_EQ(viewTransformOut, ViewTransform());
   }
 
   // Pan back
-  apzc->SetAllowedTouchBehavior(values);
-  ApzcPan(apzc, tm, time, touchEnd, touchStart, !aShouldTriggerScroll);
+  ApzcPan(apzc, tm, time, touchEnd, touchStart, !aShouldTriggerScroll, false, &allowedTouchBehaviors);
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
 
   EXPECT_EQ(pointOut, ScreenPoint());
   EXPECT_EQ(viewTransformOut, ViewTransform());
 
   apzc->Destroy();
 }
 
@@ -608,21 +618,20 @@ TEST_F(AsyncPanZoomControllerTester, Pan
 
   int time = 0;
   int touchStart = 50;
   int touchEnd = 10;
   ScreenPoint pointOut;
   ViewTransform viewTransformOut;
 
   // Pan down
-  nsTArray<uint32_t> values;
-  values.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
+  nsTArray<uint32_t> allowedTouchBehaviors;
+  allowedTouchBehaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
   apzc->SetTouchActionEnabled(true);
-  apzc->SetAllowedTouchBehavior(values);
-  ApzcPan(apzc, tm, time, touchStart, touchEnd, true, true);
+  ApzcPan(apzc, tm, time, touchStart, touchEnd, true, true, &allowedTouchBehaviors);
 
   // Send the signal that content has handled and preventDefaulted the touch
   // events. This flushes the event queue.
   apzc->ContentReceivedTouch(true);
 
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
   EXPECT_EQ(pointOut, ScreenPoint());
   EXPECT_EQ(viewTransformOut, ViewTransform());
@@ -741,26 +750,28 @@ DoLongPressTest(bool aShouldUseTouchActi
   nsRefPtr<TestAPZCTreeManager> tm = new TestAPZCTreeManager();
   nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(
     0, mcc, tm, AsyncPanZoomController::USE_GESTURE_DETECTOR);
 
   apzc->SetFrameMetrics(TestFrameMetrics());
   apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
   apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
 
-  nsTArray<uint32_t> values;
-  values.AppendElement(aBehavior);
   apzc->SetTouchActionEnabled(aShouldUseTouchAction);
-  apzc->SetAllowedTouchBehavior(values);
 
   int time = 0;
 
   nsEventStatus status = ApzcDown(apzc, 10, 10, time);
   EXPECT_EQ(nsEventStatus_eConsumeNoDefault, status);
 
+  // SetAllowedTouchBehavior() must be called after sending touch-start.
+  nsTArray<uint32_t> allowedTouchBehaviors;
+  allowedTouchBehaviors.AppendElement(aBehavior);
+  apzc->SetAllowedTouchBehavior(allowedTouchBehaviors);
+
   MockFunction<void(std::string checkPointName)> check;
 
   {
     InSequence s;
 
     EXPECT_CALL(check, Call("preHandleLongTap"));
     EXPECT_CALL(*mcc, HandleLongTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
     EXPECT_CALL(check, Call("postHandleLongTap"));
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -68,22 +68,24 @@
 #include "nsCRT.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "TexturePoolOGL.h"
 #endif
 
+#include "mozilla/Hal.h"
 #ifdef USE_SKIA
-#include "mozilla/Hal.h"
 #include "skia/SkGraphics.h"
 
 #include "SkiaGLGlue.h"
-
+#else
+class mozilla::gl::SkiaGLGlue : public GenericAtomicRefCounted {
+};
 #endif
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 
 #include "nsIGfxInfo.h"
@@ -486,16 +488,22 @@ gfxPlatform::Shutdown()
     // most platforms.  Windows is a "special snowflake", though, and has three
     // context providers available, so we have to shut all of them down.
     // We should only support the default GL provider on Windows; then, this
     // could go away. Unfortunately, we currently support WGL (the default) for
     // WebGL on Optimus.
     mozilla::gl::GLContextProviderEGL::Shutdown();
 #endif
 
+    // This will block this thread untill the ImageBridge protocol is completely
+    // deleted.
+    ImageBridgeChild::ShutDown();
+
+    CompositorParent::ShutDown();
+
     delete gGfxPlatformPrefsLock;
 
     gfxPrefs::DestroySingleton();
     gfxFont::DestroySingletons();
 
     delete gPlatform;
     gPlatform = nullptr;
 }
@@ -917,17 +925,19 @@ gfxPlatform::InitializeSkiaCacheLimits()
         cacheSizeLimit = totalMemory / 16;
       }
     }
 
   #ifdef DEBUG
     printf_stderr("Determined SkiaGL cache limits: Size %i, Items: %i\n", cacheSizeLimit, cacheItemLimit);
   #endif
 
+#ifdef USE_SKIA_GPU
     mSkiaGlue->GetGrContext()->setTextureCacheLimits(cacheItemLimit, cacheSizeLimit);
+#endif
   }
 }
 
 mozilla::gl::SkiaGLGlue*
 gfxPlatform::GetSkiaGLGlue()
 {
 #ifdef USE_SKIA_GPU
   if (!mSkiaGlue) {
--- a/hal/HalWakeLock.cpp
+++ b/hal/HalWakeLock.cpp
@@ -7,17 +7,17 @@
 #include "mozilla/HalWakeLock.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/dom/ContentParent.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIPropertyBag2.h"
-#include "nsObserverService.h"
+#include "nsIObserverService.h"
 
 using namespace mozilla;
 using namespace mozilla::hal;
 
 namespace {
 
 struct LockCount {
   LockCount()
--- a/hal/cocoa/CocoaBattery.cpp
+++ b/hal/cocoa/CocoaBattery.cpp
@@ -7,17 +7,18 @@
 #import <CoreFoundation/CoreFoundation.h>
 #import <IOKit/ps/IOPowerSources.h>
 #import <IOKit/ps/IOPSKeys.h>
 
 #include <mozilla/Hal.h>
 #include <mozilla/dom/battery/Constants.h>
 #include <mozilla/Services.h>
 
-#include <nsObserverService.h>
+#include <nsIObserverService.h>
+#include <nsIObserver.h>
 
 #include <dlfcn.h>
 
 #define IOKIT_FRAMEWORK_PATH "/System/Library/Frameworks/IOKit.framework/IOKit"
 
 #ifndef kIOPSTimeRemainingUnknown
   #define kIOPSTimeRemainingUnknown ((CFTimeInterval)-1.0)
 #endif
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -289,21 +289,21 @@ public:
 
     hal::NotifyBatteryChange(info);
     return NS_OK;
   }
 };
 
 } // anonymous namespace
 
-class BatteryObserver : public IUeventObserver,
-                        public RefCounted<BatteryObserver>
+class BatteryObserver : public IUeventObserver
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(BatteryObserver)
+  NS_INLINE_DECL_REFCOUNTING(BatteryObserver)
+
   BatteryObserver()
     :mUpdater(new BatteryUpdater())
   {
   }
 
   virtual void Notify(const NetlinkEvent &aEvent)
   {
     // this will run on IO thread
--- a/hal/gonk/GonkSwitch.cpp
+++ b/hal/gonk/GonkSwitch.cpp
@@ -46,20 +46,21 @@ namespace hal_impl {
  *  change@/devices/virtual/switch/usb_configuration
  *    ACTION=change
  *    DEVPATH=/devices/virtual/switch/usb_configuration
  *    SUBSYSTEM=switch
  *    SWITCH_NAME=usb_configuration
  *    SWITCH_STATE=0
  *    SEQNUM=5038
  */
-class SwitchHandler : public RefCounted<SwitchHandler>
+class SwitchHandler
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(SwitchHandler)
+  NS_INLINE_DECL_REFCOUNTING(SwitchHandler)
+
   SwitchHandler(const char* aDevPath, SwitchDevice aDevice)
     : mDevPath(aDevPath),
       mState(SWITCH_STATE_UNKNOWN),
       mDevice(aDevice)
   {
     GetInitialState();
   }
 
@@ -225,31 +226,30 @@ public:
   {
     NotifySwitchChange(mEvent);
     return NS_OK;
   }
 private:
   SwitchEvent mEvent;
 };
 
-class SwitchEventObserver : public IUeventObserver,
-                            public RefCounted<SwitchEventObserver>
+class SwitchEventObserver MOZ_FINAL : public IUeventObserver
 {
+  ~SwitchEventObserver()
+  {
+    mHandler.Clear();
+  }
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(SwitchEventObserver)
+  NS_INLINE_DECL_REFCOUNTING(SwitchEventObserver)
   SwitchEventObserver() : mEnableCount(0)
   {
     Init();
   }
 
-  ~SwitchEventObserver()
-  {
-    mHandler.Clear();
-  }
-
   int GetEnableCount()
   {
     return mEnableCount;
   }
 
   void EnableSwitch(SwitchDevice aDevice)
   {
     mEventInfo[aDevice].mEnabled = true;
--- a/image/public/imgIContainer.idl
+++ b/image/public/imgIContainer.idl
@@ -8,16 +8,18 @@
 
 %{C++
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxRect.h"
 #include "GraphicsFilter.h"
 #include "gfxASurface.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "nsRect.h"
 #include "nsSize.h"
 #include "limits.h"
 
 namespace mozilla {
 namespace layers {
 class LayerManager;
 class ImageContainer;
@@ -50,27 +52,27 @@ native gfxGraphicsFilter(GraphicsFilter)
 [ref] native nsIntSize(nsIntSize);
 native nsSize(nsSize);
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native ImageContainer(mozilla::layers::ImageContainer);
 [ptr] native LayerManager(mozilla::layers::LayerManager);
 native Orientation(mozilla::image::Orientation);
 [ref] native TimeStamp(mozilla::TimeStamp);
 [ptr] native SVGImageContext(mozilla::SVGImageContext);
-native already_AddRefed_gfxASurface(already_AddRefed<gfxASurface>);
+native TempRefSourceSurface(mozilla::TemporaryRef<mozilla::gfx::SourceSurface>);
 
 
 /**
  * imgIContainer is the interface that represents an image. It allows
  * access to frames as Thebes surfaces. It also allows drawing of images
  * onto Thebes contexts.
  *
  * Internally, imgIContainer also manages animation of images.
  */
-[scriptable, builtinclass, uuid(8b7db7dd-bfe9-40d3-9114-3a79c0658afd)]
+[scriptable, builtinclass, uuid(503a830c-734d-4362-91f6-73f83ac59646)]
 interface imgIContainer : nsISupports
 {
   /**
    * The width of the container rectangle.  In the case of any error,
    * zero is returned, and an exception will be thrown.
    */
   readonly attribute int32_t width;
 
@@ -145,16 +147,17 @@ interface imgIContainer : nsISupports
    */
 
   const long FLAG_NONE            = 0x0;
   const long FLAG_SYNC_DECODE     = 0x1;
   const long FLAG_DECODE_NO_PREMULTIPLY_ALPHA = 0x2;
   const long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x4;
   const long FLAG_CLAMP           = 0x8;
   const long FLAG_HIGH_QUALITY_SCALING = 0x10;
+  const long FLAG_WANT_DATA_SURFACE = 0x20;
 
   /**
     * Constants for specifying various "special" frames.
     *
     * FRAME_FIRST: The first frame
     * FRAME_CURRENT: The current frame
     *
     * FRAME_MAX_VALUE should be set to the value of the maximum constant above,
@@ -168,19 +171,18 @@ interface imgIContainer : nsISupports
    * Get a surface for the given frame. This may be a platform-native,
    * optimized surface, so you cannot inspect its pixel data. If you
    * need that, use gfxASurface::GetAsReadableARGB32ImageSurface or
    * gfxASurface::CopyToARGB32ImageSurface.
    *
    * @param aWhichFrame Frame specifier of the FRAME_* variety.
    * @param aFlags Flags of the FLAG_* variety
    */
-  [noscript, notxpcom] already_AddRefed_gfxASurface
-                         getFrame(in uint32_t aWhichFrame,
-                                  in uint32_t aFlags);
+  [noscript, notxpcom] TempRefSourceSurface getFrame(in uint32_t aWhichFrame,
+                                                     in uint32_t aFlags);
 
   /**
    * Whether the given frame is opaque; that is, needs the background painted
    * behind it.
    *
    * @param aWhichFrame Frame specifier of the FRAME_* variety.
    */
   [notxpcom] boolean frameIsOpaque(in uint32_t aWhichFrame);
--- a/image/src/ClippedImage.cpp
+++ b/image/src/ClippedImage.cpp
@@ -1,31 +1,35 @@
 /* -*- 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 "gfxDrawable.h"
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 
 #include "ClippedImage.h"
 #include "Orientation.h"
 #include "SVGImageContext.h"
 
+using namespace mozilla;
+using namespace mozilla::gfx;
 using mozilla::layers::LayerManager;
 using mozilla::layers::ImageContainer;
 
 namespace mozilla {
 namespace image {
 
 class ClippedImageCachedSurface
 {
 public:
-  ClippedImageCachedSurface(mozilla::gfx::DrawTarget* aSurface,
+  ClippedImageCachedSurface(TemporaryRef<SourceSurface> aSurface,
                             const nsIntSize& aViewportSize,
                             const SVGImageContext* aSVGContext,
                             float aFrame,
                             uint32_t aFlags)
     : mSurface(aSurface)
     , mViewportSize(aViewportSize)
     , mFrame(aFrame)
     , mFlags(aFlags)
@@ -44,23 +48,22 @@ public:
     bool matchesSVGContext = (!aSVGContext && mSVGContext.empty()) ||
                              *aSVGContext == mSVGContext.ref();
     return mViewportSize == aViewportSize &&
            matchesSVGContext &&
            mFrame == aFrame &&
            mFlags == aFlags;
   }
 
-  already_AddRefed<gfxASurface> Surface() {
-    nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mSurface);
-    return surf.forget();
+  TemporaryRef<SourceSurface> Surface() {
+    return mSurface;
   }
 
 private:
-  nsRefPtr<mozilla::gfx::DrawTarget> mSurface;
+  RefPtr<SourceSurface>              mSurface;
   const nsIntSize                    mViewportSize;
   Maybe<SVGImageContext>             mSVGContext;
   const float                        mFrame;
   const uint32_t                     mFlags;
 };
 
 class DrawSingleTileCallback : public gfxDrawingCallback
 {
@@ -204,62 +207,60 @@ ClippedImage::GetIntrinsicRatio(nsSize* 
   if (!ShouldClip()) {
     return InnerImage()->GetIntrinsicRatio(aRatio);
   }
 
   *aRatio = nsSize(mClip.width, mClip.height);
   return NS_OK;
 }
 
-NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
+NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
 ClippedImage::GetFrame(uint32_t aWhichFrame,
                        uint32_t aFlags)
 {
   return GetFrameInternal(mClip.Size(), nullptr, aWhichFrame, aFlags);
 }
 
-already_AddRefed<gfxASurface>
+TemporaryRef<SourceSurface>
 ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize,
                                const SVGImageContext* aSVGContext,
                                uint32_t aWhichFrame,
                                uint32_t aFlags)
 {
   if (!ShouldClip()) {
     return InnerImage()->GetFrame(aWhichFrame, aFlags);
   }
 
   float frameToDraw = InnerImage()->GetFrameIndex(aWhichFrame);
   if (!mCachedSurface || !mCachedSurface->Matches(aViewportSize,
                                                   aSVGContext,
                                                   frameToDraw,
                                                   aFlags)) {
     // Create a surface to draw into.
-    mozilla::RefPtr<mozilla::gfx::DrawTarget> target;
-    nsRefPtr<gfxContext> ctx;
+    RefPtr<DrawTarget> target = gfxPlatform::GetPlatform()->
+      CreateOffscreenContentDrawTarget(IntSize(mClip.width, mClip.height),
+                                       SurfaceFormat::B8G8R8A8);
 
-    target = gfxPlatform::GetPlatform()->
-      CreateOffscreenContentDrawTarget(gfx::IntSize(mClip.width, mClip.height),
-                                       gfx::SurfaceFormat::B8G8R8A8);
-    ctx = new gfxContext(target);
+    nsRefPtr<gfxContext> ctx = new gfxContext(target);
 
     // Create our callback.
     nsRefPtr<gfxDrawingCallback> drawTileCallback =
       new DrawSingleTileCallback(this, mClip, aViewportSize, aSVGContext, aWhichFrame, aFlags);
     nsRefPtr<gfxDrawable> drawable =
       new gfxCallbackDrawable(drawTileCallback, mClip.Size());
 
     // Actually draw. The callback will end up invoking DrawSingleTile.
     gfxRect imageRect(0, 0, mClip.width, mClip.height);
     gfxUtils::DrawPixelSnapped(ctx, drawable, gfxMatrix(),
                                imageRect, imageRect, imageRect, imageRect,
                                gfxImageFormat::ARGB32,
                                GraphicsFilter::FILTER_FAST);
 
     // Cache the resulting surface.
-    mCachedSurface = new ClippedImageCachedSurface(target,
+    mCachedSurface = new ClippedImageCachedSurface(target->Snapshot(),
                                                    aViewportSize,
                                                    aSVGContext,
                                                    frameToDraw,
                                                    aFlags);
   }
 
   MOZ_ASSERT(mCachedSurface, "Should have a cached surface now");
   return mCachedSurface->Surface();
@@ -317,17 +318,17 @@ ClippedImage::Draw(gfxContext* aContext,
   }
 
   // Check for tiling. If we need to tile then we need to create a
   // gfxCallbackDrawable to handle drawing for us.
   gfxRect sourceRect = aUserSpaceToImageSpace.Transform(aFill);
   if (MustCreateSurface(aContext, aUserSpaceToImageSpace, sourceRect, aSubimage, aFlags)) {
     // Create a temporary surface containing a single tile of this image.
     // GetFrame will call DrawSingleTile internally.
-    nsRefPtr<gfxASurface> surface =
+    RefPtr<SourceSurface> surface =
       GetFrameInternal(aViewportSize, aSVGContext, aWhichFrame, aFlags);
     NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
     // Create a drawable from that surface.
     nsRefPtr<gfxSurfaceDrawable> drawable =
       new gfxSurfaceDrawable(surface, gfxIntSize(mClip.width, mClip.height));
 
     // Draw.
--- a/image/src/ClippedImage.h
+++ b/image/src/ClippedImage.h
@@ -2,46 +2,50 @@
 /* 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_IMAGELIB_CLIPPEDIMAGE_H_
 #define MOZILLA_IMAGELIB_CLIPPEDIMAGE_H_
 
 #include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
 #include "mozilla/Maybe.h"
+#include "mozilla/RefPtr.h"
 
 namespace mozilla {
 namespace image {
 
 class ClippedImageCachedSurface;
 class DrawSingleTileCallback;
 
 /**
  * An Image wrapper that clips an image against a rectangle. Right now only
  * absolute coordinates in pixels are supported.
  *
  * XXX(seth): There a known (performance, not correctness) issue with
  * GetImageContainer. See the comments for that method for more information.
  */
 class ClippedImage : public ImageWrapper
 {
+  typedef mozilla::gfx::SourceSurface SourceSurface;
+
 public:
   NS_DECL_ISUPPORTS
 
   virtual ~ClippedImage();
 
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
-  NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
-                                                      uint32_t aFlags) MOZ_OVERRIDE;
+  NS_IMETHOD_(mozilla::TemporaryRef<SourceSurface>)
+    GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager,
                                mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   GraphicsFilter aFilter,
                   const gfxMatrix& aUserSpaceToImageSpace,
                   const gfxRect& aFill,
                   const nsIntRect& aSubimage,
                   const nsIntSize& aViewportSize,
@@ -50,20 +54,21 @@ public:
                   uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD RequestDiscard() MOZ_OVERRIDE;
   NS_IMETHOD_(Orientation) GetOrientation() MOZ_OVERRIDE;
 
 protected:
   ClippedImage(Image* aImage, nsIntRect aClip);
 
 private:
-  already_AddRefed<gfxASurface> GetFrameInternal(const nsIntSize& aViewportSize,
-                                                 const SVGImageContext* aSVGContext,
-                                                 uint32_t aWhichFrame,
-                                                 uint32_t aFlags);
+  mozilla::TemporaryRef<SourceSurface>
+    GetFrameInternal(const nsIntSize& aViewportSize,
+                     const SVGImageContext* aSVGContext,
+                     uint32_t aWhichFrame,
+                     uint32_t aFlags);
   bool ShouldClip();
   bool MustCreateSurface(gfxContext* aContext,
                          const gfxMatrix& aTransform,
                          const gfxRect& aSourceRect,
                          const nsIntRect& aSubimage,
                          const uint32_t aFlags) const;
   gfxFloat ClampFactor(const gfxFloat aToClamp, const int aReference) const;
   nsresult DrawSingleTile(gfxContext* aContext,
--- a/image/src/FrozenImage.cpp
+++ b/image/src/FrozenImage.cpp
@@ -1,15 +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 "FrozenImage.h"
 
+using namespace mozilla::gfx;
+
 namespace mozilla {
 namespace image {
 
 NS_IMPL_ISUPPORTS1(FrozenImage, imgIContainer)
 
 nsIntRect
 FrozenImage::FrameRect(uint32_t /* aWhichFrame - ignored */)
 {
@@ -35,17 +37,17 @@ FrozenImage::GetAnimated(bool* aAnimated
   bool dummy;
   nsresult rv = InnerImage()->GetAnimated(&dummy);
   if (NS_SUCCEEDED(rv)) {
     *aAnimated = false;
   }
   return rv;
 }
 
-NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
+NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
 FrozenImage::GetFrame(uint32_t aWhichFrame,
                       uint32_t aFlags)
 {
   return InnerImage()->GetFrame(FRAME_FIRST, aFlags);
 }
 
 NS_IMETHODIMP_(bool)
 FrozenImage::FrameIsOpaque(uint32_t aWhichFrame)
--- a/image/src/FrozenImage.h
+++ b/image/src/FrozenImage.h
@@ -2,16 +2,18 @@
 /* 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_IMAGELIB_FROZENIMAGE_H_
 #define MOZILLA_IMAGELIB_FROZENIMAGE_H_
 
 #include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 
 namespace mozilla {
 namespace image {
 
 /**
  * An Image wrapper that disables animation, freezing the image at its first
  * frame. It does this using two strategies. If this is the only instance of the
  * image, animation will never start, because IncrementAnimationConsumers is
@@ -19,28 +21,30 @@ namespace image {
  * because any imgIContainer method that is affected by animation gets its
  * aWhichFrame argument set to FRAME_FIRST when it passes through FrozenImage.
  *
  * XXX(seth): There a known (performance, not correctness) issue with
  * GetImageContainer. See the comments for that method for more information.
  */
 class FrozenImage : public ImageWrapper
 {
+  typedef mozilla::gfx::SourceSurface SourceSurface;
+
 public:
   NS_DECL_ISUPPORTS
 
   virtual ~FrozenImage() { }
 
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
   virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
   virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
 
   NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE;
-  NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
-                                                      uint32_t aFlags) MOZ_OVERRIDE;
+  NS_IMETHOD_(TemporaryRef<SourceSurface>)
+    GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) FrameIsOpaque(uint32_t aWhichFrame) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
                                layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   GraphicsFilter aFilter,
                   const gfxMatrix& aUserSpaceToImageSpace,
                   const gfxRect& aFill,
                   const nsIntRect& aSubimage,
--- a/image/src/ImageWrapper.cpp
+++ b/image/src/ImageWrapper.cpp
@@ -1,18 +1,22 @@
 /* -*- 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 "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "Orientation.h"
 
 #include "mozilla/MemoryReporting.h"
 
+using mozilla::gfx::DataSourceSurface;
+using mozilla::gfx::SourceSurface;
 using mozilla::layers::LayerManager;
 using mozilla::layers::ImageContainer;
 
 namespace mozilla {
 namespace image {
 
 // Inherited methods from Image.
 
@@ -191,17 +195,17 @@ ImageWrapper::GetType()
 }
 
 NS_IMETHODIMP
 ImageWrapper::GetAnimated(bool* aAnimated)
 {
   return mInnerImage->GetAnimated(aAnimated);
 }
 
-NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
+NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
 ImageWrapper::GetFrame(uint32_t aWhichFrame,
                        uint32_t aFlags)
 {
   return mInnerImage->GetFrame(aWhichFrame, aFlags);
 }
 
 NS_IMETHODIMP_(bool)
 ImageWrapper::FrameIsOpaque(uint32_t aWhichFrame)
--- a/image/src/OrientedImage.cpp
+++ b/image/src/OrientedImage.cpp
@@ -6,16 +6,18 @@
 #include <algorithm>
 
 #include "gfxDrawable.h"
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 
 #include "OrientedImage.h"
 
+using namespace mozilla::gfx;
+
 using std::swap;
 using mozilla::layers::LayerManager;
 using mozilla::layers::ImageContainer;
 
 namespace mozilla {
 namespace image {
 
 NS_IMPL_ISUPPORTS1(OrientedImage, imgIContainer)
@@ -70,71 +72,68 @@ OrientedImage::GetIntrinsicRatio(nsSize*
 
   if (mOrientation.SwapsWidthAndHeight()) {
     swap(aRatio->width, aRatio->height);
   }
 
   return rv;
 }
 
-NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
+NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
 OrientedImage::GetFrame(uint32_t aWhichFrame,
                         uint32_t aFlags)
 {
   nsresult rv;
 
   if (mOrientation.IsIdentity()) {
     return InnerImage()->GetFrame(aWhichFrame, aFlags);
   }
 
   // Get the underlying dimensions.
   int32_t width, height;
+  rv = InnerImage()->GetWidth(&width);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+  rv = InnerImage()->GetHeight(&height);
+  NS_ENSURE_SUCCESS(rv, nullptr);
   if (mOrientation.SwapsWidthAndHeight()) {
-    rv = InnerImage()->GetWidth(&height);
-    rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&width);
-  } else {
-    rv = InnerImage()->GetWidth(&width);
-    rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&height);
+    swap(width, height);
   }
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   // Determine an appropriate format for the surface.
   gfx::SurfaceFormat surfaceFormat;
   gfxImageFormat imageFormat;
   if (InnerImage()->FrameIsOpaque(aWhichFrame)) {
     surfaceFormat = gfx::SurfaceFormat::B8G8R8X8;
     imageFormat = gfxImageFormat::ARGB32;
   } else {
     surfaceFormat = gfx::SurfaceFormat::B8G8R8A8;
     imageFormat = gfxImageFormat::ARGB32;
   }
 
   // Create a surface to draw into.
-  mozilla::RefPtr<mozilla::gfx::DrawTarget> target;
-  target = gfxPlatform::GetPlatform()->
-    CreateOffscreenContentDrawTarget(gfx::IntSize(width, height), surfaceFormat);
+  mozilla::RefPtr<DrawTarget> target =
+    gfxPlatform::GetPlatform()->
+      CreateOffscreenContentDrawTarget(IntSize(width, height), surfaceFormat);
 
   // Create our drawable.
-  nsRefPtr<gfxASurface> innerSurface =
+  RefPtr<SourceSurface> innerSurface =
     InnerImage()->GetFrame(aWhichFrame, aFlags);
   NS_ENSURE_TRUE(innerSurface, nullptr);
   nsRefPtr<gfxDrawable> drawable =
     new gfxSurfaceDrawable(innerSurface, gfxIntSize(width, height));
 
   // Draw.
   nsRefPtr<gfxContext> ctx = new gfxContext(target);
   gfxRect imageRect(0, 0, width, height);
   gfxUtils::DrawPixelSnapped(ctx, drawable, OrientationMatrix(nsIntSize(width, height)),
                              imageRect, imageRect, imageRect, imageRect,
                              imageFormat, GraphicsFilter::FILTER_FAST);
   
-  nsRefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->
-    GetThebesSurfaceForDrawTarget(target);
-
-  return surface.forget();
+  return target->Snapshot();
 }
 
 NS_IMETHODIMP
 OrientedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
 {
   // XXX(seth): We currently don't have a way of orienting the result of
   // GetImageContainer. We work around this by always returning null, but if it
   // ever turns out that OrientedImage is widely used on codepaths that can
--- a/image/src/OrientedImage.h
+++ b/image/src/OrientedImage.h
@@ -2,43 +2,47 @@
 /* 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_IMAGELIB_ORIENTEDIMAGE_H_
 #define MOZILLA_IMAGELIB_ORIENTEDIMAGE_H_
 
 #include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "Orientation.h"
 
 namespace mozilla {
 namespace image {
 
 /**
  * An Image wrapper that rotates and/or flips an image according to a specified
  * Orientation.
  *
  * XXX(seth): There a known (performance, not correctness) issue with
  * GetImageContainer. See the comments for that method for more information.
  */
 class OrientedImage : public ImageWrapper
 {
+  typedef mozilla::gfx::SourceSurface SourceSurface;
+
 public:
   NS_DECL_ISUPPORTS
 
   virtual ~OrientedImage() { }
 
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
-  NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
-                                                      uint32_t aFlags) MOZ_OVERRIDE;
+  NS_IMETHOD_(mozilla::TemporaryRef<SourceSurface>)
+    GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager,
                                mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   GraphicsFilter aFilter,
                   const gfxMatrix& aUserSpaceToImageSpace,
                   const gfxRect& aFill,
                   const nsIntRect& aSubimage,
                   const nsIntSize& aViewportSize,
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -1,20 +1,24 @@
 /* -*- 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/. */
 
+// Must #include ImageLogging.h before any IPDL-generated files or other files that #include prlog.h
+#include "ImageLogging.h"
+
+#include "RasterImage.h"
+
 #include "base/histogram.h"
-#include "ImageLogging.h"
+#include "gfxPlatform.h"
 #include "nsComponentManagerUtils.h"
 #include "imgDecoderObserver.h"
 #include "nsError.h"
 #include "Decoder.h"
-#include "RasterImage.h"
 #include "nsAutoPtr.h"
 #include "prenv.h"
 #include "prsystem.h"
 #include "ImageContainer.h"
 #include "Layers.h"
 #include "nsPresContext.h"
 #include "nsIThreadPool.h"
 #include "nsXPCOMCIDInternal.h"
@@ -25,16 +29,18 @@
 #include "nsGIFDecoder2.h"
 #include "nsJPEGDecoder.h"
 #include "nsBMPDecoder.h"
 #include "nsICODecoder.h"
 #include "nsIconDecoder.h"
 
 #include "gfxContext.h"
 
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 #include <stdint.h>
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/gfx/Scale.h"
@@ -43,16 +49,17 @@
 #include "gfx2DGlue.h"
 #include <algorithm>
 
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 using namespace mozilla::image;
 using namespace mozilla::layers;
 
 // a mask for flags that will affect the decoding
 #define DECODE_FLAGS_MASK (imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA | imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION)
 #define DECODE_FLAGS_DEFAULT 0
 
 /* Accounting for compressed data */
@@ -875,19 +882,19 @@ RasterImage::CopyFrame(uint32_t aWhichFr
   ctx.SetPattern(pattern);
   ctx.Fill();
 
   imgsurface.forget(_retval);
   return NS_OK;
 }
 
 //******************************************************************************
-/* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
- *                                 in uint32_t aFlags); */
-NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
+/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
+ *                                   in uint32_t aFlags); */
+NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
 RasterImage::GetFrame(uint32_t aWhichFrame,
                       uint32_t aFlags)
 {
   MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
 
   if (aWhichFrame > FRAME_MAX_VALUE)
     return nullptr;
 
@@ -946,48 +953,63 @@ RasterImage::GetFrame(uint32_t aWhichFra
   // The image doesn't have a surface because it's been optimized away. Create
   // one.
   if (!framesurf) {
     nsRefPtr<gfxImageSurface> imgsurf;
     CopyFrame(aWhichFrame, aFlags, getter_AddRefs(imgsurf));
     framesurf = imgsurf;
   }
 
-  return framesurf.forget();
+  RefPtr<SourceSurface> result;
+
+  // As far as Moz2D is concerned, SourceSurface contains premultiplied alpha.
+  // If we're abusing it to contain non-premultiplied alpha then we want to
+  // avoid having Moz2D do any conversions on it (like copy to another
+  // surface). Hence why we try to wrap framesurf's data here for
+  // FLAG_DECODE_NO_PREMULTIPLY_ALPHA.
+  if ((aFlags & FLAG_WANT_DATA_SURFACE) != 0 ||
+      (aFlags & FLAG_DECODE_NO_PREMULTIPLY_ALPHA) != 0) {
+    result = gfxPlatform::GetPlatform()->GetWrappedDataSourceSurface(framesurf);
+  }
+  if (!result) {
+    result = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
+                                                                    framesurf);
+  }
+  return result.forget();
 }
 
 already_AddRefed<layers::Image>
 RasterImage::GetCurrentImage()
 {
   if (!mDecoded) {
     // We can't call StartDecoding because that can synchronously notify
     // which can cause DOM modification
     RequestDecodeCore(ASYNCHRONOUS);
     return nullptr;
   }
 
-  nsRefPtr<gfxASurface> imageSurface = GetFrame(FRAME_CURRENT, FLAG_NONE);
-  if (!imageSurface) {
+  RefPtr<SourceSurface> surface = GetFrame(FRAME_CURRENT, FLAG_NONE);
+  if (!surface) {
     // The OS threw out some or all of our buffer. Start decoding again.
     // GetFrame will only return null in the case that the image was
     // discarded. We already checked that the image is decoded, so other
     // error paths are not possible.
     ForceDiscard();
     RequestDecodeCore(ASYNCHRONOUS);
     return nullptr;
   }
 
   if (!mImageContainer) {
     mImageContainer = LayerManager::CreateImageContainer();
   }
 
   CairoImage::Data cairoData;
   GetWidth(&cairoData.mSize.width);
   GetHeight(&cairoData.mSize.height);
-  cairoData.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imageSurface);
+  cairoData.mSourceSurface = surface;
 
   nsRefPtr<layers::Image> image = mImageContainer->CreateImage(ImageFormat::CAIRO_SURFACE);
   NS_ASSERTION(image, "Failed to create Image");
 
   static_cast<CairoImage*>(image.get())->SetData(cairoData);
 
   return image.forget();
 }
--- a/image/src/SurfaceCache.cpp
+++ b/image/src/SurfaceCache.cpp
@@ -105,20 +105,21 @@ private:
   CachedSurface* mSurface;
   Cost           mCost;
 };
 
 /*
  * A CachedSurface associates a surface with a key that uniquely identifies that
  * surface.
  */
-class CachedSurface : public RefCounted<CachedSurface>
+class CachedSurface
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(CachedSurface)
+  NS_INLINE_DECL_REFCOUNTING(CachedSurface)
+
   CachedSurface(DrawTarget*       aTarget,
                 const IntSize     aTargetSize,
                 const Cost        aCost,
                 const ImageKey    aImageKey,
                 const SurfaceKey& aSurfaceKey)
     : mTarget(aTarget)
     , mTargetSize(aTargetSize)
     , mCost(aCost)
@@ -151,20 +152,21 @@ private:
 };
 
 /*
  * An ImageSurfaceCache is a per-image surface cache. For correctness we must be
  * able to remove all surfaces associated with an image when the image is
  * destroyed or invalidated. Since this will happen frequently, it makes sense
  * to make it cheap by storing the surfaces for each image separately.
  */
-class ImageSurfaceCache : public RefCounted<ImageSurfaceCache>
+class ImageSurfaceCache
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageSurfaceCache)
+  NS_INLINE_DECL_REFCOUNTING(ImageSurfaceCache)
+
   typedef nsRefPtrHashtable<nsGenericHashKey<SurfaceKey>, CachedSurface> SurfaceTable;
 
   bool IsEmpty() const { return mSurfaces.Count() == 0; }
   
   void Insert(const SurfaceKey& aKey, CachedSurface* aSurface)
   {
     MOZ_ASSERT(aSurface, "Should have a surface");
     mSurfaces.Put(aKey, aSurface);
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -644,19 +644,19 @@ VectorImage::FrameIsOpaque(uint32_t aWhi
 {
   if (aWhichFrame > FRAME_MAX_VALUE)
     NS_WARNING("aWhichFrame outside valid range!");
 
   return false; // In general, SVG content is not opaque.
 }
 
 //******************************************************************************
-/* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
- *                                 in uint32_t aFlags; */
-NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
+/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
+ *                                   in uint32_t aFlags; */
+NS_IMETHODIMP_(TemporaryRef<SourceSurface>)
 VectorImage::GetFrame(uint32_t aWhichFrame,
                       uint32_t aFlags)
 {
   MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
 
   if (aWhichFrame > FRAME_MAX_VALUE)
     return nullptr;
 
@@ -669,45 +669,32 @@ VectorImage::GetFrame(uint32_t aWhichFra
   if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth,
                                              imageIntSize.width) ||
       !mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight,
                                              imageIntSize.height)) {
     // We'll get here if our SVG doc has a percent-valued width or height.
     return nullptr;
   }
 
-  // Create a surface that we'll ultimately return
-  // ---------------------------------------------
   // Make our surface the size of what will ultimately be drawn to it.
   // (either the full image size, or the restricted region)
-  gfxIntSize surfaceSize(imageIntSize.width, imageIntSize.height);
-
-  nsRefPtr<gfxImageSurface> surface =
-    new gfxImageSurface(surfaceSize, gfxImageFormat::ARGB32);
+  RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
+    CreateOffscreenContentDrawTarget(IntSize(imageIntSize.width,
+                                             imageIntSize.height),
+                                     SurfaceFormat::B8G8R8A8);
+  nsRefPtr<gfxContext> context = new gfxContext(dt);
 
-  RefPtr<DrawTarget> drawTarget =
-    Factory::CreateDrawTargetForData(BackendType::CAIRO,
-                                     surface->Data(),
-                                     IntSize(imageIntSize.width,
-                                             imageIntSize.height),
-                                     surface->Stride(),
-                                     SurfaceFormat::B8G8R8A8);
-
-  nsRefPtr<gfxContext> context = new gfxContext(drawTarget);
-
-  // Draw to our surface!
-  // --------------------
   nsresult rv = Draw(context, GraphicsFilter::FILTER_NEAREST, gfxMatrix(),
                      gfxRect(gfxPoint(0,0), gfxIntSize(imageIntSize.width,
                                                        imageIntSize.height)),
                      nsIntRect(nsIntPoint(0,0), imageIntSize),
                      imageIntSize, nullptr, aWhichFrame, aFlags);
 
   NS_ENSURE_SUCCESS(rv, nullptr);
-  return surface.forget();
+  return dt->Snapshot();
 }
 
 //******************************************************************************
 /* [noscript] ImageContainer getImageContainer(); */
 NS_IMETHODIMP
 VectorImage::GetImageContainer(LayerManager* aManager,
                                mozilla::layers::ImageContainer** _retval)
 {
--- a/image/src/imgTools.cpp
+++ b/image/src/imgTools.cpp
@@ -1,16 +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 "imgTools.h"
 
+#include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsError.h"
 #include "imgLoader.h"
 #include "imgICache.h"
@@ -92,30 +93,16 @@ NS_IMETHODIMP imgTools::DecodeImage(nsII
   rv = image->OnImageDataComplete(nullptr, nullptr, NS_OK, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // All done.
   NS_ADDREF(*aContainer = image.get());
   return NS_OK;
 }
 
-static TemporaryRef<SourceSurface>
-GetFirstImageFrame(imgIContainer *aContainer)
-{
-  nsRefPtr<gfxASurface> frame =
-    aContainer->GetFrame(imgIContainer::FRAME_FIRST,
-                         imgIContainer::FLAG_SYNC_DECODE);
-  NS_ENSURE_TRUE(frame, nullptr);
-
-  nsRefPtr<gfxImageSurface> imageSurface = frame->CopyToARGB32ImageSurface();
-  NS_ENSURE_TRUE(imageSurface, nullptr);
-
-  return imageSurface->CopyToB8G8R8A8DataSourceSurface();
-}
-
 /**
  * This takes a DataSourceSurface rather than a SourceSurface because some
  * of the callers have a DataSourceSurface and we don't want to call
  * GetDataSurface on such surfaces since that may incure a conversion to
  * SurfaceType::DATA which we don't need.
  */
 static nsresult EncodeImageData(DataSourceSurface* aDataSurface,
                                 const nsACString& aMimeType,
@@ -156,20 +143,32 @@ static nsresult EncodeImageData(DataSour
 }
 
 NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer,
                                     const nsACString& aMimeType,
                                     const nsAString& aOutputOptions,
                                     nsIInputStream **aStream)
 {
   // Use frame 0 from the image container.
-  RefPtr<SourceSurface> frame = GetFirstImageFrame(aContainer);
+  RefPtr<SourceSurface> frame =
+    aContainer->GetFrame(imgIContainer::FRAME_FIRST,
+                         imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
-  RefPtr<DataSourceSurface> dataSurface = frame->GetDataSurface();
+  RefPtr<DataSourceSurface> dataSurface;
+
+  if (frame->GetFormat() == SurfaceFormat::B8G8R8A8) {
+    dataSurface = frame->GetDataSurface();
+  } else {
+    // Convert format to SurfaceFormat::B8G8R8A8
+    dataSurface = gfxUtils::
+      CopySurfaceToDataSourceSurfaceWithFormat(frame,
+                                               SurfaceFormat::B8G8R8A8);
+  }
+
   NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
 
   return EncodeImageData(dataSurface, aMimeType, aOutputOptions, aStream);
 }
 
 NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
                                           const nsACString& aMimeType,
                                           int32_t aScaledWidth,
@@ -181,17 +180,19 @@ NS_IMETHODIMP imgTools::EncodeScaledImag
 
   // If no scaled size is specified, we'll just encode the image at its
   // original size (no scaling).
   if (aScaledWidth == 0 && aScaledHeight == 0) {
     return EncodeImage(aContainer, aMimeType, aOutputOptions, aStream);
   }
 
   // Use frame 0 from the image container.
-  RefPtr<SourceSurface> frame = GetFirstImageFrame(aContainer);
+  RefPtr<SourceSurface> frame =
+    aContainer->GetFrame(imgIContainer::FRAME_FIRST,
+                         imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   int32_t frameWidth = frame->GetSize().width;
   int32_t frameHeight = frame->GetSize().height;
 
   // If the given width or height is zero we'll replace it with the image's
   // original dimensions.
   if (aScaledWidth == 0) {
@@ -242,17 +243,19 @@ NS_IMETHODIMP imgTools::EncodeCroppedIma
 
   // If no size is specified then we'll preserve the image's original dimensions
   // and don't need to crop.
   if (aWidth == 0 && aHeight == 0) {
     return EncodeImage(aContainer, aMimeType, aOutputOptions, aStream);
   }
 
   // Use frame 0 from the image container.
-  RefPtr<SourceSurface> frame = GetFirstImageFrame(aContainer);
+  RefPtr<SourceSurface> frame =
+    aContainer->GetFrame(imgIContainer::FRAME_FIRST,
+                         imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   int32_t frameWidth = frame->GetSize().width;
   int32_t frameHeight = frame->GetSize().height;
 
   // If the given width or height is zero we'll replace it with the image's
   // original dimensions.
   if (aWidth == 0) {
--- a/ipc/netd/Netd.cpp
+++ b/ipc/netd/Netd.cpp
@@ -11,16 +11,17 @@
 #include "cutils/properties.h"
 #include "android/log.h"
 
 #include "nsWhitespaceTokenizer.h"
 #include "nsXULAppAPI.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
+#include "mozilla/RefPtr.h"
 
 
 #define CHROMIUM_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #define ICS_SYS_USB_RNDIS_MAC "/sys/class/android_usb/android0/f_rndis/ethaddr"
 #define INVALID_SOCKET -1
 #define MAX_RECONNECT_TIMES 10
 
 namespace {
--- a/ipc/netd/Netd.h
+++ b/ipc/netd/Netd.h
@@ -1,16 +1,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_system_netd_h__
 #define mozilla_system_netd_h__
 
-#include "mozilla/RefPtr.h"
+#include "nsISupportsImpl.h"
 #include "nsAutoPtr.h"
 #include "base/message_loop.h"
 #include "mozilla/FileUtils.h"
 
 #define MAX_COMMAND_SIZE  4096
 
 namespace mozilla {
 namespace ipc {
@@ -21,38 +21,41 @@ namespace ipc {
 struct NetdCommand
 {
   uint8_t mData[MAX_COMMAND_SIZE];
 
   // Number of octets in mData.
   size_t mSize;
 };
 
-class NetdConsumer : public mozilla::RefCounted<NetdConsumer>
+class NetdConsumer
 {
+protected:
+  virtual ~NetdConsumer() { }
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(NetdConsumer)
-  virtual ~NetdConsumer() { }
+  NS_INLINE_DECL_REFCOUNTING(NetdConsumer)
+
   virtual void MessageReceived(NetdCommand* aMessage) = 0;
 };
 
 class NetdWriteTask : public Task
 {
   virtual void Run();
 };
 
-class NetdClient : public MessageLoopForIO::LineWatcher,
-                   public RefCounted<NetdClient>
+class NetdClient : public MessageLoopForIO::LineWatcher
 {
+  virtual ~NetdClient();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(NetdClient)
+  NS_INLINE_DECL_REFCOUNTING(NetdClient)
   typedef std::queue<NetdCommand*> NetdCommandQueue;
 
   NetdClient();
-  virtual ~NetdClient();
   static void Start();
   static void SendNetdCommandIOThread(NetdCommand* aMessage);
 
 private:
   void WriteNetdCommand();
   virtual void OnError();
   virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage);
   virtual void OnFileCanWriteWithoutBlocking(int aFd);
--- a/ipc/unixsocket/UnixSocket.h
+++ b/ipc/unixsocket/UnixSocket.h
@@ -130,24 +130,26 @@ public:
 
 enum SocketConnectionStatus {
   SOCKET_DISCONNECTED = 0,
   SOCKET_LISTENING = 1,
   SOCKET_CONNECTING = 2,
   SOCKET_CONNECTED = 3
 };
 
-class UnixSocketConsumer : public AtomicRefCounted<UnixSocketConsumer>
+class UnixSocketConsumer
 {
+protected:
+  virtual ~UnixSocketConsumer();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(UnixSocketConsumer)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UnixSocketConsumer)
+
   UnixSocketConsumer();
 
-  virtual ~UnixSocketConsumer();
-
   SocketConnectionStatus GetConnectionStatus() const
   {
     MOZ_ASSERT(NS_IsMainThread());
     return mConnectionStatus;
   }
 
   int GetSuggestedConnectDelayMs() const
   {
--- a/js/ipc/JavaScriptChild.cpp
+++ b/js/ipc/JavaScriptChild.cpp
@@ -434,16 +434,18 @@ JavaScriptChild::AnswerIsExtensible(cons
     JSAutoRequest request(cx);
 
     *result = false;
 
     RootedObject obj(cx, findObject(objId));
     if (!obj)
         return false;
 
+    JSAutoCompartment comp(cx, obj);
+
     bool extensible;
     if (!JS_IsExtensible(cx, obj, &extensible))
         return fail(cx, rs);
 
     *result = !!extensible;
     return ok(rs);
 }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug892794.js
@@ -0,0 +1,13 @@
+// |jit-test| ion-eager
+
+function test0(v) {
+  return (2147483648-Math.max(1.1,-(((2<<(-v|v))-3)|0)))|0;
+}
+assertEq(test0(1.6), 2147483645);
+assertEq(test0(437348122.9), 2147483646);
+
+function test1(v) {
+  return (2147483648+Math.min(v,0))|0;
+}
+assertEq(test1(2.1), -2147483648)
+assertEq(test1(-0.1), 2147483647)
--- a/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js
@@ -1,15 +1,18 @@
+load(libdir + "asserts.js");
 /*
  * Call the trap with the handler as the this value, the target as the first
  * argument, and the original arguments as the third argument.
+ *
+ * Hooks that don't return an object must throw.
  */
 var target = function () {};
 var handler = {
     construct: function (target1, args) {
         assertEq(this, handler);
         assertEq(target1, target);
         assertEq(args.length, 2);
         assertEq(args[0], 2);
         assertEq(args[1], 3);
     }
 }
-assertEq(new (new Proxy(target, handler))(2, 3), undefined);
+assertThrowsInstanceOf(function () {new (new Proxy(target, handler))(2, 3)}, TypeError);
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4369,16 +4369,17 @@ ICGetElemNativeCompiler::generateStubCod
             emitCallNative(masm, objReg);
 
         } else {
             JS_ASSERT(acctype_ == ICGetElemNativeStub::ScriptedGetter);
 
             // Load function in scratchReg and ensure that it has a jit script.
             masm.loadPtr(Address(BaselineStubReg, ICGetElemNativeGetterStub::offsetOfGetter()),
                          scratchReg);
+            masm.branchIfFunctionHasNoScript(scratchReg, popR1 ? &failurePopR1 : &failure);
             masm.loadPtr(Address(scratchReg, JSFunction::offsetOfNativeOrScript()), scratchReg);
             masm.loadBaselineOrIonRaw(scratchReg, scratchReg, SequentialExecution,
                                       popR1 ? &failurePopR1 : &failure);
 
             // At this point, we are guaranteed to successfully complete.
             if (popR1)
                 masm.addPtr(Imm32(sizeof(size_t)), BaselineStackReg);
 
@@ -4801,34 +4802,47 @@ ICGetElem_Arguments::Compiler::generateS
     return true;
 }
 
 //
 // SetElem_Fallback
 //
 
 static bool
+SetElemDenseAddHasSameShapes(ICSetElem_DenseAdd *stub, JSObject *obj)
+{
+    size_t numShapes = stub->protoChainDepth() + 1;
+    for (size_t i = 0; i < numShapes; i++) {
+        static const size_t MAX_DEPTH = ICSetElem_DenseAdd::MAX_PROTO_CHAIN_DEPTH;
+        if (obj->lastProperty() != stub->toImplUnchecked<MAX_DEPTH>()->shape(i))
+            return false;
+        obj = obj->getProto();
+        if (!obj && i != numShapes - 1)
+            return false;
+    }
+
+    return true;
+}
+
+static bool
 DenseSetElemStubExists(JSContext *cx, ICStub::Kind kind, ICSetElem_Fallback *stub, HandleObject obj)
 {
     JS_ASSERT(kind == ICStub::SetElem_Dense || kind == ICStub::SetElem_DenseAdd);
 
     for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
         if (kind == ICStub::SetElem_Dense && iter->isSetElem_Dense()) {
             ICSetElem_Dense *dense = iter->toSetElem_Dense();
             if (obj->lastProperty() == dense->shape() && obj->getType(cx) == dense->type())
                 return true;
         }
 
         if (kind == ICStub::SetElem_DenseAdd && iter->isSetElem_DenseAdd()) {
             ICSetElem_DenseAdd *dense = iter->toSetElem_DenseAdd();
-            if (obj->lastProperty() == dense->toImplUnchecked<0>()->shape(0) &&
-                obj->getType(cx) == dense->type())
-            {
+            if (obj->getType(cx) == dense->type() && SetElemDenseAddHasSameShapes(dense, obj))
                 return true;
-            }
         }
     }
     return false;
 }
 
 static bool
 TypedArraySetElemStubExists(ICSetElem_Fallback *stub, HandleObject obj, bool expectOOB)
 {
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -3550,16 +3550,17 @@ class ICSetElem_DenseAdd : public ICUpda
     static size_t offsetOfType() {
         return offsetof(ICSetElem_DenseAdd, type_);
     }
 
     HeapPtrTypeObject &type() {
         return type_;
     }
     size_t protoChainDepth() const {
+        MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH);
         return extra_;
     }
 
     template <size_t ProtoChainDepth>
     ICSetElem_DenseAddImpl<ProtoChainDepth> *toImplUnchecked() {
         return static_cast<ICSetElem_DenseAddImpl<ProtoChainDepth> *>(this);
     }
 
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -3011,53 +3011,43 @@ jit::TraceIonScripts(JSTracer* trc, JSSc
 
 AutoDebugModeInvalidation::~AutoDebugModeInvalidation()
 {
     MOZ_ASSERT(!!comp_ != !!zone_);
 
     if (needInvalidation_ == NoNeed)
         return;
 
-    // Invalidate the stack if any compartments toggled from on->off, because
-    // we allow scripts to be on stack when turning off debug mode.
-    bool invalidateStack = needInvalidation_ == ToggledOff;
     Zone *zone = zone_ ? zone_ : comp_->zone();
     JSRuntime *rt = zone->runtimeFromMainThread();
     FreeOp *fop = rt->defaultFreeOp();
 
     if (comp_) {
         StopAllOffThreadCompilations(comp_);
     } else {
         for (CompartmentsInZoneIter comp(zone_); !comp.done(); comp.next())
             StopAllOffThreadCompilations(comp);
     }
 
-    if (invalidateStack) {
-        jit::MarkActiveBaselineScripts(zone);
-
-        for (JitActivationIterator iter(rt); !iter.done(); ++iter) {
-            JSCompartment *comp = iter.activation()->compartment();
-            if ((comp_ && comp_ == comp) ||
-                (zone_ && zone_ == comp->zone() && comp->principals))
-            {
-                IonContext ictx(CompileRuntime::get(rt));
-                AutoFlushCache afc("AutoDebugModeInvalidation", rt->jitRuntime());
-                IonSpew(IonSpew_Invalidate, "Invalidating frames for debug mode toggle");
-                InvalidateActivation(fop, iter.jitTop(), true);
-            }
+    jit::MarkActiveBaselineScripts(zone);
+
+    for (JitActivationIterator iter(rt); !iter.done(); ++iter) {
+        JSCompartment *comp = iter.activation()->compartment();
+        if ((comp_ && comp_ == comp) || (zone_ && zone_ == comp->zone())) {
+            IonContext ictx(CompileRuntime::get(rt));
+            AutoFlushCache afc("AutoDebugModeInvalidation", rt->jitRuntime());
+            IonSpew(IonSpew_Invalidate, "Invalidating frames for debug mode toggle");
+            InvalidateActivation(fop, iter.jitTop(), true);
         }
     }
 
     for (gc::CellIter i(zone, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
-        if ((comp_ && script->compartment() == comp_) ||
-            (zone_ && script->compartment()->principals))
-        {
+        if ((comp_ && script->compartment() == comp_) || zone_) {
             FinishInvalidation<SequentialExecution>(fop, script);
             FinishInvalidation<ParallelExecution>(fop, script);
             FinishDiscardBaselineScript(fop, script);
-            // script->clearAnalysis();
             script->resetUseCount();
         } else if (script->hasBaselineScript()) {
             script->baselineScript()->resetActive();
         }
     }
 }
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -432,8 +432,10 @@ MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST,
 MSG_DEF(JSMSG_NO_EXPORT_NAME,           378, 0, JSEXN_SYNTAXERR, "missing export name")
 MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT, 379, 0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
 MSG_DEF(JSMSG_INVALID_PROTOTYPE,        380, 0, JSEXN_TYPEERR, "prototype field is not an object")
 MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_TO_UNSIZED, 381, 0, JSEXN_TYPEERR, "cannot create a handle to an unsized type")
 MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL,      382, 1, JSEXN_TYPEERR, "[[SetPrototypeOf]] failed on {0}")
 MSG_DEF(JSMSG_INVALID_ARG_TYPE,         383, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}")
 MSG_DEF(JSMSG_TERMINATED,               384, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}")
 MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP, 385, 1, JSEXN_ERR, "No such property on self-hosted object: {0}")
+MSG_DEF(JSMSG_PROXY_EXTENSIBILITY,      386, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target")
+MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT,   387, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object")
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -1072,22 +1072,16 @@ ScriptedIndirectProxyHandler::fun_toStri
         return nullptr;
     }
     RootedObject obj(cx, &proxy->as<ProxyObject>().extra(0).toObject().getReservedSlot(0).toObject());
     return fun_toStringHelper(cx, obj, indent);
 }
 
 ScriptedIndirectProxyHandler ScriptedIndirectProxyHandler::singleton;
 
-static JSObject *
-GetDirectProxyHandlerObject(JSObject *proxy)
-{
-    return proxy->as<ProxyObject>().extra(0).toObjectOrNull();
-}
-
 /* Derived class for all scripted direct proxy handlers. */
 class ScriptedDirectProxyHandler : public DirectProxyHandler {
   public:
     ScriptedDirectProxyHandler();
     virtual ~ScriptedDirectProxyHandler();
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
@@ -1109,16 +1103,19 @@ class ScriptedDirectProxyHandler : publi
     virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
                      MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
                      bool strict, MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
                          MutableHandleValue vp) MOZ_OVERRIDE;
 
+    /* ES6 Harmony traps */
+    virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
+
     /* Spidermonkey extensions. */
     virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
     virtual bool isScripted() MOZ_OVERRIDE { return true; }
 
     static ScriptedDirectProxyHandler singleton;
 };
 
@@ -1360,16 +1357,26 @@ IdToValue(JSContext *cx, HandleId id, Mu
     value.set(IdToValue(id)); // Re-use out-param to avoid Rooted overhead.
     JSString *name = ToString<CanGC>(cx, value);
     if (!name)
         return false;
     value.set(StringValue(name));
     return true;
 }
 
+// Get the [[ProxyHandler]] of a scripted direct proxy.
+//
+// NB: This *must* stay synched with proxy().
+static JSObject *
+GetDirectProxyHandlerObject(JSObject *proxy)
+{
+    JS_ASSERT(proxy->as<ProxyObject>().handler() == &ScriptedDirectProxyHandler::singleton);
+    return proxy->as<ProxyObject>().extra(0).toObjectOrNull();
+}
+
 // TrapGetOwnProperty(O, P)
 static bool
 TrapGetOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue rval)
 {
     // step 1
     RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
 
     // step 2
@@ -2220,16 +2227,52 @@ ScriptedDirectProxyHandler::keys(JSConte
                              v, js::NullPtr(), bytes.ptr());
         return false;
     }
 
     // steps g-n are shared
     return ArrayToIdVector(cx, proxy, target, trapResult, props, JSITER_OWNONLY, cx->names().keys);
 }
 
+// ES6 (5 April, 2014) 9.5.3 Proxy.[[IsExtensible]](P)
+bool
+ScriptedDirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
+{
+    RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
+
+    RootedObject target(cx, proxy->as<ProxyObject>().target());
+
+    RootedValue trap(cx);
+    if (!JSObject::getProperty(cx, handler, handler, cx->names().isExtensible, &trap))
+        return false;
+
+    if (trap.isUndefined())
+        return DirectProxyHandler::isExtensible(cx, proxy, extensible);
+
+    Value argv[] = {
+        ObjectValue(*target)
+    };
+    RootedValue trapResult(cx);
+    if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
+        return false;
+
+    bool booleanTrapResult = ToBoolean(trapResult);
+    bool targetResult;
+    if (!JSObject::isExtensible(cx, target, &targetResult))
+        return false;
+
+    if (targetResult != booleanTrapResult) {
+       JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_EXTENSIBILITY);
+       return false;
+    }
+
+    *extensible = booleanTrapResult;
+    return true;
+}
+
 bool
 ScriptedDirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags,
                                     MutableHandleValue vp)
 {
     // FIXME: Provide a proper implementation for this trap, see bug 787004
     return DirectProxyHandler::iterate(cx, proxy, flags, vp);
 }
 
@@ -2300,17 +2343,23 @@ ScriptedDirectProxyHandler::construct(JS
         return DirectProxyHandler::construct(cx, proxy, args);
 
     // step 6
     Value constructArgv[] = {
         ObjectValue(*target),
         ObjectValue(*argsArray)
     };
     RootedValue thisValue(cx, ObjectValue(*handler));
-    return Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv, args.rval());
+    if (!Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv, args.rval()))
+        return false;
+    if (!args.rval().isObject()) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT);
+        return false;
+    }
+    return true;
 }
 
 ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
 
 #define INVOKE_ON_PROTOTYPE(cx, handler, proxy, protoCall)                   \
     JS_BEGIN_MACRO                                                           \
         RootedObject proto(cx);                                              \
         if (!JSObject::getProto(cx, proxy, &proto))                          \
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Proxy/proxy-constructNonObject.js
@@ -0,0 +1,18 @@
+function bogusConstruct(target) { return 4; }
+function bogusConstructUndefined(target) { }
+
+var handler = { construct: bogusConstruct }
+
+function callable() {}
+
+var p = new Proxy(callable, handler);
+
+assertThrowsInstanceOf(function () { new p(); }, TypeError,
+                       "[[Construct must throw if an object is not returned.");
+
+handler.construct = bogusConstructUndefined;
+assertThrowsInstanceOf(function () { new p(); }, TypeError,
+                       "[[Construct must throw if an object is not returned.");
+
+if (typeof reportCompare === "function")
+    reportCompare(0,0, "OK");
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Proxy/proxy-isExtensible.js
@@ -0,0 +1,94 @@
+// Test ES6 Proxy trap compliance for Object.isExtensible() on exotic proxy
+// objects.
+var unsealed = {};
+var sealed = Object.seal({});
+var handler = {};
+
+assertEq(Object.isExtensible(unsealed), true);
+assertEq(Object.isExtensible(sealed), false);
+
+var targetSealed = new Proxy(sealed, handler);
+var targetUnsealed = new Proxy(unsealed, handler);
+
+var handlerCalled = false;
+
+// without traps, forward to the target
+// First, make sure we get the obvious answer on a non-exotic target.
+assertEq(Object.isExtensible(targetSealed), false, "Must forward to target without hook.");
+assertEq(Object.isExtensible(targetUnsealed), true, "Must forward to target without hook.");
+
+// Now, keep everyone honest. What if the target itself is a proxy?
+function ensureCalled() { handlerCalled = true; return true; }
+var proxyTarget = new Proxy({}, { isExtensible : ensureCalled });
+assertEq(Object.isExtensible(new Proxy(proxyTarget, {})), true, "Must forward to target without hook.");
+assertEq(handlerCalled, true, "Must forward to target without hook.");
+
+// with traps, makes sure that the handler is called, and that we throw if the
+// trap disagrees with the target
+function testExtensible(obj, shouldThrow, expectedResult)
+{
+    handlerCalled = false;
+    if (shouldThrow)
+        assertThrowsInstanceOf(function () { Object.isExtensible(obj); },
+                               TypeError, "Must throw if handler and target disagree.");
+    else
+        assertEq(Object.isExtensible(obj), expectedResult, "Must return the correct value.");
+    assertEq(handlerCalled, true, "Must call handler trap if present");
+}
+
+// What if the trap says it's necessarily sealed?
+function fakeSealed() { handlerCalled = true; return false; }
+handler.isExtensible = fakeSealed;
+testExtensible(targetSealed, false, false);
+testExtensible(targetUnsealed, true);
+
+// What if the trap says it's never sealed?
+function fakeUnsealed() { handlerCalled = true; return true; }
+handler.isExtensible = fakeUnsealed;
+testExtensible(targetSealed, true);
+testExtensible(targetUnsealed, false, true);
+
+// make sure we are able to prevent further extensions mid-flight and throw if the
+// hook tries to lie.
+function makeSealedTruth(target) { handlerCalled = true; Object.preventExtensions(target); return false; }
+function makeSealedLie(target) { handlerCalled = true; Object.preventExtensions(target); return true; }
+handler.isExtensible = makeSealedTruth;
+testExtensible(new Proxy({}, handler), false, false);
+handler.isExtensible = makeSealedLie;
+testExtensible(new Proxy({}, handler), true);
+
+// What if the trap doesn't directly return a boolean?
+function falseyNonBool() { handlerCalled = true; return undefined; }
+handler.isExtensible = falseyNonBool;
+testExtensible(targetSealed, false, false);
+testExtensible(targetUnsealed, true);
+
+function truthyNonBool() { handlerCalled = true; return {}; }
+handler.isExtensible = truthyNonBool;
+testExtensible(targetSealed, true);
+testExtensible(targetUnsealed, false, true);
+
+// What if the trap throws?
+function ExtensibleError() { }
+ExtensibleError.prototype = new Error();
+ExtensibleError.prototype.constructor = ExtensibleError;
+function throwFromTrap() { throw new ExtensibleError(); }
+handler.isExtensible = throwFromTrap;
+
+// exercise some other code paths and make sure that they invoke the trap and
+// can handle the ensuing error.
+assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); },
+                       ExtensibleError, "Must throw if the trap does.");
+assertThrowsInstanceOf(function () { Object.isFrozen(targetSealed); },
+                       ExtensibleError, "Must throw if the trap does.");
+assertThrowsInstanceOf(function () { Object.isSealed(targetSealed); },
+                       ExtensibleError, "Must throw if the trap does.");
+
+
+// What if the trap likes to re-ask old questions?
+function recurse() { return Object.isExtensible(targetSealed); }
+handler.isExtensible = recurse;
+assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); },
+                       InternalError, "Should allow and detect infinite recurison.");
+
+reportCompare(0, 0, "OK");
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -98,16 +98,17 @@
     macro(isFinite, isFinite, "isFinite") \
     macro(isNaN, isNaN, "isNaN") \
     macro(isPrototypeOf, isPrototypeOf, "isPrototypeOf") \
     macro(iterate, iterate, "iterate") \
     macro(Infinity, Infinity, "Infinity") \
     macro(int8, int8, "int8") \
     macro(int16, int16, "int16") \
     macro(int32, int32, "int32") \
+    macro(isExtensible, isExtensible, "isExtensible") \
     macro(iterator, iterator, "iterator") \
     macro(iteratorIntrinsic, iteratorIntrinsic, "__iterator__") \
     macro(join, join, "join") \
     macro(keys, keys, "keys") \
     macro(lastIndex, lastIndex, "lastIndex") \
     macro(length, length, "length") \
     macro(let, let, "let") \
     macro(line, line, "line") \
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -281,17 +281,17 @@ 1234567890123456789012345678901234567890
     macro(JSOP_UNUSED47,  47, "unused47",   NULL,         1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED48,  48, "unused48",   NULL,         1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED49,  49, "unused49",   NULL,         1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED50,  50, "unused50",   NULL,         1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED51,  51, "unused51",   NULL,         1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED52,  52, "unused52",   NULL,         1,  0,  0,  JOF_BYTE) \
     \
     macro(JSOP_GETPROP,   53, "getprop",    NULL,         5,  1,  1, JOF_ATOM|JOF_PROP|JOF_TYPESET|JOF_TMPSLOT3) \
-    macro(JSOP_SETPROP,   54, "setprop",    NULL,         5,  2,  1, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING|JOF_TMPSLOT) \
+    macro(JSOP_SETPROP,   54, "setprop",    NULL,         5,  2,  1, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) \
     macro(JSOP_GETELEM,   55, "getelem",    NULL,         1,  2,  1, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC) \
     macro(JSOP_SETELEM,   56, "setelem",    NULL,         1,  3,  1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING) \
     macro(JSOP_UNUSED57,  57, "unused57",   NULL,         1,  0,  0, JOF_BYTE) \
     macro(JSOP_CALL,      58, "call",       NULL,         3, -1,  1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET) \
     macro(JSOP_NAME,      59, "name",       NULL,         5,  0,  1, JOF_ATOM|JOF_NAME|JOF_TYPESET) \
     macro(JSOP_DOUBLE,    60, "double",     NULL,         5,  0,  1, JOF_DOUBLE) \
     macro(JSOP_STRING,    61, "string",     NULL,         5,  0,  1, JOF_ATOM) \
     macro(JSOP_ZERO,      62, "zero",       "0",          1,  0,  1, JOF_BYTE) \
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -41,19 +41,20 @@ enum LayerState {
   // when the layer has rounded rect clips.
   LAYER_ACTIVE_FORCE,
   // Special layer that is metadata only.
   LAYER_ACTIVE_EMPTY,
   // Inactive style layer for rendering SVG effects.
   LAYER_SVG_EFFECTS
 };
 
-class RefCountedRegion : public RefCounted<RefCountedRegion> {
+class RefCountedRegion {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(RefCountedRegion)
+  NS_INLINE_DECL_REFCOUNTING(RefCountedRegion)
+
   RefCountedRegion() : mIsInfinite(false) {}
   nsRegion mRegion;
   bool mIsInfinite;
 };
 
 struct ContainerLayerParameters {
   ContainerLayerParameters() :
     mXScale(1), mYScale(1), mAncestorClipRect(nullptr),
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -5392,31 +5392,22 @@ nsLayoutUtils::SurfaceFromElement(nsIIma
 
   int32_t imgWidth, imgHeight;
   rv = imgContainer->GetWidth(&imgWidth);
   nsresult rv2 = imgContainer->GetHeight(&imgHeight);
   if (NS_FAILED(rv) || NS_FAILED(rv2))
     return result;
 
   if (!noRasterize || imgContainer->GetType() == imgIContainer::TYPE_RASTER) {
-    bool wantImageSurface = (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) != 0;
-    if (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) {
-      wantImageSurface = true;
+    if (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) {
+      frameFlags |= imgIContainer::FLAG_WANT_DATA_SURFACE;
     }
-    
-    nsRefPtr<gfxASurface> gfxsurf =
-      imgContainer->GetFrame(whichFrame, frameFlags);
-    if (!gfxsurf)
+    result.mSourceSurface = imgContainer->GetFrame(whichFrame, frameFlags);
+    if (!result.mSourceSurface) {
       return result;
-
-    if (wantImageSurface) {
-      result.mSourceSurface = gfxPlatform::GetPlatform()->GetWrappedDataSourceSurface(gfxsurf);
-    }
-    if (!result.mSourceSurface) {
-      result.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, gfxsurf);
     }
   } else {
     result.mDrawInfo.mImgContainer = imgContainer;
     result.mDrawInfo.mWhichFrame = whichFrame;
     result.mDrawInfo.mDrawingFlags = frameFlags;
   }
 
   int32_t corsmode;
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -1079,17 +1079,17 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/layout/xul-boxobject-tree;1", &kNS_TREEBOXOBJECT_CID },
 #endif // MOZ_XUL
 #ifdef MOZ_XUL
   { "@mozilla.org/inspector/dom-view;1", &kIN_DOMVIEW_CID },
 #endif
   { "@mozilla.org/inspector/deep-tree-walker;1", &kIN_DEEPTREEWALKER_CID },
   { "@mozilla.org/inspector/flasher;1", &kIN_FLASHER_CID },
   { "@mozilla.org/inspector/search;1?type=cssvalue", &kIN_CSSVALUESEARCH_CID },
-  { "@mozilla.org/inspector/dom-utils;1", &kIN_DOMUTILS_CID },
+  { IN_DOMUTILS_CONTRACTID, &kIN_DOMUTILS_CID },
   { "@mozilla.org/xml/xml-document;1", &kNS_XMLDOCUMENT_CID },
   { "@mozilla.org/svg/svg-document;1", &kNS_SVGDOCUMENT_CID },
   { NS_DOMMULTIPARTBLOB_CONTRACTID, &kNS_DOMMULTIPARTBLOB_CID },
   { NS_DOMMULTIPARTFILE_CONTRACTID, &kNS_DOMMULTIPARTFILE_CID },
   { "@mozilla.org/content/dom-selection;1", &kNS_DOMSELECTION_CID },
   { "@mozilla.org/content/post-content-iterator;1", &kNS_CONTENTITERATOR_CID },
   { "@mozilla.org/content/pre-content-iterator;1", &kNS_PRECONTENTITERATOR_CID },
   { "@mozilla.org/content/subtree-content-iterator;1", &kNS_SUBTREEITERATOR_CID },
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -210,17 +210,17 @@ static void BlitSurface(DrawTarget* aDes
 void
 nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
                                       nsRenderingContext* aCtx)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
 
-  nsRenderingContext context;
+  nsRefPtr<nsRenderingContext> context;
   nsRefPtr<gfxContext> dest = aCtx->ThebesContext();
   nsRefPtr<gfxASurface> surf;
   RefPtr<DrawTarget> dt;
   nsRefPtr<gfxContext> ctx;
   gfxRect destRect;
 #ifndef MOZ_GFX_OPTIMIZE_MOBILE
   if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) &&
       aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() &&
@@ -249,23 +249,24 @@ nsDisplayCanvasBackgroundImage::Paint(ns
     }
     if (surf || dt) {
       if (surf) {
         ctx = new gfxContext(surf);
       } else {
         ctx = new gfxContext(dt);
       }
       ctx->Translate(-gfxPoint(destRect.x, destRect.y));
-      context.Init(aCtx->DeviceContext(), ctx);
+      context = new nsRenderingContext();
+      context->Init(aCtx->DeviceContext(), ctx);
     }
   }
 #endif
 
   PaintInternal(aBuilder,
-                (surf || dt) ? &context : aCtx,
+                (surf || dt) ? context.get() : aCtx,
                 (surf || dt) ? bgClipRect: mVisibleRect,
                 &bgClipRect);
 
   if (surf) {
     BlitSurface(dest, destRect, surf);
     frame->Properties().Set(nsIFrame::CachedBackgroundImage(),
                             surf.forget().take());
   }
--- a/layout/inspector/inDOMView.cpp
+++ b/layout/inspector/inDOMView.cpp
@@ -19,16 +19,17 @@
 #include "nsIDOMMutationEvent.h"
 #include "nsBindingManager.h"
 #include "nsNameSpaceManager.h"
 #include "nsIDocument.h"
 #include "nsIServiceManager.h"
 #include "nsITreeColumns.h"
 #include "nsITreeBoxObject.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/Services.h"
 
 #ifdef ACCESSIBILITY
 #include "nsIAccessible.h"
 #include "nsIAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 
@@ -785,17 +786,17 @@ inDOMView::ContentInserted(nsIDocument *
 {
   if (!mTree)
     return;
 
   nsresult rv;
   nsCOMPtr<nsIDOMNode> childDOMNode(do_QueryInterface(aChild));
   nsCOMPtr<nsIDOMNode> parent;
   if (!mDOMUtils) {
-    mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1");
+    mDOMUtils = services::GetInDOMUtils();
     if (!mDOMUtils) {
       return;
     }
   }
   mDOMUtils->GetParentForNode(childDOMNode, mShowAnonymous,
                               getter_AddRefs(parent));
 
   // find the inDOMViewNode for the parent of the inserted content
@@ -1184,17 +1185,17 @@ inDOMView::GetChildNodesFor(nsIDOMNode* 
         AppendAttrsToArray(attrs, aResult);
       }
     }
   }
 
   if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) {
     nsCOMPtr<nsIDOMNodeList> kids;
     if (!mDOMUtils) {
-      mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1");
+      mDOMUtils = services::GetInDOMUtils();
       if (!mDOMUtils) {
         return NS_ERROR_FAILURE;
       }
     }
 
     mDOMUtils->GetChildrenForNode(aNode, mShowAnonymous,
                                   getter_AddRefs(kids));
 
@@ -1229,17 +1230,17 @@ inDOMView::AppendKidsToArray(nsIDOMNodeL
 {
   uint32_t l = 0;
   aKids->GetLength(&l);
   nsCOMPtr<nsIDOMNode> kid;
   uint16_t nodeType = 0;
 
   // Try and get DOM Utils in case we don't have one yet.
   if (!mShowWhitespaceNodes && !mDOMUtils) {
-    mDOMUtils = do_CreateInstance("@mozilla.org/inspector/dom-utils;1");
+    mDOMUtils = services::GetInDOMUtils();
   }
 
   for (uint32_t i = 0; i < l; ++i) {
     aKids->Item(i, getter_AddRefs(kid));
     kid->GetNodeType(&nodeType);
 
     NS_ASSERTION(nodeType && nodeType <= nsIDOMNode::NOTATION_NODE,
                  "Unknown node type. "
--- a/layout/inspector/inIDOMUtils.idl
+++ b/layout/inspector/inIDOMUtils.idl
@@ -99,8 +99,12 @@ interface inIDOMUtils : nsISupports
    * Parse CSS and update the style sheet in place.
    *
    * @param DOMCSSStyleSheet aSheet
    * @param DOMString aInput
    *        The new source string for the style sheet.
    */
   void parseStyleSheet(in nsIDOMCSSStyleSheet aSheet, in DOMString aInput);
 };
+
+%{ C++
+#define IN_DOMUTILS_CONTRACTID "@mozilla.org/inspector/dom-utils;1"
+%}
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -653,43 +653,30 @@ public:
   {
     if (mTouchSensitiveRegion.IsEmpty())
       return false;
 
     *aOutRegion = CSSRect::FromAppUnits(mTouchSensitiveRegion.GetBounds());
     return true;
   }
 
-  virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid)
+  virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+                                    APZStateChange aChange,
+                                    int aArg)
   {
     if (MessageLoop::current() != mUILoop) {
       mUILoop->PostTask(
         FROM_HERE,
-        NewRunnableMethod(this, &RemoteContentController::NotifyTransformBegin,
-                          aGuid));
+        NewRunnableMethod(this, &RemoteContentController::NotifyAPZStateChange,
+                          aGuid, aChange, aArg));
       return;
     }
     if (mRenderFrame) {
       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
-      browser->NotifyTransformBegin(aGuid.mScrollId);
-    }
-  }
-
-  virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid)
-  {
-    if (MessageLoop::current() != mUILoop) {
-      mUILoop->PostTask(
-        FROM_HERE,
-        NewRunnableMethod(this, &RemoteContentController::NotifyTransformEnd,
-                          aGuid));
-      return;
-    }
-    if (mRenderFrame) {
-      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
-      browser->NotifyTransformEnd(aGuid.mScrollId);
+      browser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
     }
   }
 
   // Methods used by RenderFrameParent to set fields stored here.
 
   void SaveZoomConstraints(const ZoomConstraints& aConstraints)
   {
     mHaveZoomConstraints = true;
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -313,21 +313,21 @@ nsFilterInstance::BuildSourcePaint(Sourc
     if (!offscreenDT) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     ctx = new gfxContext(offscreenDT);
   }
 
   ctx->Translate(-neededRect.TopLeft());
 
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
+  nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
+  tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
 
   gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
-  gfxContext *gfx = tmpCtx.ThebesContext();
+  gfxContext *gfx = tmpCtx->ThebesContext();
   gfx->Multiply(deviceToFilterSpace);
 
   gfx->Save();
 
   gfxMatrix matrix =
     nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_PAINTING,
                             mTransformRoot);
   if (!matrix.IsSingular()) {
@@ -396,18 +396,18 @@ nsFilterInstance::BuildSourceImage(gfxAS
     if (!offscreenDT) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     ctx = new gfxContext(offscreenDT);
   }
 
   ctx->Translate(-neededRect.TopLeft());
 
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
+  nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
+  tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
 
   gfxRect r = FilterSpaceToUserSpace(neededRect);
   r.RoundOut();
   nsIntRect dirty;
   if (!gfxUtils::GfxRectToIntRect(r, &dirty))
     return NS_ERROR_FAILURE;
 
   // SVG graphics paint to device space, so we need to set an initial device
@@ -417,18 +417,18 @@ nsFilterInstance::BuildSourceImage(gfxAS
   // (In theory it would be better to minimize error by having filtered SVG
   // graphics temporarily paint to user space when painting the sources and
   // only set a user space to filter space transform on the gfxContext
   // (since that would eliminate the transform multiplications from user
   // space to device space and back again). However, that would make the
   // code more complex while being hard to get right without introducing
   // subtle bugs, and in practice it probably makes no real difference.)
   gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
-  tmpCtx.ThebesContext()->Multiply(deviceToFilterSpace);
-  mPaintCallback->Paint(&tmpCtx, mTargetFrame, &dirty, mTransformRoot);
+  tmpCtx->ThebesContext()->Multiply(deviceToFilterSpace);
+  mPaintCallback->Paint(tmpCtx, mTargetFrame, &dirty, mTransformRoot);
 
   RefPtr<SourceSurface> sourceGraphicSource;
 
   if (offscreenSurface) {
     sourceGraphicSource =
       gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTargetDT, offscreenSurface);
   } else {
     sourceGraphicSource = offscreenDT->Snapshot();
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -600,18 +600,18 @@ PaintFrameCallback::operator()(gfxContex
                                const GraphicsFilter& aFilter,
                                const gfxMatrix& aTransform)
 {
   if (mFrame->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)
     return false;
 
   mFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
 
-  nsRenderingContext context;
-  context.Init(mFrame->PresContext()->DeviceContext(), aContext);
+  nsRefPtr<nsRenderingContext> context(new nsRenderingContext());
+  context->Init(mFrame->PresContext()->DeviceContext(), aContext);
   aContext->Save();
 
   // Clip to aFillRect so that we don't paint outside.
   aContext->NewPath();
   aContext->Rectangle(aFillRect);
   aContext->Clip();
 
   aContext->Multiply(gfxMatrix(aTransform).Invert());
@@ -639,17 +639,17 @@ PaintFrameCallback::operator()(gfxContex
   nsRect dirty(-offset.x, -offset.y,
                mPaintServerSize.width, mPaintServerSize.height);
 
   uint32_t flags = nsLayoutUtils::PAINT_IN_TRANSFORM |
                    nsLayoutUtils::PAINT_ALL_CONTINUATIONS;
   if (mFlags & nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES) {
     flags |= nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES;
   }
-  nsLayoutUtils::PaintFrame(&context, mFrame,
+  nsLayoutUtils::PaintFrame(context, mFrame,
                             dirty, NS_RGBA(0, 0, 0, 0),
                             flags);
 
   aContext->Restore();
 
   mFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
 
   return true;
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -221,35 +221,35 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
   // 'image'. However, we need to set the same matrix on the temporary context
   // and pattern that we create below as is currently set on 'gfx'.
   // Unfortunately, any device offset set by SetDeviceOffset() is affected by
   // the transform passed to the SetMatrix() calls, so to avoid that we account
   // for the device offset in the transform rather than use SetDeviceOffset().
   gfxMatrix matrix =
     gfx->CurrentMatrix() * gfxMatrix().Translate(-clipExtents.TopLeft());
 
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(this->PresContext()->DeviceContext(), image);
-  tmpCtx.ThebesContext()->SetMatrix(matrix);
+  nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext);
+  tmpCtx->Init(this->PresContext()->DeviceContext(), image);
+  tmpCtx->ThebesContext()->SetMatrix(matrix);
 
   mMaskParent = aParent;
   if (mMaskParentMatrix) {
     *mMaskParentMatrix = aMatrix;
   } else {
     mMaskParentMatrix = new gfxMatrix(aMatrix);
   }
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     // The CTM of each frame referencing us can be different
     nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
     if (SVGFrame) {
       SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
     }
-    nsSVGUtils::PaintFrameWithEffects(&tmpCtx, nullptr, kid);
+    nsSVGUtils::PaintFrameWithEffects(tmpCtx, nullptr, kid);
   }
 
   uint8_t *data   = image->Data();
   int32_t  stride = image->Stride();
   nsIntRect rect(0, 0, surfaceSize.width, surfaceSize.height);
 
   if (StyleSVGReset()->mMaskType == NS_STYLE_MASK_TYPE_LUMINANCE) {
     if (StyleSVG()->mColorInterpolation ==
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -367,19 +367,19 @@ nsSVGPatternFrame::PaintPattern(gfxASurf
   }
 
   nsRefPtr<gfxASurface> tmpSurface =
     gfxPlatform::GetPlatform()->CreateOffscreenSurface(surfaceSize,
                                                        gfxContentType::COLOR_ALPHA);
   if (!tmpSurface || tmpSurface->CairoStatus())
     return NS_ERROR_FAILURE;
 
-  nsRenderingContext context;
-  context.Init(aSource->PresContext()->DeviceContext(), tmpSurface);
-  gfxContext* gfx = context.ThebesContext();
+  nsRefPtr<nsRenderingContext> context(new nsRenderingContext());
+  context->Init(aSource->PresContext()->DeviceContext(), tmpSurface);
+  gfxContext* gfx = context->ThebesContext();
 
   // Fill with transparent black
   gfx->SetOperator(gfxContext::OPERATOR_CLEAR);
   gfx->Paint();
   gfx->SetOperator(gfxContext::OPERATOR_OVER);
 
   if (aGraphicOpacity != 1.0f) {
     gfx->Save();
@@ -401,17 +401,17 @@ nsSVGPatternFrame::PaintPattern(gfxASurf
     patternFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
     for (nsIFrame* kid = firstKid; kid;
          kid = kid->GetNextSibling()) {
       // The CTM of each frame referencing us can be different
       nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
       if (SVGFrame) {
         SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
       }
-      nsSVGUtils::PaintFrameWithEffects(&context, nullptr, kid);
+      nsSVGUtils::PaintFrameWithEffects(context, nullptr, kid);
     }
     patternFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
   }
 
   patternFrame->mSource = nullptr;
 
   if (aGraphicOpacity != 1.0f) {
     gfx->PopGroupToSource();
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1466,21 +1466,22 @@ nsSVGUtils::PaintSVGGlyph(Element* aElem
                           DrawMode aDrawMode,
                           gfxTextContextPaint* aContextPaint)
 {
   nsIFrame* frame = aElement->GetPrimaryFrame();
   nsISVGChildFrame* svgFrame = do_QueryFrame(frame);
   if (!svgFrame) {
     return false;
   }
-  nsRenderingContext context;
-  context.Init(frame->PresContext()->DeviceContext(), aContext);
-  context.AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint, nullptr);
+  nsRefPtr<nsRenderingContext> context(new nsRenderingContext());
+  context->Init(frame->PresContext()->DeviceContext(), aContext);
+  context->AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint,
+                       nullptr);
   svgFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
-  nsresult rv = svgFrame->PaintSVG(&context, nullptr, frame);
+  nsresult rv = svgFrame->PaintSVG(context, nullptr, frame);
   return NS_SUCCEEDED(rv);
 }
 
 bool
 nsSVGUtils::GetSVGGlyphExtents(Element* aElement,
                                const gfxMatrix& aSVGToAppSpace,
                                gfxRect* aResult)
 {
--- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c
+++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c
@@ -1573,17 +1573,17 @@ sdp_result_e sdp_build_media (sdp_t *sdp
                 flex_string_sprintf(fs, " %s",
                                  sdp_get_payload_name((sdp_payload_e)mca_p->payload_type[i]));
             } else {
                 flex_string_sprintf(fs, " %u", mca_p->payload_type[i]);
             }
         }
     } else {
         /* Add port to SDP if transport is DTLS/SCTP */
-    	flex_string_sprintf(fs, " %u ", (u32)mca_p->sctpport);
+    	flex_string_sprintf(fs, " %u", (u32)mca_p->sctpport);
     }
 
     flex_string_sprintf(fs, "\r\n");
 
     if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
         SDP_PRINT("%s Built m= media line", sdp_p->debug_str);
     }
     return (SDP_SUCCESS);
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -2812,17 +2812,17 @@ TEST_F(SignalingTest, missingUfrag)
     "a=rtpmap:120 VP8/90000\r\n"
     "a=recvonly\r\n"
     "a=candidate:0 1 UDP 2113601791 192.168.178.20 49929 typ host\r\n"
     "a=candidate:1 1 UDP 1694236671 77.9.79.167 49929 typ srflx raddr "
       "192.168.178.20 rport 49929\r\n"
     "a=candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ host\r\n"
     "a=candidate:1 2 UDP 1694236670 77.9.79.167 50769 typ srflx raddr "
       "192.168.178.20 rport 50769\r\n"
-    "m=application 54054 DTLS/SCTP 5000 \r\n"
+    "m=application 54054 DTLS/SCTP 5000\r\n"
     "c=IN IP4 77.9.79.167\r\n"
     "a=fmtp:HuRUu]Dtcl\\zM,7(OmEU%O$gU]x/z\tD protocol=webrtc-datachannel;"
       "streams=16\r\n"
     "a=sendrecv\r\n";
 
   // Need to create an offer, since that's currently required by our
   // FSM. This may change in the future.
   a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
--- a/netwerk/base/src/NetworkActivityMonitor.cpp
+++ b/netwerk/base/src/NetworkActivityMonitor.cpp
@@ -146,47 +146,54 @@ nsNetMon_AcceptRead(PRFileDesc *listenSo
   if (ret > 0)
     NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
   return ret;
 }
 
 
 class NotifyNetworkActivity : public nsRunnable {
 public:
-  NotifyNetworkActivity(nsIObserverService* aObs,
-                        NetworkActivityMonitor::Direction aDirection)
-    : mObs(aObs)
-    , mDirection(aDirection)
+  NotifyNetworkActivity(NetworkActivityMonitor::Direction aDirection)
+    : mDirection(aDirection)
   {}
   NS_IMETHOD Run()
   {
-    mObs->NotifyObservers(nullptr,
-                          mDirection == NetworkActivityMonitor::kUpload
-                            ? NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC
-                            : NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC,
-                          nullptr);
+    MOZ_ASSERT(NS_IsMainThread());
+
+    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+    if (!obs)
+      return NS_ERROR_FAILURE;
+
+    obs->NotifyObservers(nullptr,
+                         mDirection == NetworkActivityMonitor::kUpload
+                           ? NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC
+                           : NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC,
+                         nullptr);
     return NS_OK;
   }
 private:
   nsCOMPtr<nsIObserverService>      mObs;
   NetworkActivityMonitor::Direction mDirection;
 };
 
 NetworkActivityMonitor * NetworkActivityMonitor::gInstance = nullptr;
 
 NetworkActivityMonitor::NetworkActivityMonitor()
   : mLayerIdentity(PR_INVALID_IO_LAYER)
   , mBlipInterval(PR_INTERVAL_NO_TIMEOUT)
 {
+  MOZ_COUNT_CTOR(NetworkActivityMonitor);
+
   NS_ASSERTION(gInstance==nullptr,
                "multiple NetworkActivityMonitor instances!");
 }
 
 NetworkActivityMonitor::~NetworkActivityMonitor()
 {
+  MOZ_COUNT_DTOR(NetworkActivityMonitor);
   gInstance = nullptr;
 }
 
 nsresult
 NetworkActivityMonitor::Init(int32_t blipInterval)
 {
   nsresult rv;
 
@@ -224,20 +231,16 @@ NetworkActivityMonitor::Init_Internal(in
   mLayerMethods.write      = nsNetMon_Write;
   mLayerMethods.writev     = nsNetMon_Writev;
   mLayerMethods.recv       = nsNetMon_Recv;
   mLayerMethods.send       = nsNetMon_Send;
   mLayerMethods.recvfrom   = nsNetMon_RecvFrom;
   mLayerMethods.sendto     = nsNetMon_SendTo;
   mLayerMethods.acceptread = nsNetMon_AcceptRead;
 
-  mObserverService = mozilla::services::GetObserverService();
-  if (!mObserverService)
-    return NS_ERROR_FAILURE;
-
   mBlipInterval = PR_MillisecondsToInterval(blipInterval);
   // Set the last notification times to time that has just expired, so any
   // activity even right now will trigger notification.
   mLastNotificationTime[kUpload] = PR_IntervalNow() - mBlipInterval;
   mLastNotificationTime[kDownload] = mLastNotificationTime[kUpload];
 
   return NS_OK;
 }
@@ -282,12 +285,11 @@ NetworkActivityMonitor::DataInOut(Direct
   }
 
   return NS_OK;
 }
 
 void
 NetworkActivityMonitor::PostNotification(Direction direction)
 {
-  nsRefPtr<nsIRunnable> ev = new NotifyNetworkActivity(mObserverService,
-                                                       direction);
+  nsRefPtr<nsIRunnable> ev = new NotifyNetworkActivity(direction);
   NS_DispatchToMainThread(ev);
 }
--- a/netwerk/base/src/NetworkActivityMonitor.h
+++ b/netwerk/base/src/NetworkActivityMonitor.h
@@ -2,22 +2,21 @@
  *
  * 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 NetworkActivityMonitor_h___
 #define NetworkActivityMonitor_h___
 
-#include "nsCOMPtr.h"
+#include <stdint.h>
+#include "nscore.h"
 #include "prio.h"
 #include "prinrval.h"
 
-class nsIObserverService;
-
 namespace mozilla { namespace net {
 
 class NetworkActivityMonitor
 {
 public:
   enum Direction {
     kUpload   = 0,
     kDownload = 1
@@ -36,14 +35,13 @@ private:
   nsresult Init_Internal(int32_t blipInterval);
   void PostNotification(Direction direction);
 
   static NetworkActivityMonitor * gInstance;
   PRDescIdentity                  mLayerIdentity;
   PRIOMethods                     mLayerMethods;
   PRIntervalTime                  mBlipInterval;
   PRIntervalTime                  mLastNotificationTime[2];
-  nsCOMPtr<nsIObserverService>    mObserverService;
 };
 
 }} // namespace mozilla::net
 
 #endif /* NetworkActivityMonitor_h___ */
--- a/security/manager/ssl/src/SharedCertVerifier.h
+++ b/security/manager/ssl/src/SharedCertVerifier.h
@@ -6,32 +6,34 @@
 #define mozilla_psm__SharedCertVerifier_h
 
 #include "certt.h"
 #include "CertVerifier.h"
 #include "mozilla/RefPtr.h"
 
 namespace mozilla { namespace psm {
 
-class SharedCertVerifier : public mozilla::psm::CertVerifier,
-                           public mozilla::AtomicRefCounted<SharedCertVerifier>
+class SharedCertVerifier : public mozilla::psm::CertVerifier
 {
+protected:
+  ~SharedCertVerifier();
+
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedCertVerifier)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedCertVerifier)
+
   SharedCertVerifier(implementation_config ic,
 #ifndef NSS_NO_LIBPKIX
                      missing_cert_download_config ac, crl_download_config cdc,
 #endif
                      ocsp_download_config odc, ocsp_strict_config osc,
                      ocsp_get_config ogc)
     : mozilla::psm::CertVerifier(ic,
 #ifndef NSS_NO_LIBPKIX
                                  ac, cdc,
 #endif
                                  odc, osc, ogc)
   {
   }
-  ~SharedCertVerifier();
 };
 
 } } // namespace mozilla::psm
 
 #endif // mozilla_psm__SharedCertVerifier_h
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
@@ -134,13 +134,17 @@ GetOCSPResponseForType(OCSPResponseType 
 
   SECItem* response = CreateEncodedOCSPResponse(context);
   if (!response) {
     PrintPRError("CreateEncodedOCSPResponse failed");
     return nullptr;
   }
 
   SECItemArray* arr = SECITEM_AllocArray(aArena, nullptr, 1);
-  arr->items[0].data = response ? response->data : nullptr;
-  arr->items[0].len = response ? response->len : 0;
+  if (!arr) {
+    PrintPRError("SECITEM_AllocArray failed");
+    return nullptr;
+  }
+  arr->items[0].data = response->data;
+  arr->items[0].len = response->len;
 
   return arr;
 }
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -14,16 +14,18 @@ var _quit = false;
 var _passed = true;
 var _tests_pending = 0;
 var _passedChecks = 0, _falsePassedChecks = 0;
 var _todoChecks = 0;
 var _cleanupFunctions = [];
 var _pendingTimers = [];
 var _profileInitialized = false;
 
+let _Promise = Components.utils.import("resource://gre/modules/Promise.jsm", this).Promise;
+
 let _log = function (action, params) {
   if (typeof _XPCSHELL_PROCESS != "undefined") {
     params.process = _XPCSHELL_PROCESS;
   }
   params.action = action;
   params._time = Date.now();
   dump("\n" + JSON.stringify(params) + "\n");
 }
@@ -175,17 +177,17 @@ function _do_main() {
 
   while (thr.hasPendingEvents())
     thr.processNextEvent(true);
 }
 
 function _do_quit() {
   _log("test_info",
        {_message: "TEST-INFO | (xpcshell/head.js) | exiting test\n"});
-
+  _Promise.Debugging.flushUncaughtErrors();
   _quit = true;
 }
 
 function _format_exception_stack(stack) {
   if (typeof stack == "object" && stack.caller) {
     let frame = stack;
     let strStack = "";
     while (frame != null) {
@@ -343,16 +345,25 @@ function _register_protocol_handlers() {
 
 function _execute_test() {
   _register_protocol_handlers();
 
   // Override idle service by default.
   // Call do_get_idle() to restore the factory and get the service.
   _fakeIdleService.activate();
 
+  _Promise.Debugging.clearUncaughtErrorObservers();
+  _Promise.Debugging.addUncaughtErrorObserver(function observer({message, date, fileName, stack, lineNumber}) {
+    let text = "Once bug 976205 has landed, THIS ERROR WILL CAUSE A TEST FAILURE.\n" +
+        " A promise chain failed to handle a rejection: " +
+        message + " - rejection date: " + date;
+    _log_message_with_stack("test_known_fail",
+                            text, stack, fileName);
+  });
+
   // _HEAD_FILES is dynamically defined by <runxpcshelltests.py>.
   _load_files(_HEAD_FILES);
   // _TEST_FILE is dynamically defined by <runxpcshelltests.py>.
   _load_files(_TEST_FILE);
 
   // Support a common assertion library, Assert.jsm.
   let Assert = Components.utils.import("resource://testing-common/Assert.jsm", null).Assert;
   // Pass a custom report function for xpcshell-test style reporting.
@@ -1423,20 +1434,22 @@ let _gTestIndex = 0; // The index of the
 let _gTaskRunning = false;
 function run_next_test()
 {
   if (_gTaskRunning) {
     throw new Error("run_next_test() called from an add_task() test function. " +
                     "run_next_test() should not be called from inside add_task() " +
                     "under any circumstances!");
   }
-
+ 
   function _run_next_test()
   {
     if (_gTestIndex < _gTests.length) {
+      // Flush uncaught errors as early and often as possible.
+      _Promise.Debugging.flushUncaughtErrors();
       let _isTask;
       [_isTask, _gRunningTest] = _gTests[_gTestIndex++];
       print("TEST-INFO | " + _TEST_FILE + " | Starting " + _gRunningTest.name);
       do_test_pending(_gRunningTest.name);
 
       if (_isTask) {
         _gTaskRunning = true;
         _Task.spawn(_gRunningTest).then(
--- a/toolkit/components/social/test/browser/browser.ini
+++ b/toolkit/components/social/test/browser/browser.ini
@@ -14,11 +14,11 @@ support-files =
   eventsource.resource^headers^
 
 [browser_workerAPI.js]
 [browser_SocialProvider.js]
 [browser_notifications.js]
 
 # These tests are currently unreliable on ASAN builds with remote frameworkers.
 [browser_frameworker.js]
-skip-if = asan || (os == 'linux' && debug) # Bug 994798 for Linux debug disabling
+skip-if = asan || (os == 'linux' && debug) || (os == 'mac' && debug) # Bug 994798 for Linux debug disabling, bug 994300 for Mac debug disabling
 [browser_frameworker_sandbox.js]
-skip-if = asan || (os == 'linux' && debug) # Bug 994798 for Linux debug disabling
+skip-if = asan || (os == 'linux' && debug) || (os == 'mac' && debug) # Bug 994798 for Linux debug disabling, bug 994300 for Mac debug disabling
--- a/toolkit/content/widgets/findbar.xml
+++ b/toolkit/content/widgets/findbar.xml
@@ -169,23 +169,16 @@
                            xbl:inherits="accesskey=findpreviousaccesskey"/>
         <xul:toolbarbutton anonid="find-next"
                            class="findbar-find-next tabbable"
                            tooltiptext="&next.tooltip;"
                            oncommand="onFindAgainCommand(false);"
                            disabled="true"
                            xbl:inherits="accesskey=findnextaccesskey"/>
       </xul:hbox>
-      <xul:image anonid="find-status-icon" class="findbar-find-fast find-status-icon"/>
-      <xul:description anonid="find-status"
-                       control="findbar-textbox"
-                       class="findbar-find-fast findbar-find-status">
-      <!-- Do not use value, first child is used because it provides a11y with text change events -->
-      </xul:description>
-      <xul:spacer flex="1"/>
       <xul:toolbarbutton anonid="highlight"
                          class="findbar-highlight tabbable"
                          label="&highlightAll.label;"
                          accesskey="&highlightAll.accesskey;"
                          tooltiptext="&highlightAll.tooltiptext;"
                          oncommand="toggleHighlight(this.checked);"
                          type="checkbox"
                          xbl:inherits="accesskey=highlightaccesskey"/>
@@ -193,16 +186,22 @@
                          class="findbar-case-sensitive tabbable"
                          label="&caseSensitive.label;"
                          accesskey="&caseSensitive.accesskey;"
                          tooltiptext="&caseSensitive.tooltiptext;"
                          oncommand="_setCaseSensitivity(this.checked);"
                          type="checkbox"
                          xbl:inherits="accesskey=matchcaseaccesskey"/>
       <xul:label anonid="match-case-status" class="findbar-find-fast"/>
+      <xul:image anonid="find-status-icon" class="findbar-find-fast find-status-icon"/>
+      <xul:description anonid="find-status"
+                       control="findbar-textbox"
+                       class="findbar-find-fast findbar-find-status">
+      <!-- Do not use value, first child is used because it provides a11y with text change events -->
+      </xul:description>
     </xul:hbox>
     <xul:toolbarbutton anonid="find-closebutton"
                        class="findbar-closebutton close-icon"
                        tooltiptext="&findCloseButton.tooltip;"
                        oncommand="close();"/>
     </content>
 
     <implementation implements="nsIDOMEventListener, nsIEditActionListener">
--- a/toolkit/modules/Promise-backend.js
+++ b/toolkit/modules/Promise-backend.js
@@ -73,18 +73,37 @@ const N_WITNESS = Name("witness");
 // In this snippet, the error is reported both by p1 and by p2.
 //
 
 XPCOMUtils.defineLazyServiceGetter(this, "FinalizationWitnessService",
                                    "@mozilla.org/toolkit/finalizationwitness;1",
                                    "nsIFinalizationWitnessService");
 
 let PendingErrors = {
+  // An internal counter, used to generate unique id.
   _counter: 0,
+  // Functions registered to be notified when a pending error
+  // is reported as uncaught.
+  _observers: new Set(),
   _map: new Map(),
+
+  /**
+   * Initialize PendingErrors
+   */
+  init: function() {
+    Services.obs.addObserver(function observe(aSubject, aTopic, aValue) {
+      PendingErrors.report(aValue);
+    }, "promise-finalization-witness", false);
+  },
+
+  /**
+   * Register an error as tracked.
+   *
+   * @return The unique identifier of the error.
+   */
   register: function(error) {
     let id = "pending-error-" + (this._counter++);
     //
     // At this stage, ideally, we would like to store the error itself
     // and delay any treatment until we are certain that we will need
     // to report that error. However, in the (unlikely but possible)
     // case the error holds a reference to the promise itself, doing so
     // would prevent the promise from being garbabe-collected, which
@@ -161,56 +180,112 @@ let PendingErrors = {
         }
       }
     } catch (ex) {
       // Ignore value
     }
     this._map.set(id, value);
     return id;
   },
-  extract: function(id) {
+
+  /**
+   * Notify all observers that a pending error is now uncaught.
+   *
+   * @param id The identifier of the pending error, as returned by
+   * |register|.
+   */
+  report: function(id) {
     let value = this._map.get(id);
+    if (!value) {
+      return; // The error has already been reported
+    }
     this._map.delete(id);
-    return value;
+    for (let obs of this._observers.values()) {
+      obs(value);
+    }
   },
+
+  /**
+   * Mark all pending errors are uncaught, notify the observers.
+   */
+  flush: function() {
+    // Since we are going to modify the map while walking it,
+    // let's copying the keys first.
+    let keys = [key for (key of this._map.keys())];
+    for (let key of keys) {
+      this.report(key);
+    }
+  },
+
+  /**
+   * Stop tracking an error, as this error has been caught,
+   * eventually.
+   */
   unregister: function(id) {
     this._map.delete(id);
+  },
+
+  /**
+   * Add an observer notified when an error is reported as uncaught.
+   *
+   * @param {function} observer A function notified when an error is
+   * reported as uncaught. Its arguments are
+   *   {message, date, fileName, stack, lineNumber}
+   * All arguments are optional.
+   */
+  addObserver: function(observer) {
+    this._observers.add(observer);
+  },
+
+  /**
+   * Remove an observer added with addObserver
+   */
+  removeObserver: function(observer) {
+    this._observers.delete(observer);
+  },
+
+  /**
+   * Remove all the observers added with addObserver
+   */
+  removeAllObservers: function() {
+    this._observers.clear();
   }
 };
+PendingErrors.init();
 
-// Actually print the finalization warning.
-Services.obs.addObserver(function observe(aSubject, aTopic, aValue) {
-  let error = PendingErrors.extract(aValue);
-  let {message, date, fileName, stack, lineNumber} = error;
+// Default mechanism for displaying errors
+PendingErrors.addObserver(function(details) {
   let error = Cc['@mozilla.org/scripterror;1'].createInstance(Ci.nsIScriptError);
   if (!error || !Services.console) {
     // Too late during shutdown to use the nsIConsole
     dump("*************************\n");
     dump("A promise chain failed to handle a rejection\n\n");
-    dump("On: " + date + "\n");
-    dump("Full message: " + message + "\n");
+    dump("On: " + details.date + "\n");
+    dump("Full message: " + details.message + "\n");
     dump("See https://developer.mozilla.org/Mozilla/JavaScript_code_modules/Promise.jsm/Promise\n");
-    dump("Full stack: " + (stack||"not available") + "\n");
+    dump("Full stack: " + (details.stack||"not available") + "\n");
     dump("*************************\n");
     return;
   }
-  if (stack) {
-    message += "\nFull Stack: " + stack;
+  let message = details.message;
+  if (details.stack) {
+    message += "\nFull Stack: " + details.stack;
   }
   error.init(
              /*message*/"A promise chain failed to handle a rejection.\n\n" +
-             "Date: " + date + "\nFull Message: " + message,
-             /*sourceName*/ fileName,
-             /*sourceLine*/ lineNumber?("" + lineNumber):0,
-             /*lineNumber*/ lineNumber || 0,
+             "Date: " + details.date + "\nFull Message: " + details.message,
+             /*sourceName*/ details.fileName,
+             /*sourceLine*/ details.lineNumber?("" + details.lineNumber):0,
+             /*lineNumber*/ details.lineNumber || 0,
              /*columnNumber*/ 0,
              /*flags*/ Ci.nsIScriptError.errorFlag,
              /*category*/ "chrome javascript");
   Services.console.logMessage(error);
-}, "promise-finalization-witness", false);
+});
+
 
 ///////// Additional warnings for developers
 //
 // The following error types are considered programmer errors, which should be
 // reported (possibly redundantly) so as to let programmers fix their code.
 const ERRORS_TO_REPORT = ["EvalError", "RangeError", "ReferenceError", "TypeError"];
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -491,16 +566,56 @@ Promise.race = function (aValues)
 
   return new Promise((resolve, reject) => {
     for (let value of aValues) {
       Promise.resolve(value).then(resolve, reject);
     }
   });
 };
 
+Promise.Debugging = {
+  /**
+   * Add an observer notified when an error is reported as uncaught.
+   *
+   * @param {function} observer A function notified when an error is
+   * reported as uncaught. Its arguments are
+   *   {message, date, fileName, stack, lineNumber}
+   * All arguments are optional.
+   */
+  addUncaughtErrorObserver: function(observer) {
+    PendingErrors.addObserver(observer);
+  },
+
+  /**
+   * Remove an observer added with addUncaughtErrorObserver
+   *
+   * @param {function} An observer registered with
+   * addUncaughtErrorObserver.
+   */
+  removeUncaughtErrorObserver: function(observer) {
+    PendingErrors.removeObserver(observer);
+  },
+
+  /**
+   * Remove all the observers added with addUncaughtErrorObserver
+   */
+  clearUncaughtErrorObservers: function() {
+    PendingErrors.removeAllObservers();
+  },
+
+  /**
+   * Force all pending errors to be reported immediately as uncaught.
+   * Note that this may cause some false positives.
+   */
+  flushUncaughtErrors: function() {
+    PendingErrors.flush();
+  },
+};
+Object.freeze(Promise.Debugging);
+
 Object.freeze(Promise);
 
 ////////////////////////////////////////////////////////////////////////////////
 //// PromiseWalker
 
 /**
  * This singleton object invokes the handlers registered on resolved and
  * rejected promises, ensuring that processing is not recursive and is done in
--- a/toolkit/modules/tests/xpcshell/test_Promise.js
+++ b/toolkit/modules/tests/xpcshell/test_Promise.js
@@ -1,16 +1,20 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 Components.utils.import("resource://gre/modules/Promise.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Task.jsm");
 
+// Deactivate the standard xpcshell observer, as it turns uncaught
+// rejections into failures, which we don't want here.
+Promise.Debugging.clearUncaughtErrorObservers();
+
 ////////////////////////////////////////////////////////////////////////////////
 //// Test runner
 
 let run_promise_tests = function run_promise_tests(tests, cb) {
   let loop = function loop(index) {
     if (index >= tests.length) {
       if (cb) {
         cb.call();
@@ -954,38 +958,36 @@ tests.push(
 function wait_for_uncaught(aMustAppear, aTimeout = undefined) {
   let remaining = new Set();
   for (let k of aMustAppear) {
     remaining.add(k);
   }
   let deferred = Promise.defer();
   let print = do_print;
   let execute_soon = do_execute_soon;
-  let observer = function(aMessage) {
-    execute_soon(function() {
-      let message = aMessage.message;
-      print("Observing " + message);
-      for (let expected of remaining) {
-        if (message.indexOf(expected) != -1) {
-          print("I found " + expected);
-          remaining.delete(expected);
-        }
+  let observer = function({message, stack}) {
+    let data = message + stack;
+    print("Observing " + message + ", looking for " + aMustAppear.join(", "));
+    for (let expected of remaining) {
+      if (data.indexOf(expected) != -1) {
+        print("I found " + expected);
+        remaining.delete(expected);
       }
       if (remaining.size == 0 && observer) {
-        Services.console.unregisterListener(observer);
+        Promise.Debugging.removeUncaughtErrorObserver(observer);
         observer = null;
         deferred.resolve();
       }
-    });
+    }
   };
-  Services.console.registerListener(observer);
+  Promise.Debugging.addUncaughtErrorObserver(observer);
   if (aTimeout) {
     do_timeout(aTimeout, function timeout() {
       if (observer) {
-        Services.console.unregisterListener(observer);
+        Promise.Debugging.removeUncaughtErrorObserver(observer);
         observer = null;
       }
       deferred.reject(new Error("Timeout"));
     });
   }
   return deferred.promise;
 }
 
@@ -1050,16 +1052,17 @@ function wait_for_uncaught(aMustAppear, 
           //
           // Unfortunately, we might still have intermittent failures,
           // materialized as timeouts.
           //
           for (let i = 0; i < 100; ++i) {
             Promise.reject(error);
           }
         })();
+        do_print("Posted all rejections");
         Components.utils.forceGC();
         Components.utils.forceCC();
         Components.utils.forceShrinkingGC();
         return promise;
       }));
   }
 })();
 
--- a/widget/cocoa/nsClipboard.mm
+++ b/widget/cocoa/nsClipboard.mm
@@ -461,25 +461,19 @@ nsClipboard::PasteboardDictFromTransfera
       ptrPrimitive->GetData(getter_AddRefs(primitiveData));
 
       nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
       if (!image) {
         NS_WARNING("Image isn't an imgIContainer in transferable");
         continue;
       }
 
-      nsRefPtr<gfxASurface> thebesSurface =
+      RefPtr<SourceSurface> surface =
         image->GetFrame(imgIContainer::FRAME_CURRENT,
                         imgIContainer::FLAG_SYNC_DECODE);
-      if (!thebesSurface) {
-        continue;
-      }
-      RefPtr<SourceSurface> surface =
-        gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(
-          gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget(), thebesSurface);
       if (!surface) {
         continue;
       }
       CGImageRef imageRef = NULL;
       nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &imageRef);
       if (NS_FAILED(rv) || !imageRef) {
         continue;
       }
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; 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 "gfxImageSurface.h"
 #include "gfxPlatform.h"
+#include "gfxUtils.h"
 #include "nsCocoaUtils.h"
 #include "nsChildView.h"
 #include "nsMenuBarX.h"
 #include "nsCocoaWindow.h"
 #include "nsCOMPtr.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIAppShellService.h"
 #include "nsIXULWindow.h"
@@ -21,17 +22,22 @@
 #include "mozilla/gfx/2D.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/TextEvents.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
+using mozilla::gfx::BackendType;
 using mozilla::gfx::DataSourceSurface;
+using mozilla::gfx::DrawTarget;
+using mozilla::gfx::Factory;
+using mozilla::gfx::IntPoint;
+using mozilla::gfx::IntRect;
 using mozilla::gfx::IntSize;
 using mozilla::gfx::SurfaceFormat;
 using mozilla::gfx::SourceSurface;
 
 static float
 MenuBarScreenHeight()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
@@ -273,20 +279,29 @@ void data_ss_release_callback(void *aDat
     static_cast<DataSourceSurface*>(aDataSourceSurface)->Unmap();
     static_cast<DataSourceSurface*>(aDataSourceSurface)->Release();
   }
 }
 
 nsresult nsCocoaUtils::CreateCGImageFromSurface(SourceSurface* aSurface,
                                                 CGImageRef* aResult)
 {
-  RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
+  RefPtr<DataSourceSurface> dataSurface;
 
-  MOZ_ASSERT(dataSurface->GetFormat() ==  SurfaceFormat::B8G8R8A8,
-             "We assume B8G8R8A8 when calling CGImageCreate");
+  if (aSurface->GetFormat() ==  SurfaceFormat::B8G8R8A8) {
+    dataSurface = aSurface->GetDataSurface();
+  } else {
+    // CGImageCreate only supports 16- and 32-bit bit-depth
+    // Convert format to SurfaceFormat::B8G8R8A8
+    dataSurface = gfxUtils::
+      CopySurfaceToDataSourceSurfaceWithFormat(aSurface,
+                                               SurfaceFormat::B8G8R8A8);
+  }
+
+  NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
 
   int32_t width = dataSurface->GetSize().width;
   int32_t height = dataSurface->GetSize().height;
   if (height < 1 || width < 1) {
     return NS_ERROR_FAILURE;
   }
 
   DataSourceSurface::MappedSurface map;
@@ -396,27 +411,17 @@ nsresult nsCocoaUtils::CreateNSImageFrom
       gfxRect(0.0f, 0.0f, scaledWidth, scaledHeight),
       nsIntRect(0, 0, width, height),
       nsIntSize(scaledWidth, scaledHeight),
       nullptr, aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
 
     surface =
       gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, frame);
   } else {
-    nsRefPtr<gfxASurface> thebesSurface =
-      aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
-    NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
-
-    nsRefPtr<gfxImageSurface> thebesImageSurface =
-      thebesSurface->GetAsReadableARGB32ImageSurface();
-    NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
-
-    surface =
-      gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
-                                                             thebesImageSurface);
+    surface = aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
   }
 
   NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
   CGImageRef imageRef = NULL;
   nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &imageRef);
   if (NS_FAILED(rv) || !imageRef) {
     return NS_ERROR_FAILURE;
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -382,28 +382,24 @@ nsMenuItemIconX::OnStopFrame(imgIRequest
        mImageRegionRect.YMost() > origHeight)) {
     [mNativeMenuItem setImage:nil];
     return NS_ERROR_FAILURE;
   }
 
   if (mImageRegionRect.IsEmpty()) {
     mImageRegionRect.SetRect(0, 0, origWidth, origHeight);
   }
-  
-  nsRefPtr<gfxASurface> thebesSurface =
+
+  RefPtr<SourceSurface> surface =
     imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
                              imgIContainer::FLAG_NONE);
-  if (!thebesSurface) {
+  if (!surface) {
     [mNativeMenuItem setImage:nil];
     return NS_ERROR_FAILURE;
   }
-  RefPtr<SourceSurface> surface =
-    gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
-                                                           thebesSurface);
-  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
   CGImageRef origImage = NULL;
   nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &origImage);
   if (NS_FAILED(rv) || !origImage) {
     [mNativeMenuItem setImage:nil];
     return NS_ERROR_FAILURE;
   }
 
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -237,20 +237,16 @@ HwcComposer2D::PrepareLayerList(Layer* a
 
     if (!transform3D.Is2D(&transform) || !transform.PreservesAxisAlignedRectangles()) {
         LOGD("Layer has a 3D transform or a non-square angle rotation");
         return false;
     }
 
 
     if (ContainerLayer* container = aLayer->AsContainerLayer()) {
-        if (container->UseIntermediateSurface()) {
-            LOGD("Container layer needs intermediate surface");
-            return false;
-        }
         nsAutoTArray<Layer*, 12> children;
         container->SortChildrenBy3DZOrder(children);
 
         for (uint32_t i = 0; i < children.Length(); i++) {
             if (!PrepareLayerList(children[i], clip, transform, aGLWorldTransform)) {
                 return false;
             }
         }
@@ -325,22 +321,34 @@ HwcComposer2D::PrepareLayerList(Layer* a
     if (!mList || current >= mMaxLayerCount) {
         if (!ReallocLayerList() || current >= mMaxLayerCount) {
             LOGE("PrepareLayerList failed! Could not increase the maximum layer count");
             return false;
         }
     }
 
     HwcLayer& hwcLayer = mList->hwLayers[current];
+    hwcLayer.flags = 0;
+
+    if (ContainerLayer* parent = aLayer->GetParent()) {
+        if (parent->UseIntermediateSurface()) {
+            LOGD("Parent container needs intermediate surface");
+            hwcLayer.flags = HWC_SKIP_LAYER;
+#if ANDROID_VERSION < 18
+            // No partial HWC Composition on older versions
+            return false;
+#endif
+        }
+    }
+
     hwcLayer.displayFrame = displayFrame;
     setCrop(&hwcLayer, sourceCrop);
     buffer_handle_t handle = fillColor ? nullptr : state.mSurface->getNativeBuffer()->handle;
     hwcLayer.handle = handle;
 
-    hwcLayer.flags = 0;
     hwcLayer.hints = 0;
     hwcLayer.blending = isOpaque ? HWC_BLENDING_NONE : HWC_BLENDING_PREMULT;
 #if ANDROID_VERSION >= 17
     hwcLayer.compositionType = HWC_FRAMEBUFFER;
 
     hwcLayer.acquireFenceFd = -1;
     hwcLayer.releaseFenceFd = -1;
 #if ANDROID_VERSION >= 18
--- a/widget/gtk/nsImageToPixbuf.cpp
+++ b/widget/gtk/nsImageToPixbuf.cpp
@@ -38,33 +38,28 @@ NS_IMETHODIMP_(GdkPixbuf*)
 nsImageToPixbuf::ConvertImageToPixbuf(imgIContainer* aImage)
 {
     return ImageToPixbuf(aImage);
 }
 
 GdkPixbuf*
 nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
 {
-    nsRefPtr<gfxASurface> thebesSurface =
+    RefPtr<SourceSurface> surface =
       aImage->GetFrame(imgIContainer::FRAME_CURRENT,
                        imgIContainer::FLAG_SYNC_DECODE);
 
     // If the last call failed, it was probably because our call stack originates
     // in an imgINotificationObserver event, meaning that we're not allowed request
     // a sync decode. Presumably the originating event is something sensible like
     // OnStopFrame(), so we can just retry the call without a sync decode.
-    if (!thebesSurface)
-      thebesSurface = aImage->GetFrame(imgIContainer::FRAME_CURRENT,
-                                       imgIContainer::FLAG_NONE);
+    if (!surface)
+      surface = aImage->GetFrame(imgIContainer::FRAME_CURRENT,
+                                 imgIContainer::FLAG_NONE);
 
-    NS_ENSURE_TRUE(thebesSurface, nullptr);
-
-    RefPtr<SourceSurface> surface =
-      gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
-                                                             thebesSurface);
     NS_ENSURE_TRUE(surface, nullptr);
 
     return SourceSurfaceToPixbuf(surface,
                                  surface->GetSize().width,
                                  surface->GetSize().height);
 }
 
 GdkPixbuf*
--- a/widget/qt/nsClipboard.cpp
+++ b/widget/qt/nsClipboard.cpp
@@ -174,25 +174,19 @@ nsClipboard::SetNativeClipboardData( nsI
                     continue;
 
                 nsCOMPtr<nsISupports> primitiveData;
                 ptrPrimitive->GetData(getter_AddRefs(primitiveData));
                 nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
                 if (!image)  // Not getting an image for an image mime type!?
                    continue;
 
-                nsRefPtr<gfxASurface> thebesSurface =
+                RefPtr<SourceSurface> surface =
                   image->GetFrame(imgIContainer::FRAME_CURRENT,
                                   imgIContainer::FLAG_SYNC_DECODE);
-                if (!thebesSurface)
-                  continue;
-
-                RefPtr<SourceSurface> surface =
-                  gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
-                                                                         thebesSurface);
                 if (!surface)
                   continue;
 
                 RefPtr<DataSourceSurface> dataSurface =
                   surface->GetDataSurface();
                 if (!dataSurface)
                   continue;
 
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -726,22 +726,18 @@ AsyncFaviconDataReady::OnComplete(nsIURI
   nsAutoCString mimeTypeOfInputData;
   mimeTypeOfInputData.AssignLiteral("image/vnd.microsoft.icon");
   nsCOMPtr<imgIContainer> container;
   nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1");
   rv = imgtool->DecodeImageData(stream, aMimeType,
                                 getter_AddRefs(container));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<gfxASurface> imgFrame =
+  RefPtr<SourceSurface> surface =
     container->GetFrame(imgIContainer::FRAME_FIRST, 0);
-  NS_ENSURE_TRUE(imgFrame, NS_ERROR_FAILURE);
-
-  RefPtr<SourceSurface> surface =
-    gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imgFrame);
   NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
   RefPtr<DataSourceSurface> dataSurface;
   IntSize size;
 
   if (mURLShortcut) {
     // Create a 48x48 surface and paint the icon into the central 16x16 rect.
     size.width = 48;
--- a/widget/windows/nsImageClipboard.cpp
+++ b/widget/windows/nsImageClipboard.cpp
@@ -1,17 +1,20 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
+#include "nsImageClipboard.h"
+
+#include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/RefPtr.h"
 #include "nsITransferable.h"
-#include "nsImageClipboard.h"
 #include "nsGfxCIID.h"
 #include "nsMemory.h"
 #include "prmem.h"
 #include "imgIEncoder.h"
 #include "nsLiteralString.h"
 #include "nsComponentManagerUtils.h"
 
 #define BFH_LENGTH 14
@@ -115,32 +118,34 @@ nsImageToClipboard::CalcSpanLength(uint3
 // image. 
 //
 nsresult
 nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap )
 {
     nsresult rv;
     *outBitmap = nullptr;
 
-    nsRefPtr<gfxASurface> thebesSurface =
+    RefPtr<SourceSurface> surface =
       inImage->GetFrame(imgIContainer::FRAME_CURRENT,
                         imgIContainer::FLAG_SYNC_DECODE);
-    NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
-    nsRefPtr<gfxImageSurface> thebesImageSurface =
-      thebesSurface->GetAsReadableARGB32ImageSurface();
-    NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
+    MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+               surface->GetFormat() == SurfaceFormat::B8G8R8X8);
 
-    IntSize surfaceSize(thebesImageSurface->GetSize().width,
-                        thebesImageSurface->GetSize().height);
-    RefPtr<DataSourceSurface> dataSurface =
-      Factory::CreateWrappingDataSourceSurface(thebesImageSurface->Data(),
-                                               thebesImageSurface->Stride(),
-                                               surfaceSize,
-                                               SurfaceFormat::B8G8R8A8);
+    RefPtr<DataSourceSurface> dataSurface;
+    if (surface->GetFormat() == SurfaceFormat::B8G8R8A8) {
+      dataSurface = surface->GetDataSurface();
+    } else {
+      // XXXjwatt Bug 995923 - get rid of this copy and handle B8G8R8X8
+      // directly below once bug 995807 is fixed.
+      dataSurface = gfxUtils::
+        CopySurfaceToDataSourceSurfaceWithFormat(surface,
+                                                 SurfaceFormat::B8G8R8A8);
+    }
     NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
 
     nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/bmp", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     
     uint32_t format;
     nsAutoString options;
     if (mWantDIBV5) {
@@ -148,21 +153,25 @@ nsImageToClipboard::CreateFromImage ( im
     } else {
       options.AppendLiteral("version=3;bpp=");
     }
     switch (dataSurface->GetFormat()) {
     case SurfaceFormat::B8G8R8A8:
         format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
         options.AppendInt(32);
         break;
+#if 0
+    // XXXjwatt Bug 995923 - fix |format| and reenable once bug 995807 is fixed.
     case SurfaceFormat::B8G8R8X8:
         format = imgIEncoder::INPUT_FORMAT_RGB;
         options.AppendInt(24);
         break;
+#endif
     default:
+        NS_NOTREACHED("Unexpected surface format");
         return NS_ERROR_INVALID_ARG;  
     }
 
     DataSourceSurface::MappedSurface map;
     bool mappedOK = dataSurface->Map(DataSourceSurface::MapType::READ, &map);
     NS_ENSURE_TRUE(mappedOK, NS_ERROR_FAILURE);
 
     rv = encoder->InitFromData(map.mData, 0,
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -48,17 +48,16 @@ using mozilla::plugins::PluginInstancePa
 #ifdef MOZ_ENABLE_D3D10_LAYER
 #include "LayerManagerD3D10.h"
 #endif
 #include "mozilla/layers/CompositorParent.h"
 #include "ClientLayerManager.h"
 
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
-#include "mozilla/gfx/2D.h"
 
 extern "C" {
 #define PIXMAN_DONT_DEFINE_STDINT
 #include "pixman.h"
 }
 
 using namespace mozilla;
 using namespace mozilla::gfx;
@@ -611,57 +610,52 @@ nsresult nsWindowGfx::CreateIcon(imgICon
                                   uint32_t aHotspotY,
                                   gfxIntSize aScaledSize,
                                   HICON *aIcon) {
 
   MOZ_ASSERT((aScaledSize.width > 0 && aScaledSize.height > 0) ||
              (aScaledSize.width == 0 && aScaledSize.height == 0));
 
   // Get the image data
-  nsRefPtr<gfxASurface> thebesSurface =
+  RefPtr<SourceSurface> surface =
     aContainer->GetFrame(imgIContainer::FRAME_CURRENT,
                          imgIContainer::FLAG_SYNC_DECODE);
-  NS_ENSURE_TRUE(thebesSurface, NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(surface, NS_ERROR_NOT_AVAILABLE);
 
-  RefPtr<SourceSurface> surface =
-    gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr,
-                                                           thebesSurface);
-  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
-
-  IntSize surfaceSize(surface->GetSize().width, surface->GetSize().height);
-  if (surfaceSize.IsEmpty()) {
+  IntSize frameSize = surface->GetSize();
+  if (frameSize.IsEmpty()) {
     return NS_ERROR_FAILURE;
   }
 
   IntSize iconSize(aScaledSize.width, aScaledSize.height);
   if (iconSize == IntSize(0, 0)) { // use frame's intrinsic size
-    iconSize = surfaceSize;
+    iconSize = frameSize;
   }
 
   RefPtr<DataSourceSurface> dataSurface;
   bool mappedOK;
   DataSourceSurface::MappedSurface map;
 
-  if (iconSize != surfaceSize) {
+  if (iconSize != frameSize) {
     // Scale the surface
     dataSurface = Factory::CreateDataSourceSurface(iconSize,
                                                    SurfaceFormat::B8G8R8A8);
     NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
     mappedOK = dataSurface->Map(DataSourceSurface::MapType::READ_WRITE, &map);
     NS_ENSURE_TRUE(mappedOK, NS_ERROR_FAILURE);
 
     RefPtr<DrawTarget> dt =
       Factory::CreateDrawTargetForData(BackendType::CAIRO,
                                        map.mData,
                                        dataSurface->GetSize(),
                                        map.mStride,
                                        SurfaceFormat::B8G8R8A8);
     dt->DrawSurface(surface,
                     Rect(0, 0, iconSize.width, iconSize.height),
-                    Rect(0, 0, surfaceSize.width, surfaceSize.height),
+                    Rect(0, 0, frameSize.width, frameSize.height),
                     DrawSurfaceOptions(),
                     DrawOptions(1.0f, CompositionOp::OP_SOURCE));
   } else if (surface->GetFormat() != SurfaceFormat::B8G8R8A8) {
     // Convert format to SurfaceFormat::B8G8R8A8
     dataSurface = gfxUtils::
       CopySurfaceToDataSourceSurfaceWithFormat(surface,
                                                SurfaceFormat::B8G8R8A8);
     NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
--- a/widget/windows/winrt/APZController.cpp
+++ b/widget/windows/winrt/APZController.cpp
@@ -298,30 +298,42 @@ class TransformedEndEvent : public nsRun
 {
   NS_IMETHOD Run() {
     MetroUtils::FireObserver("apzc-transform-end", L"");
     return NS_OK;
   }
 };
 
 void
-APZController::NotifyTransformBegin(const ScrollableLayerGuid& aGuid)
+APZController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+                                    APZStateChange aChange,
+                                    int aArg)
 {
-  if (NS_IsMainThread()) {
-    MetroUtils::FireObserver("apzc-transform-begin", L"");
-    return;
+  switch (aChange) {
+    case APZStateChange::TransformBegin:
+    {
+      if (NS_IsMainThread()) {
+        MetroUtils::FireObserver("apzc-transform-begin", L"");
+        return;
+      }
+      nsCOMPtr<nsIRunnable> runnable = new TransformedStartEvent();
+      NS_DispatchToMainThread(runnable);
+      break;
+    }
+    case APZStateChange::TransformEnd:
+    {
+      if (NS_IsMainThread()) {
+        MetroUtils::FireObserver("apzc-transform-end", L"");
+        return;
+      }
+      nsCOMPtr<nsIRunnable> runnable = new TransformedEndEvent();
+      NS_DispatchToMainThread(runnable);
+      break;
+    }
+    default:
+    {
+      // We don't currently care about other state changes.
+      break;
+    }
   }
-  nsCOMPtr<nsIRunnable> runnable = new TransformedStartEvent();
-  NS_DispatchToMainThread(runnable);
-}
-
-void
-APZController::NotifyTransformEnd(const ScrollableLayerGuid& aGuid)
-{
-  if (NS_IsMainThread()) {
-    MetroUtils::FireObserver("apzc-transform-end", L"");
-    return;
-  }
-  nsCOMPtr<nsIRunnable> runnable = new TransformedEndEvent();
-  NS_DispatchToMainThread(runnable);
 }
 
 } } }
--- a/widget/windows/winrt/APZController.h
+++ b/widget/windows/winrt/APZController.h
@@ -44,18 +44,19 @@ public:
                              int32_t aModifiers,
                              const mozilla::layers::ScrollableLayerGuid& aGuid);
   virtual void HandleLongTapUp(const mozilla::CSSPoint& aPoint,
                                int32_t aModifiers,
                                const mozilla::layers::ScrollableLayerGuid& aGuid);
   virtual void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
   virtual void PostDelayedTask(Task* aTask, int aDelayMs);
   virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints);
-  virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid);
-  virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid);
+  virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+                                    APZStateChange aChange,
+                                    int aArg);
   
   void SetWidgetListener(nsIWidgetListener* aWidgetListener);
 
   bool HitTestAPZC(mozilla::ScreenIntPoint& aPoint);
   void TransformCoordinateToGecko(const mozilla::ScreenIntPoint& aPoint,
                                   LayoutDeviceIntPoint* aRefPointOut);
   void ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPreventDefault);
   nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aEvent,
new file mode 100644
--- /dev/null
+++ b/widget/xpwidgets/ActiveElementManager.cpp
@@ -0,0 +1,151 @@
+/* -*- 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 "ActiveElementManager.h"
+#include "mozilla/EventStates.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
+#include "inIDOMUtils.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMElement.h"
+#include "nsIDOMEventTarget.h"
+#include "base/message_loop.h"
+#include "base/task.h"
+
+namespace mozilla {
+namespace widget {
+
+static int32_t sActivationDelayMs = 100;
+static bool sActivationDelayMsSet = false;
+
+ActiveElementManager::ActiveElementManager()
+  : mDomUtils(services::GetInDOMUtils()),
+    mCanBePan(false),
+    mCanBePanSet(false),
+    mSetActiveTask(nullptr)
+{
+  if (!sActivationDelayMsSet) {
+    Preferences::AddIntVarCache(&sActivationDelayMs,
+                                "ui.touch_activation.delay_ms",
+                                sActivationDelayMs);
+    sActivationDelayMsSet = true;
+  }
+}
+
+ActiveElementManager::~ActiveElementManager() {}
+
+void
+ActiveElementManager::SetTargetElement(nsIDOMEventTarget* aTarget)
+{
+  if (mTarget) {
+    // Multiple fingers on screen (since HandleTouchEnd clears mTarget).
+    ResetActive();
+    return;
+  }
+
+  mTarget = do_QueryInterface(aTarget);
+  TriggerElementActivation();
+}
+
+void
+ActiveElementManager::HandleTouchStart(bool aCanBePan)
+{
+  mCanBePan = aCanBePan;
+  mCanBePanSet = true;
+  TriggerElementActivation();
+}
+
+void
+ActiveElementManager::TriggerElementActivation()
+{
+  // Both HandleTouchStart() and SetTargetElement() call this. They can be
+  // called in either order. One will set mCanBePanSet, and the other, mTarget.
+  // We want to actually trigger the activation once both are set.
+  if (!(mTarget && mCanBePanSet)) {
+    return;
+  }
+
+  // If the touch cannot be a pan, make mTarget :active right away.
+  // Otherwise, wait a bit to see if the user will pan or not.
+  if (!mCanBePan) {
+    SetActive(mTarget);
+  } else {
+    mSetActiveTask = NewRunnableMethod(
+        this, &ActiveElementManager::SetActiveTask, mTarget);
+    MessageLoop::current()->PostDelayedTask(
+        FROM_HERE, mSetActiveTask, sActivationDelayMs);
+  }
+}
+
+void
+ActiveElementManager::HandlePanStart()
+{
+  // The user started to pan, so we don't want mTarget to be :active.
+  // Make it not :active, and clear any pending task to make it :active.
+  CancelTask();
+  ResetActive();
+}
+
+void
+ActiveElementManager::HandleTouchEnd(bool aWasClick)
+{
+  // If the touch was a click, make mTarget :active right away.
+  // nsEventStateManager will reset the active element when processing
+  // the mouse-down event generated by the click.
+  CancelTask();
+  if (aWasClick) {
+    SetActive(mTarget);
+  }
+
+  // Clear mTarget for next touch.
+  mTarget = nullptr;
+}
+
+void
+ActiveElementManager::SetActive(nsIDOMElement* aTarget)
+{
+  if (mDomUtils) {
+    mDomUtils->SetContentState(aTarget, NS_EVENT_STATE_ACTIVE.GetInternalValue());;
+  }
+}
+
+void
+ActiveElementManager::ResetActive()
+{
+  // Clear the :active flag from mTarget by setting it on the document root.
+  if (mTarget) {
+    nsCOMPtr<nsIDOMDocument> doc;
+    mTarget->GetOwnerDocument(getter_AddRefs(doc));
+    if (doc) {
+      nsCOMPtr<nsIDOMElement> root;
+      doc->GetDocumentElement(getter_AddRefs(root));
+      if (root) {
+        SetActive(root);
+      }
+    }
+  }
+}
+
+void
+ActiveElementManager::SetActiveTask(nsIDOMElement* aTarget)
+{
+  // This gets called from mSetActiveTask's Run() method. The message loop
+  // deletes the task right after running it, so we need to null out
+  // mSetActiveTask to make sure we're not left with a dangling pointer.
+  mSetActiveTask = nullptr;
+  SetActive(aTarget);
+}
+
+void
+ActiveElementManager::CancelTask()
+{
+  if (mSetActiveTask) {
+    mSetActiveTask->Cancel();
+    mSetActiveTask = nullptr;
+  }
+}
+
+}
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/widget/xpwidgets/ActiveElementManager.h
@@ -0,0 +1,85 @@
+/* -*- 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_widget_ActiveElementManager_h__
+#define __mozilla_widget_ActiveElementManager_h__
+
+#include "nsCOMPtr.h"
+#include "nsISupportsImpl.h"
+
+class inIDOMUtils;
+class nsIDOMEventTarget;
+class nsIDOMElement;
+class CancelableTask;
+
+namespace mozilla {
+namespace widget {
+
+/**
+ * Manages setting and clearing the ':active' CSS pseudostate in the presence
+ * of touch input.
+ */
+class ActiveElementManager {
+public:
+  NS_INLINE_DECL_REFCOUNTING(ActiveElementManager)
+
+  ActiveElementManager();
+  ~ActiveElementManager();
+
+  /**
+   * Specify the target of a touch. Typically this should be called right
+   * before HandleTouchStart(), but we give callers the flexibility to specify
+   * the target later if they don't know it at the time they call
+   * HandleTouchStart().
+   * |aTarget| may be nullptr.
+   */
+  void SetTargetElement(nsIDOMEventTarget* aTarget);
+  /**
+   * Handle a touch-start event.
+   * @param aCanBePan whether the touch can be a pan
+   */
+  void HandleTouchStart(bool aCanBePan);
+  /**
+   * Handle the start of panning.
+   */
+  void HandlePanStart();
+  /**
+   * Handle a touch-end or touch-cancel event.
+   * @param aWasClick whether the touch was a click
+   */
+  void HandleTouchEnd(bool aWasClick);
+private:
+  nsCOMPtr<inIDOMUtils> mDomUtils;
+  /**
+   * The target of the first touch point in the current touch block.
+   */
+  nsCOMPtr<nsIDOMElement> mTarget;
+  /**
+   * Whether the current touch block can be a pan. Set in HandleTouchStart().
+   */
+  bool mCanBePan;
+  /**
+   * Whether mCanBePan has been set for the current touch block.
+   * We need to keep track of this to allow HandleTouchStart() and
+   * SetTargetElement() to be called in either order.
+   */
+  bool mCanBePanSet;
+  /**
+   * A task for calling SetActive() after a timeout.
+   */
+  CancelableTask* mSetActiveTask;
+
+  // Helpers
+  void TriggerElementActivation();
+  void SetActive(nsIDOMElement* aTarget);
+  void ResetActive();
+  void SetActiveTask(nsIDOMElement* aTarget);
+  void CancelTask();
+};
+
+}
+}
+
+#endif /*__mozilla_widget_ActiveElementManager_h__ */
--- a/widget/xpwidgets/moz.build
+++ b/widget/xpwidgets/moz.build
@@ -1,23 +1,25 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
+    'ActiveElementManager.h',
     'APZCCallbackHelper.h',
     'ContentHelper.h',
     'GfxDriverInfo.h',
     'GfxInfoBase.h',
     'GfxInfoCollector.h',
 ]
 
 UNIFIED_SOURCES += [
+    'ActiveElementManager.cpp',
     'APZCCallbackHelper.cpp',
     'ContentHelper.cpp',
     'GfxDriverInfo.cpp',
     'GfxInfoBase.cpp',
     'GfxInfoCollector.cpp',
     'GfxInfoWebGL.cpp',
     'InputData.cpp',
     'nsBaseAppShell.cpp',
--- a/xpcom/build/ServiceList.h
+++ b/xpcom/build/ServiceList.h
@@ -9,16 +9,17 @@ MOZ_SERVICE(AccessibilityService, nsIAcc
 MOZ_SERVICE(ChromeRegistryService, nsIChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(ToolkitChromeRegistryService, nsIToolkitChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(XULChromeRegistryService, nsIXULChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(XULOverlayProviderService, nsIXULOverlayProvider, "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(IOService, nsIIOService, "@mozilla.org/network/io-service;1")
 MOZ_SERVICE(ObserverService, nsIObserverService, "@mozilla.org/observer-service;1")
 MOZ_SERVICE(StringBundleService, nsIStringBundleService, "@mozilla.org/intl/stringbundle;1")
 MOZ_SERVICE(XPConnect, nsIXPConnect, "@mozilla.org/js/xpc/XPConnect;1")
+MOZ_SERVICE(InDOMUtils, inIDOMUtils, "@mozilla.org/inspector/dom-utils;1")
 
 #ifdef MOZ_USE_NAMESPACE
 namespace mozilla
 {
 #endif
 
 MOZ_SERVICE(HistoryService, IHistory, "@mozilla.org/browser/history;1")
 
--- a/xpcom/build/Services.cpp
+++ b/xpcom/build/Services.cpp
@@ -15,16 +15,17 @@
 #include "nsNetCID.h"
 #include "nsObserverService.h"
 #include "nsXPCOMPrivate.h"
 #include "nsIStringBundle.h"
 #include "nsIToolkitChromeRegistry.h"
 #include "nsIXULOverlayProvider.h"
 #include "IHistory.h"
 #include "nsIXPConnect.h"
+#include "inIDOMUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::services;
 
 /*
  * Define a global variable and a getter for every service in ServiceList.
  * eg. gIOService and GetIOService()
  */
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -121,19 +121,16 @@ extern nsresult nsStringInputStreamConst
 #include "base/command_line.h"
 #include "base/message_loop.h"
 
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/AvailableMemoryTracker.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SystemMemoryReporter.h"
 
-#include "mozilla/layers/ImageBridgeChild.h"
-#include "mozilla/layers/CompositorParent.h"
-
 #ifdef MOZ_VISUAL_EVENT_TRACER
 #include "mozilla/VisualEventTracer.h"
 #endif
 
 #include "ogg/ogg.h"
 #ifdef MOZ_VPX
 #include "vpx_mem/vpx_mem.h"
 #endif
@@ -740,21 +737,16 @@ ShutdownXPCOM(nsIServiceManager* servMgr
             if (NS_SUCCEEDED(rv))
             {
                 (void) observerService->
                     NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                     nullptr);
             }
         }
 
-        // This must happen after the shutdown of media and widgets, which
-        // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
-        mozilla::layers::ImageBridgeChild::ShutDown();
-        mozilla::layers::CompositorParent::ShutDown();
-
         NS_ProcessPendingEvents(thread);
         mozilla::scache::StartupCache::DeleteSingleton();
         if (observerService)
             (void) observerService->
                 NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
                                 nullptr);
 
         gXPCOMThreadsShutDown = true;
--- a/xpcom/ds/moz.build
+++ b/xpcom/ds/moz.build
@@ -48,18 +48,16 @@ EXPORTS += [
     'nsAtomService.h',
     'nsCharSeparatedTokenizer.h',
     'nsCheapSets.h',
     'nsCRT.h',
     'nsExpirationTracker.h',
     'nsHashPropertyBag.h',
     'nsHashtable.h',
     'nsMathUtils.h',
-    'nsObserverList.h',
-    'nsObserverService.h',
     'nsStaticAtom.h',
     'nsStaticNameTable.h',
     'nsStringEnumerator.h',
     'nsSupportsArray.h',
     'nsSupportsPrimitives.h',
     'nsVariant.h',
     'nsWhitespaceTokenizer.h',
 ]
--- a/xpcom/ds/nsObserverService.cpp
+++ b/xpcom/ds/nsObserverService.cpp
@@ -217,17 +217,17 @@ nsObserverService::Create(nsISupports* o
         NS_NewRunnableMethod(os, &nsObserverService::RegisterReporter);
     NS_DispatchToCurrentThread(registerRunnable);
 
     return os->QueryInterface(aIID, aInstancePtr);
 }
 
 #define NS_ENSURE_VALIDCALL \
     if (!NS_IsMainThread()) {                                     \
-        NS_ERROR("Using observer service off the main thread!");  \
+        MOZ_CRASH("Using observer service off the main thread!"); \
         return NS_ERROR_UNEXPECTED;                               \
     }                                                             \
     if (mShuttingDown) {                                          \
         NS_ERROR("Using observer service after XPCOM shutdown!"); \
         return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;                  \
     }
 
 NS_IMETHODIMP
--- a/xpcom/ds/nsObserverService.h
+++ b/xpcom/ds/nsObserverService.h
@@ -22,17 +22,17 @@ class nsObserverService MOZ_FINAL
   : public nsIObserverService
   , public nsIMemoryReporter
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_OBSERVERSERVICE_CID)
 
   nsObserverService();
 
-  NS_DECL_THREADSAFE_ISUPPORTS
+  NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVERSERVICE
   NS_DECL_NSIMEMORYREPORTER
 
   void Shutdown();
 
   static nsresult
   Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
 
--- a/xpcom/threads/BackgroundHangMonitor.cpp
+++ b/xpcom/threads/BackgroundHangMonitor.cpp
@@ -23,17 +23,17 @@
 #include <algorithm>
 
 namespace mozilla {
 
 /**
  * BackgroundHangManager is the global object that
  * manages all instances of BackgroundHangThread.
  */
-class BackgroundHangManager : public AtomicRefCounted<BackgroundHangManager>
+class BackgroundHangManager
 {
 private:
   // Background hang monitor thread function
   static void MonitorThread(void* aData)
   {
     PR_SetCurrentThreadName("BgHangManager");
 
 #ifdef MOZ_NUWA_PROCESS
@@ -57,17 +57,17 @@ private:
   // Stop hang monitoring
   bool mShutdown;
 
   BackgroundHangManager(const BackgroundHangManager&);
   BackgroundHangManager& operator=(const BackgroundHangManager&);
   void RunMonitorThread();
 
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(BackgroundHangManager)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundHangManager)
   static StaticRefPtr<BackgroundHangManager> sInstance;
 
   // Lock for access to members of this class
   Monitor mLock;
   // Current time as seen by hang monitors
   PRIntervalTime mIntervalNow;
   // List of BackgroundHangThread instances associated with each thread
   LinkedList<BackgroundHangThread> mHangThreads;