Merge inbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Wed, 07 Jan 2015 15:41:20 -0800
changeset 222539 70de2960aa877d7755ee6f66bf2d4c4c46bfed2c
parent 222476 ee72fef1c55494ac8a589e60e145bdca106b60ea (current diff)
parent 222538 58767ba4867e170256a7b50593ac04641d91a912 (diff)
child 222540 0d091f3311b4422a91d35b1764626325bc5252bd
child 222609 c6b66f2272252f2f0b3b59e1df19be2b1ab32eb5
child 222625 ca142ec8ba0f923cf1eab93fe3e888d00e17d320
push id28067
push userkwierso@gmail.com
push dateWed, 07 Jan 2015 23:41:38 +0000
treeherdermozilla-central@70de2960aa87 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0a1
first release with
nightly linux32
70de2960aa87 / 37.0a1 / 20150108030220 / files
nightly linux64
70de2960aa87 / 37.0a1 / 20150108030220 / files
nightly mac
70de2960aa87 / 37.0a1 / 20150108030220 / files
nightly win32
70de2960aa87 / 37.0a1 / 20150108030220 / files
nightly win64
70de2960aa87 / 37.0a1 / 20150108030220 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c a=merge CLOSED TREE
browser/base/content/test/general/browser_bug846489.js
browser/base/content/test/general/browser_bug846489_content.js
configure.in
mobile/android/chrome/content/browser.js
testing/web-platform/meta/webmessaging/postMessage_Date.sub.htm.ini
testing/web-platform/meta/webmessaging/postMessage_origin_mismatch.sub.htm.ini
testing/web-platform/meta/webmessaging/postMessage_origin_mismatch_xorigin.sub.htm.ini
testing/web-platform/meta/webmessaging/with-ports/010.html.ini
testing/web-platform/meta/webmessaging/with-ports/025.html.ini
testing/web-platform/meta/webmessaging/with-ports/026.html.ini
testing/web-platform/meta/webmessaging/without-ports/008.html.ini
testing/web-platform/meta/webmessaging/without-ports/009.html.ini
testing/web-platform/meta/webmessaging/without-ports/010.html.ini
testing/web-platform/meta/webmessaging/without-ports/026.html.ini
testing/web-platform/tests/cors/testrunner.html
testing/web-platform/tests/old-tests/submission/Infraware/Forms/contents/Forms/button_form.html
testing/web-platform/tests/old-tests/submission/Infraware/Forms/contents/Forms/datalist_options.html
testing/web-platform/tests/old-tests/submission/Infraware/Forms/contents/Forms/fieldset_form.html
testing/web-platform/tests/old-tests/submission/Infraware/Forms/contents/Forms/form_getterindex_2.html
testing/web-platform/tests/old-tests/submission/Infraware/Forms/contents/Forms/input_form.html
testing/web-platform/tests/old-tests/submission/Infraware/Forms/contents/Forms/keygen_form.html
testing/web-platform/tests/progress-events/tests/submissions/Samsung/resources/img.jpg
testing/web-platform/tests/progress-events/tests/submissions/Samsung/security-consideration.sub.html
xpcom/base/AlreadyAddRefed.h
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2638,21 +2638,16 @@ let BrowserOnClick = {
       return;
     }
 
     let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
                            .getService(Ci.nsISerializationHelper);
     let transportSecurityInfo = serhelper.deserializeObject(securityInfo);
     transportSecurityInfo.QueryInterface(Ci.nsITransportSecurityInfo)
 
-    if (transportSecurityInfo.failedCertChain == null) {
-      Cu.reportError("transportSecurityInfo didn't have a failedCertChain for a failedChannel");
-      return;
-    }
-
     showReportStatus("activity");
 
     /*
      * Requested info for the report:
      * - Domain of bad connection
      * - Error type (e.g. Pinning, domain mismatch, etc)
      * - Cert chain (at minimum, same data to distrust each cert in the
      *   chain)
@@ -2672,21 +2667,24 @@ let BrowserOnClick = {
         derString += String.fromCharCode(derArray[i]);
       }
       return derString;
     }
 
     // Convert the nsIX509CertList into a format that can be parsed into
     // JSON
     let asciiCertChain = [];
-    let certs = transportSecurityInfo.failedCertChain.getEnumerator();
-    while (certs.hasMoreElements()) {
-      let cert = certs.getNext();
-      cert.QueryInterface(Ci.nsIX509Cert);
-      asciiCertChain.push(btoa(getDERString(cert)));
+
+    if (transportSecurityInfo.failedCertChain) {
+      let certs = transportSecurityInfo.failedCertChain.getEnumerator();
+      while (certs.hasMoreElements()) {
+        let cert = certs.getNext();
+        cert.QueryInterface(Ci.nsIX509Cert);
+        asciiCertChain.push(btoa(getDERString(cert)));
+      }
     }
 
     let report = {
       hostname: location.hostname,
       port: location.port,
       timestamp: Math.round(Date.now() / 1000),
       errorCode: transportSecurityInfo.errorCode,
       failedCertChain: asciiCertChain,
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -5,20 +5,20 @@ support-files =
   alltabslistener.html
   app_bug575561.html
   app_subframe_bug575561.html
   authenticate.sjs
   aboutHome_content_script.js
   browser_bug479408_sample.html
   browser_bug678392-1.html
   browser_bug678392-2.html
-  browser_bug846489_content.js
   browser_bug970746.xhtml
   browser_fxa_oauth.html
   browser_registerProtocolHandler_notification.html
+  browser_ssl_error_reports_content.js
   browser_star_hsts.sjs
   browser_tab_dragdrop2_frame1.xul
   browser_web_channel.html
   bug592338.html
   bug792517-2.html
   bug792517.html
   bug792517.sjs
   bug839103.css
@@ -148,17 +148,16 @@ skip-if = e10s
 [browser_bug413915.js]
 [browser_bug416661.js]
 skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug417483.js]
 skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug419612.js]
 skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug422590.js]
-[browser_bug846489.js]
 [browser_bug423833.js]
 skip-if = true # bug 428712
 [browser_bug424101.js]
 skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug427559.js]
 skip-if = e10s # Bug 1102015 - "content window is focused - Got [object ChromeWindow], expected [object CPOW [object Window]]"
 [browser_bug431826.js]
 [browser_bug432599.js]
@@ -394,16 +393,17 @@ skip-if = buildapp == 'mulet' || e10s # 
 [browser_searchHighlight.js]
 skip-if = true
 [browser_searchSuggestionUI.js]
 skip-if = e10s
 support-files =
   searchSuggestionUI.html
   searchSuggestionUI.js
 [browser_selectTabAtIndex.js]
+[browser_ssl_error_reports.js]
 [browser_star_hsts.js]
 [browser_subframe_favicons_not_used.js]
 [browser_tabDrop.js]
 skip-if = buildapp == 'mulet' || e10s
 [browser_tabMatchesInAwesomebar.js]
 skip-if = e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s (test calls gBrowser.swapBrowsersAndCloseOther)
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 skip-if = e10s || os == 'linux' # Bug 1093373, bug 1104755
rename from browser/base/content/test/general/browser_bug846489.js
rename to browser/base/content/test/general/browser_ssl_error_reports.js
--- a/browser/base/content/test/general/browser_bug846489.js
+++ b/browser/base/content/test/general/browser_ssl_error_reports.js
@@ -1,67 +1,69 @@
-var badPin = "https://include-subdomains.pinning.example.com";
-var enabledPref = false;
-var automaticPref = false;
-var urlPref = "security.ssl.errorReporting.url";
-var enforcement_level = 1;
+let badChainURL = "https://badchain.include-subdomains.pinning.example.com";
+let noCertURL = "https://fail-handshake.example.com";
+let enabledPref = false;
+let automaticPref = false;
+let urlPref = "security.ssl.errorReporting.url";
+let enforcement_level = 1;
 
 function loadFrameScript() {
   let mm = Cc["@mozilla.org/globalmessagemanager;1"]
            .getService(Ci.nsIMessageListenerManager);
   const ROOT = getRootDirectory(gTestPath);
-  mm.loadFrameScript(ROOT+"browser_bug846489_content.js", true);
+  mm.loadFrameScript(ROOT + "browser_ssl_error_reports_content.js", true);
 }
 
 add_task(function*(){
   waitForExplicitFinish();
   loadFrameScript();
   SimpleTest.requestCompleteLog();
   yield testSendReportDisabled();
-  yield testSendReportManual();
+  yield testSendReportManual(badChainURL, "succeed");
+  yield testSendReportManual(noCertURL, "nocert");
   yield testSendReportAuto();
   yield testSendReportError();
   yield testSetAutomatic();
 });
 
 // creates a promise of the message in an error page
 function createNetworkErrorMessagePromise(aBrowser) {
   return new Promise(function(resolve, reject) {
     // Error pages do not fire "load" events, so use a progressListener.
-    var originalDocumentURI = aBrowser.contentDocument.documentURI;
+    let originalDocumentURI = aBrowser.contentDocument.documentURI;
 
-    var progressListener = {
+    let progressListener = {
       onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
         // Make sure nothing other than an error page is loaded.
         if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) {
           reject("location change was not to an error page");
         }
       },
 
       onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
         let doc = aBrowser.contentDocument;
 
         if (doc.getElementById("reportCertificateError")) {
           // Wait until the documentURI changes (from about:blank) this should
           // be the error page URI.
-          var documentURI = doc.documentURI;
+          let documentURI = doc.documentURI;
           if (documentURI == originalDocumentURI) {
             return;
           }
 
           aWebProgress.removeProgressListener(progressListener,
             Ci.nsIWebProgress.NOTIFY_LOCATION |
             Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);
-          var matchArray = /about:neterror\?.*&d=([^&]*)/.exec(documentURI);
+          let matchArray = /about:neterror\?.*&d=([^&]*)/.exec(documentURI);
           if (!matchArray) {
             reject("no network error message found in URI")
           return;
           }
 
-          var errorMsg = matchArray[1];
+          let errorMsg = matchArray[1];
           resolve(decodeURIComponent(errorMsg));
         }
       },
 
       QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
                           Ci.nsISupportsWeakReference])
     };
 
@@ -69,17 +71,17 @@ function createNetworkErrorMessagePromis
             Ci.nsIWebProgress.NOTIFY_LOCATION |
             Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);
   });
 }
 
 // check we can set the 'automatically send' pref
 let testSetAutomatic = Task.async(function*() {
   setup();
-  let tab = gBrowser.addTab(badPin, {skipAnimation: true});
+  let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
   let browser = tab.linkedBrowser;
   let mm = browser.messageManager;
 
   gBrowser.selectedTab = tab;
 
   // ensure we have the correct error message from about:neterror
   let netError = createNetworkErrorMessagePromise(browser);
   yield netError;
@@ -114,32 +116,34 @@ let testSetAutomatic = Task.async(functi
 
   yield prefDisabled;
 
   gBrowser.removeTab(tab);
   cleanup();
 });
 
 // test that manual report sending (with button clicks) works
-let testSendReportManual = Task.async(function*() {
+let testSendReportManual = Task.async(function*(testURL, suffix) {
   setup();
   Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true);
-  Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?succeed");
+  Services.prefs.setCharPref("security.ssl.errorReporting.url",
+    "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?" + suffix);
 
-  let tab = gBrowser.addTab(badPin, {skipAnimation: true});
+  let tab = gBrowser.addTab(testURL, {skipAnimation: true});
   let browser = tab.linkedBrowser;
   let mm = browser.messageManager;
 
   gBrowser.selectedTab = tab;
 
   // ensure we have the correct error message from about:neterror
   let netError = createNetworkErrorMessagePromise(browser);
   yield netError;
   netError.then(function(val){
-    is(val.startsWith("An error occurred during a connection to include-subdomains.pinning.example.com"), true ,"ensure the correct error message came from about:neterror");
+    is(val.startsWith("An error occurred during a connection to"), true,
+                      "ensure the correct error message came from about:neterror");
   });
 
   // Check the report starts on click
   let btn = browser.contentDocument.getElementById("reportCertificateError");
 
   // check the content script sends the message to report
   let reportWillStart = new Promise(function(resolve, reject){
     mm.addMessageListener("Browser:SendSSLErrorReport", function() {
@@ -180,17 +184,17 @@ let testSendReportManual = Task.async(fu
 
 // test that automatic sending works
 let testSendReportAuto = Task.async(function*() {
   setup();
   Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true);
   Services.prefs.setBoolPref("security.ssl.errorReporting.automatic", true);
   Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?succeed");
 
-  let tab = gBrowser.addTab(badPin, {skipAnimation: true});
+  let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
   let browser = tab.linkedBrowser;
   let mm = browser.messageManager;
 
   gBrowser.selectedTab = tab;
 
   let reportWillStart = Promise.defer();
   mm.addMessageListener("Browser:SendSSLErrorReport", function() {
     reportWillStart.resolve();
@@ -229,17 +233,17 @@ let testSendReportAuto = Task.async(func
 
 // test that an error is shown if there's a problem with the report server
 let testSendReportError = Task.async(function*() {
   setup();
   Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true);
   Services.prefs.setBoolPref("security.ssl.errorReporting.automatic", true);
   Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?error");
 
-  let tab = gBrowser.addTab(badPin, {skipAnimation: true});
+  let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
   let browser = tab.linkedBrowser;
   let mm = browser.messageManager;
 
   gBrowser.selectedTab = tab;
 
   // check the report send starts....
   let reportWillStart = new Promise(function(resolve, reject){
     mm.addMessageListener("Browser:SendSSLErrorReport", function() {
@@ -250,56 +254,56 @@ let testSendReportError = Task.async(fun
   let netError = createNetworkErrorMessagePromise(browser);
   yield netError;
   yield reportWillStart;
 
   // and that errors are seen
   let reportErrors = new Promise(function(resolve, reject) {
     mm.addMessageListener("ssler-test:SSLErrorReportStatus", function(message) {
       switch(message.data.reportStatus) {
-      case "complete":
-        reject(message.data.reportStatus);
-        break;
-      case "error":
-        resolve(message.data.reportStatus);
-        break;
+        case "complete":
+          reject(message.data.reportStatus);
+          break;
+        case "error":
+          resolve(message.data.reportStatus);
+          break;
       }
     });
   });
 
   yield reportErrors;
 
   gBrowser.removeTab(tab);
   cleanup();
 });
 
 let testSendReportDisabled = Task.async(function*() {
   setup();
   Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", false);
   Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://offdomain.com");
 
-  let tab = gBrowser.addTab(badPin, {skipAnimation: true});
+  let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
   let browser = tab.linkedBrowser;
   let mm = browser.messageManager;
 
   gBrowser.selectedTab = tab;
 
   // Ensure we have an error page
   let netError = createNetworkErrorMessagePromise(browser);
   yield netError;
 
   let reportErrors = new Promise(function(resolve, reject) {
     mm.addMessageListener("ssler-test:SSLErrorReportStatus", function(message) {
       switch(message.data.reportStatus) {
-      case "complete":
-        reject(message.data.reportStatus);
-        break;
-      case "error":
-        resolve(message.data.reportStatus);
-        break;
+        case "complete":
+          reject(message.data.reportStatus);
+          break;
+        case "error":
+          resolve(message.data.reportStatus);
+          break;
       }
     });
   });
 
   // click the button
   mm.sendAsyncMessage("ssler-test:SendBtnClick",{forceUI:true});
 
   // check we get an error
rename from browser/base/content/test/general/browser_bug846489_content.js
rename to browser/base/content/test/general/browser_ssl_error_reports_content.js
--- a/browser/base/content/test/general/pinning_reports.sjs
+++ b/browser/base/content/test/general/pinning_reports.sjs
@@ -1,41 +1,69 @@
 const EXPECTED_CHAIN = [
   "MIIDCjCCAfKgAwIBAgIENUiGYDANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDExtBbHRlcm5hdGUgVHJ1c3RlZCBBdXRob3JpdHkwHhcNMTQxMDAxMjExNDE5WhcNMjQxMDAxMjExNDE5WjAxMS8wLQYDVQQDEyZpbmNsdWRlLXN1YmRvbWFpbnMucGlubmluZy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxYrge8C4eVfTb6/lJ4k/+/4J6wlnWpp5Szxy1MHhsLB+LJh/HRHqkO/tsigT204kTeU3dxuAfQHz0g+Td8dr6KICLLNVFUPw+XjhBV4AtxV8wcprs6EmdBhJgAjkFB4M76BL7/Ow0NfH012WNESn8TTbsp3isgkmrXjTZhWR33vIL1eDNimykp/Os/+JO+x9KVfdCtDCrPwO9Yusial5JiaW7qemRtVuUDL87NSJ7xokPEOSc9luv/fBamZ3rgqf3K6epqg+0o3nNCCcNFnfLW52G0t69+dIjr39WISHnqqZj3Sb7JPU6OmxTd13ByoLkoM3ZUQ2Lpas+RJvQyGXkCAwEAAaM1MDMwMQYDVR0RBCowKIImaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAAmzXfeoOS59FkNABRonFPRyFl7BoGpVJENUteFfTa2pdAhGYdo19Y4uILTTj+vtDAa5yryb5Uvd+YuJnExosbMMkzCrmZ9+VJCJdqUTb+idwk9/sgPl2gtGeRmefB0hXSUFHc/p1CDufSpYOmj9NCUZD2JEsybgJQNulkfAsVnS3lzDcxAwcO+RC/1uJDSiUtcBpWS4FW58liuDYE7PD67kLJHZPVUV2WCMuIl4VM2tKPtvShz1JkZ5UytOLs6jPfviNAk/ftXczaE2/RJgM2MnDX9nGzOxG6ONcVNCljL8avhFBCosutE6i5LYSZR6V14YY/xOn15WDSuWdnIsJCo=",
   "MIIC2jCCAcKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDExtBbHRlcm5hdGUgVHJ1c3RlZCBBdXRob3JpdHkwHhcNMTQwOTI1MjEyMTU0WhcNMjQwOTI1MjEyMTU0WjAmMSQwIgYDVQQDExtBbHRlcm5hdGUgVHJ1c3RlZCBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBT+BwAhO52IWgSIdZZifU9LHOs3IR/+8DCC0WP5d/OuyKlZ6Rqd0tsd3i7durhQyjHSbLf2lJStcnFjcVEbEnNI76RuvlN8xLLn5eV+2Ayr4cZYKztudwRmw+DV/iYAiMSy0hs7m3ssfX7qpoi1aNRjUanwU0VTCPQhF1bEKAC2du+C5Z8e92zN5t87w7bYr7lt+m8197XliXEu+0s9RgnGwGaZ296BIRz6NOoJYTa43n06LU1I1+Z4d6lPdzUFrSR0GBaMhUSurUBtOin3yWiMhg1VHX/KwqGc4als5GyCVXy8HGrA/0zQPOhetxrlhEVAdK/xBt7CZvByj1Rcc7AgMBAAGjEzARMA8GA1UdEwQIMAYBAf8CAQAwDQYJKoZIhvcNAQELBQADggEBAJq/hogSRqzPWTwX4wTn/DVSNdWwFLv53qep9YrSMJ8ZsfbfK9Es4VP4dBLRQAVMJ0Z5mW1I6d/n0KayTanuUBvemYdxPi/qQNSs8UJcllqdhqWzmzAg6a0LxrMnEeKzPBPD6q8PwQ7tYP+B4sBN9tnnsnyPgti9ZiNZn5FwXZliHXseQ7FE9/SqHlLw5LXW3YtKjuti6RmuV6fq3j+D4oeC5vb1mKgIyoTqGN6ze57v8RHi+pQ8Q+kmoUn/L3Z2YmFe4SKN/4WoyXr8TdejpThGOCGCAd3565s5gOx5QfSQX11P8NZKO8hcN0tme3VzmGpHK0Z/6MTmdpNaTwQ6odk="
   ];
 
-function handleRequest(request, response)
-{
-  if (request.queryString === "succeed") {
-    // read the report from the client
-    let inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
-    inputStream.init(request.bodyInputStream, 0x01, 0004, 0);
+function parseReport(request) {
+  // read the report from the request
+  let inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
+  inputStream.init(request.bodyInputStream, 0x01, 0004, 0);
+
+  let body = "";
+  if (inputStream) {
+    while (inputStream.available()) {
+      body = body + inputStream.read(inputStream.available());
+    }
+  }
+  // parse the report
+  return JSON.parse(body);
+}
+
+function handleRequest(request, response) {
+  let report = {};
+  let certChain = [];
 
-    let body = "";
-    if (inputStream) {
-      while (inputStream.available()) {
-        body = body + inputStream.read(inputStream.available());
+  switch (request.queryString) {
+    case "succeed":
+      report = parseReport(request);
+      certChain = report.failedCertChain;
+
+      // ensure the cert chain is what we expect
+      for (idx in certChain) {
+        if (certChain[idx] !== EXPECTED_CHAIN[idx]) {
+          // if the chain differs, send an error response to cause test
+          // failure
+          response.setStatusLine("1.1", 500, "Server error");
+          response.write("<html>The report contained an unexpected chain</html>");
+          return;
+        }
       }
-    }
-    // parse the report
-    let report = JSON.parse(body);
-    let certChain = report.failedCertChain;
 
-    // ensure the cert chain is what we expect
-    for (idx in certChain) {
-      if (certChain[idx] !== EXPECTED_CHAIN[idx]) {
-        // if the chain differs, send an error response to cause test
-        // failure
+      // if all is as expected, send the 201 the client expects
+      response.setStatusLine("1.1", 201, "Created");
+      response.write("<html>OK</html>");
+      break;
+    case "nocert":
+      report = parseReport(request);
+      certChain = report.failedCertChain;
+
+      if (certChain && certChain.length > 0) {
+        // We're not expecting a chain; if there is one, send an error
         response.setStatusLine("1.1", 500, "Server error");
         response.write("<html>The report contained an unexpected chain</html>");
         return;
       }
-    }
 
-    // if all is as expected, send the 201 the client expects
-    response.setStatusLine("1.1", 201, "Created");
-    response.write("<html>OK</html>");
-  } else if (request.queryString === "error") {
-    response.setStatusLine("1.1", 500, "Server error");
-    response.write("<html>server error</html>");
+      // if all is as expected, send the 201 the client expects
+      response.setStatusLine("1.1", 201, "Created");
+      response.write("<html>OK</html>");
+      break;
+    case "error":
+      response.setStatusLine("1.1", 500, "Server error");
+      response.write("<html>server error</html>");
+      break;
+    default:
+      response.setStatusLine("1.1", 500, "Server error");
+      response.write("<html>succeed, nocert or error expected</html>");
+      break;
   }
 }
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -890,23 +890,24 @@ bin/libfreebl_32int64_3.so
 @RESPATH@/components/DataStore.manifest
 @RESPATH@/components/DataStoreImpl.js
 @RESPATH@/components/dom_datastore.xpt
 
 ; Shutdown Terminator
 @RESPATH@/components/nsTerminatorTelemetry.js
 @RESPATH@/components/terminator.manifest
 
-#ifdef MOZ_ASAN
-#ifdef CLANG_CXX
+#if defined(CLANG_CXX)
+#if defined(MOZ_ASAN) || defined(MOZ_TSAN)
 @BINPATH@/llvm-symbolizer
 #endif
-#ifdef CLANG_CL
+#endif
+
+#if defined(MOZ_ASAN) && defined(CLANG_CL)
 @BINPATH@/clang_rt.asan_dynamic-i386.dll
 #endif
-#endif
 
 
 ; media
 #ifdef MOZ_EME
 @RESPATH@/gmp-clearkey/0.1/@DLL_PREFIX@clearkey@DLL_SUFFIX@
 @RESPATH@/gmp-clearkey/0.1/clearkey.info
 #endif
--- a/build/autoconf/winsdk.m4
+++ b/build/autoconf/winsdk.m4
@@ -1,37 +1,22 @@
 dnl This Source Code Form is subject to the terms of the Mozilla Public
 dnl License, v. 2.0. If a copy of the MPL was not distributed with this
 dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 dnl Identify which version of the SDK we're building with
 dnl Windows Server 2008 and newer SDKs have WinSDKVer.h, get the version
 dnl from there
 AC_DEFUN([MOZ_FIND_WINSDK_VERSION], [
-  MOZ_CHECK_HEADERS([winsdkver.h])
-  if test "$ac_cv_header_winsdkver_h" = "yes"; then
-      dnl Get the highest _WIN32_WINNT and NTDDI versions supported
-      dnl Take the higher of the two
-      dnl This is done because the Windows 7 beta SDK reports its
-      dnl NTDDI_MAXVER to be 0x06000100 instead of 0x06010000, as it should
-      AC_CACHE_CHECK(for highest Windows version supported by this SDK,
-                     ac_cv_winsdk_maxver,
-                     [cat > conftest.h <<EOF
+  AC_CACHE_CHECK(for highest Windows version supported by this SDK,
+                 ac_cv_winsdk_maxver,
+                 [cat > conftest.h <<EOF
 #include <winsdkver.h>
-#include <sdkddkver.h>
 
-#if (NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT_MAXVER) > NTDDI_MAXVER)
-#define WINSDK_MAXVER NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT_MAXVER)
-#else
-#define WINSDK_MAXVER NTDDI_MAXVER
-#endif
-
-WINSDK_MAXVER
+WINVER_MAXVER
 EOF
                       ac_cv_winsdk_maxver=`$CPP conftest.h 2>/dev/null | tail -n1`
                       rm -f conftest.h
                      ])
-      MOZ_WINSDK_MAXVER=${ac_cv_winsdk_maxver}
-  else
-      dnl Any SDK which doesn't have WinSDKVer.h is too old.
-      AC_MSG_ERROR([Your SDK does not have WinSDKVer.h. It is probably too old. Please upgrade to a newer SDK or try running the Windows SDK Configuration Tool and selecting a newer SDK. See https://developer.mozilla.org/En/Windows_SDK_versions for more details on fixing this.])
-  fi
+      dnl WinSDKVer.h returns the version number in 4-digit format while many
+      dnl consumers expect 8. Therefore, pad the result with an extra 4 zeroes.
+      MOZ_WINSDK_MAXVER=${ac_cv_winsdk_maxver}0000
 ])
--- a/build/pgo/server-locations.txt
+++ b/build/pgo/server-locations.txt
@@ -15,28 +15,32 @@
 # and a comma-separated list of options (if indeed any options are needed).
 #
 # The format of an origin is, referring to RFC 2396, a scheme (either "http" or
 # "https"), followed by "://", followed by a host, followed by ":", followed by
 # a port number.  The colon and port number must be present even if the port
 # number is the default for the protocol.
 #
 # Unrecognized options are ignored.  Recognized options are "primary" and
-# "privileged", "nocert", "cert=some_cert_nickname", "redir=hostname".
+# "privileged", "nocert", "cert=some_cert_nickname", "redir=hostname" and
+# "failHandshake".
 #
 # "primary" denotes a location which is the canonical location of
 # the server; this location is the one assumed for requests which don't
 # otherwise identify a particular origin (e.g. HTTP/1.0 requests).  
 #
 # "privileged" denotes a location which should have the ability to request 
 # elevated privileges; the default is no privileges.
 #
 # "nocert" makes sense only for https:// hosts and means there is not
 # any certificate automatically generated for this host.
 #
+# "failHandshake" causes the tls handshake to fail (by sending a client hello to
+# the client).
+#
 # "cert=nickname" tells the pgo server to use a particular certificate
 # for this host. The certificate is referenced by its nickname that must
 # not contain any spaces. The certificate  key files (PKCS12 modules)
 # for custom certification are loaded from build/pgo/certs
 # directory. When new certificate is added to this dir pgo/ssltunnel
 # must be built then. This is only necessary for cases where we really do
 # want specific certs.
 #
@@ -222,17 +226,18 @@ https://marketplace.firefox.com:443     
 https://marketplace-dev.allizom.org:443   privileged
 https://marketplace.allizom.org:443       privileged
 
 # Host for HPKP
 https://include-subdomains.pinning-dynamic.example.com:443        privileged,cert=dynamicPinningGood
 https://bad.include-subdomains.pinning-dynamic.example.com:443    privileged,cert=dynamicPinningBad
 
 # Host for static pin tests
-https://include-subdomains.pinning.example.com:443                privileged,cert=staticPinningBad
+https://badchain.include-subdomains.pinning.example.com:443       privileged,cert=staticPinningBad
+https://fail-handshake.example.com:443                            privileged,failHandshake
 
 # Hosts for sha1 console warning tests
 https://sha1ee.example.com:443                                    privileged,cert=sha1_end_entity
 https://sha256ee.example.com:443                                  privileged,cert=sha256_end_entity
 
 # Hosts for ssl3/rc4 console warning tests
 https://ssl3.example.com:443        privileged,ssl3
 https://rc4.example.com:443         privileged,rc4
--- a/configure.in
+++ b/configure.in
@@ -410,40 +410,37 @@ dnl Special win32 checks
 dnl ========================================================
 
 MOZ_ARG_ENABLE_BOOL(metro,
 [  --enable-metro           Enable Windows Metro build targets],
     MOZ_METRO=1,
     MOZ_METRO=)
 if test -n "$MOZ_METRO"; then
     AC_DEFINE(MOZ_METRO)
-    # Target the Windows 8 Kit
-    WINSDK_TARGETVER=602
-    WINVER=502
     # toolkit/library/makefile.in needs these, see nsDllMain.
     CRTDLLVERSION=110
     CRTEXPDLLVERSION=1-1-0
-else
-    # Target the Windows 7 SDK by default
-    WINSDK_TARGETVER=601
-    WINVER=502
 fi
 
 AC_SUBST(CRTDLLVERSION)
 AC_SUBST(CRTEXPDLLVERSION)
 
+# Target the Windows 8.1 SDK by default
+WINSDK_TARGETVER=603
+WINVER=502
+
 MOZ_ARG_WITH_STRING(windows-version,
 [  --with-windows-version=WINSDK_TARGETVER
-                          Windows SDK version to target. Lowest version
-                          currently allowed is 601 (Win7), highest is 602 (Win8)],
+                          Windows SDK version to target. Win8.1 (603) is
+                          currently the minimum supported version.],
   WINSDK_TARGETVER=$withval)
 
-# Currently only two sdk versions allowed, 601 and 602
+# Currently only version 603 is allowed
 case "$WINSDK_TARGETVER" in
-601|602)
+603)
     MOZ_WINSDK_TARGETVER=0${WINSDK_TARGETVER}0000
     ;;
 
 *)
     AC_MSG_ERROR([Invalid value for --with-windows-version ($WINSDK_TARGETVER)]);
     ;;
 esac
 
@@ -680,17 +677,17 @@ case "$target" in
                 ;;
             esac
         fi
 
         # strsafe.h on mingw uses macros for function deprecation that pollutes namespace
         # causing problems with local implementations with the same name.
         AC_DEFINE(STRSAFE_NO_DEPRECATE)
 
-        MOZ_WINSDK_MAXVER=0x06020000
+        MOZ_WINSDK_MAXVER=0x06030000
     fi # !GNU_CC
 
     AC_DEFINE_UNQUOTED(WINVER,0x$WINVER)
     AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x$WINVER)
     # Require OS features provided by IE 6.0 SP2 (XP SP2)
     AC_DEFINE_UNQUOTED(_WIN32_IE,0x0603)
 
     # If the maximum version supported by this SDK is lower than the target
@@ -5875,20 +5872,16 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
 
   # Find a D3D compiler DLL in a Windows SDK.
   MOZ_D3DCOMPILER_VISTA_DLL=
   case "$MOZ_WINSDK_MAXVER" in
   0x0603*)
     MOZ_D3DCOMPILER_VISTA_DLL=d3dcompiler_47.dll
     AC_MSG_RESULT([Found D3D compiler in Windows SDK 8.1.])
   ;;
-  0x0602*)
-    MOZ_D3DCOMPILER_VISTA_DLL=d3dcompiler_46.dll
-    AC_MSG_RESULT([Found D3D compiler in Windows SDK 8.0.])
-  ;;
   esac
 
   if test -n "$MOZ_D3DCOMPILER_VISTA_DLL"; then
     # We have a name, now track down the path.
     if test -n "$WINDOWSSDKDIR"; then
       MOZ_D3DCOMPILER_VISTA_DLL_PATH="$WINDOWSSDKDIR/Redist/D3D/$MOZ_D3D_CPU_SUFFIX/$MOZ_D3DCOMPILER_VISTA_DLL"
       if test -f "$MOZ_D3DCOMPILER_VISTA_DLL_PATH"; then
         AC_MSG_RESULT([Found MOZ_D3DCOMPILER_VISTA_DLL_PATH: $MOZ_D3DCOMPILER_VISTA_DLL_PATH])
@@ -6027,25 +6020,16 @@ MOZ_ARG_DISABLE_BOOL(gamepad,
     MOZ_GAMEPAD=1)
 
 if test "$MOZ_GAMEPAD"; then
     case "$OS_TARGET" in
     Darwin)
         MOZ_GAMEPAD_BACKEND=cocoa
         ;;
     WINNT)
-        case "$MOZ_WINSDK_MAXVER" in
-        # We support building with the Windows 7 SDK otherwise, but
-        # Gamepad support requires the Windows 8 SDK for some HID headers.
-        0x0601*)
-          AC_MSG_ERROR([The Windows 8 SDK or newer is required to build Gamepad support. Please install a newer Windows SDK or reconfigure with --disable-gamepad to disable gamepad support.])
-          ;;
-        *)
-          ;;
-        esac
         MOZ_GAMEPAD_BACKEND=windows
         ;;
     Linux)
         MOZ_CHECK_HEADER([linux/joystick.h])
         if test "$ac_cv_header_linux_joystick_h" != "yes"; then
           AC_MSG_ERROR([Can't find header linux/joystick.h, needed for gamepad support. Please install Linux kernel headers or reconfigure with --disable-gamepad to disable gamepad support.])
         fi
         MOZ_GAMEPAD_BACKEND=linux
@@ -7972,23 +7956,16 @@ if test -z "${GLIB_GMODULE_LIBS}" \
 fi
 
 AC_SUBST_LIST(GLIB_GMODULE_LIBS)
 
 dnl ========================================================
 dnl Graphics checks.
 dnl ========================================================
 
-if test "${OS_TARGET}" = "WINNT"; then
-  if $PERL -e "exit($MOZ_WINSDK_MAXVER < 0x06020000)"; then
-    MOZ_ENABLE_DIRECT2D1_1=1
-    AC_SUBST(MOZ_ENABLE_DIRECT2D1_1)
-  fi
-fi
-
 if test "${OS_TARGET}" = "WINNT" -o \
         "${OS_ARCH}" = "Darwin" -o \
         "${MOZ_WIDGET_TOOLKIT}" = "android" -o \
         "${MOZ_WIDGET_TOOLKIT}" = "gonk" -o \
         "${MOZ_WIDGET_TOOLKIT}" = "gtk2" -o \
         "${MOZ_WIDGET_TOOLKIT}" = "gtk3"; then
     case "${target_cpu}" in
     i*86*|x86_64|arm)
@@ -8153,27 +8130,22 @@ if test "$MOZ_TREE_CAIRO"; then
         QT_SURFACE_FEATURE="#define CAIRO_HAS_QT_SURFACE 1"
         ;;
       cocoa | uikit)
         QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
         QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
         QUARTZ_FONT_FEATURE="#define CAIRO_HAS_QUARTZ_FONT 1"
         ;;
       windows)
-        WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
+        WIN32_D2D_SURFACE_FEATURE="#define CAIRO_HAS_D2D_SURFACE 1"
+        WIN32_DWRITE_FONT_FEATURE="#define CAIRO_HAS_DWRITE_FONT 1"
         WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
-        if test "$MOZ_WINSDK_TARGETVER" -ge "06010000"; then
-            WIN32_DWRITE_FONT_FEATURE="#define CAIRO_HAS_DWRITE_FONT 1"
-            WIN32_D2D_SURFACE_FEATURE="#define CAIRO_HAS_D2D_SURFACE 1"
-            MOZ_ENABLE_D2D_SURFACE=1
-            MOZ_ENABLE_DWRITE_FONT=1
-        else
-            WIN32_DWRITE_FONT_FEATURE=
-            WIN32_D2D_SURFACE_FEATURE=
-        fi
+        WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
+        MOZ_ENABLE_D2D_SURFACE=1
+        MOZ_ENABLE_DWRITE_FONT=1
 
         MOZ_CHECK_HEADER(d3d9.h, MOZ_ENABLE_D3D9_LAYER=1)
 
         dnl D3D10 Layers depend on D2D Surfaces.
         if test -n "$WIN32_D2D_SURFACE_FEATURE"; then
           MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
         fi
         ;;
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -506,16 +506,37 @@ nsDOMWindowUtils::SetResolution(float aX
     sf->SetResolution(gfxSize(aXResolution, aYResolution));
     presShell->SetResolution(aXResolution, aYResolution);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::SetResolutionAndScaleTo(float aXResolution, float aYResolution)
+{
+  if (!nsContentUtils::IsCallerChrome()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  nsIPresShell* presShell = GetPresShell();
+  if (!presShell) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
+  if (sf) {
+    sf->SetResolutionAndScaleTo(gfxSize(aXResolution, aYResolution));
+    presShell->SetResolutionAndScaleTo(aXResolution, aYResolution);
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/canvas/CanvasImageCache.cpp
+++ b/dom/canvas/CanvasImageCache.cpp
@@ -157,17 +157,17 @@ public:
   void Destroy()
   {
     UnregisterMemoryPressureEvent();
     mImageCache = nullptr;
   }
 
   NS_IMETHODIMP Observe(nsISupports* aSubject,
                         const char* aTopic,
-                        const char16_t* aSomeData)
+                        const char16_t* aSomeData) MOZ_OVERRIDE
   {
     if (!mImageCache || strcmp(aTopic, "memory-pressure")) {
       return NS_OK;
     }
 
     mImageCache->AgeAllGenerations();
     return NS_OK;
   }
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -159,17 +159,17 @@ static int64_t gCanvasAzureMemoryUsed = 
 // underlying surface implementations.  See bug 655638 for details.
 class Canvas2dPixelsReporter MOZ_FINAL : public nsIMemoryReporter
 {
   ~Canvas2dPixelsReporter() {}
 public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
-                            nsISupports* aData, bool aAnonymize)
+                            nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE
   {
     return MOZ_COLLECT_REPORT(
       "canvas-2d-pixels", KIND_OTHER, UNITS_BYTES,
       gCanvasAzureMemoryUsed,
       "Memory used by 2D canvases. Each canvas requires "
       "(width * height * 4) bytes.");
   }
 };
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -579,25 +579,25 @@ public:
       mDSPathBuilder->BezierTo(transform * aCP1,
                                 transform * aCP2,
                                 transform * aCP3);
     }
   }
 
   friend class CanvasRenderingContext2DUserData;
 
-  virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
+  virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) MOZ_OVERRIDE;
 
 
   // Given a point, return hit region ID if it exists
-  nsString GetHitRegion(const mozilla::gfx::Point& aPoint);
+  nsString GetHitRegion(const mozilla::gfx::Point& aPoint) MOZ_OVERRIDE;
 
 
   // return true and fills in the bound rect if element has a hit region.
-  bool GetHitRegionRect(Element* aElement, nsRect& aRect);
+  bool GetHitRegionRect(Element* aElement, nsRect& aRect) MOZ_OVERRIDE;
 
 protected:
   nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
                              uint32_t aWidth, uint32_t aHeight,
                              JSObject** aRetval);
 
   nsresult PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
                                  dom::Uint8ClampedArray* aArray,
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -187,17 +187,17 @@ public:
 
     MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLContext)
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
                                                            nsIDOMWebGLRenderingContext)
 
-    virtual JSObject* WrapObject(JSContext* cx) = 0;
+    virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE = 0;
 
     NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
 
     // nsICanvasRenderingContextInternal
 #ifdef DEBUG
     virtual int32_t GetWidth() const MOZ_OVERRIDE;
     virtual int32_t GetHeight() const MOZ_OVERRIDE;
 #endif
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -266,17 +266,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(DOMEventTa
     return _to GetJSContextForEventHandlers(); \
   }
 
 #define NS_REALLY_FORWARD_NSIDOMEVENTTARGET(_class) \
   using _class::AddEventListener;                   \
   using _class::RemoveEventListener;                \
   NS_FORWARD_NSIDOMEVENTTARGET(_class::)            \
   virtual mozilla::EventListenerManager*            \
-  GetOrCreateListenerManager() {                    \
+  GetOrCreateListenerManager() MOZ_OVERRIDE {       \
     return _class::GetOrCreateListenerManager();    \
   }                                                 \
   virtual mozilla::EventListenerManager*            \
-  GetExistingListenerManager() const {              \
+  GetExistingListenerManager() const MOZ_OVERRIDE { \
     return _class::GetExistingListenerManager();    \
   }
 
 #endif // mozilla_DOMEventTargetHelper_h_
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -99,17 +99,17 @@ public:
   // latter will occur when an external drag occurs, that is, a drag where the
   // source is another application, or a drag is started by calling the drag
   // service directly. For clipboard operations, aClipboardType indicates
   // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations,
   // or if access to the system clipboard should not be allowed.
   DataTransfer(nsISupports* aParent, uint32_t aEventType, bool aIsExternal,
                int32_t aClipboardType);
 
-  virtual JSObject* WrapObject(JSContext* aCx);
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void SetParentObject(nsISupports* aNewParent)
   {
     MOZ_ASSERT(aNewParent);
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -287,38 +287,38 @@ private:
 
 } // namespace dom
 } // namespace mozilla
 
 #define NS_FORWARD_TO_EVENT \
   NS_FORWARD_NSIDOMEVENT(Event::)
 
 #define NS_FORWARD_NSIDOMEVENT_NO_SERIALIZATION_NO_DUPLICATION(_to) \
-  NS_IMETHOD GetType(nsAString& aType){ return _to GetType(aType); } \
-  NS_IMETHOD GetTarget(nsIDOMEventTarget * *aTarget) { return _to GetTarget(aTarget); } \
-  NS_IMETHOD GetCurrentTarget(nsIDOMEventTarget * *aCurrentTarget) { return _to GetCurrentTarget(aCurrentTarget); } \
-  NS_IMETHOD GetEventPhase(uint16_t *aEventPhase) { return _to GetEventPhase(aEventPhase); } \
-  NS_IMETHOD GetBubbles(bool *aBubbles) { return _to GetBubbles(aBubbles); } \
-  NS_IMETHOD GetCancelable(bool *aCancelable) { return _to GetCancelable(aCancelable); } \
-  NS_IMETHOD GetTimeStamp(DOMTimeStamp *aTimeStamp) { return _to GetTimeStamp(aTimeStamp); } \
-  NS_IMETHOD StopPropagation(void) { return _to StopPropagation(); } \
-  NS_IMETHOD PreventDefault(void) { return _to PreventDefault(); } \
-  NS_IMETHOD InitEvent(const nsAString & eventTypeArg, bool canBubbleArg, bool cancelableArg) { return _to InitEvent(eventTypeArg, canBubbleArg, cancelableArg); } \
-  NS_IMETHOD GetDefaultPrevented(bool *aDefaultPrevented) { return _to GetDefaultPrevented(aDefaultPrevented); } \
-  NS_IMETHOD StopImmediatePropagation(void) { return _to StopImmediatePropagation(); } \
-  NS_IMETHOD GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget) { return _to GetOriginalTarget(aOriginalTarget); } \
-  NS_IMETHOD GetExplicitOriginalTarget(nsIDOMEventTarget** aExplicitOriginalTarget) { return _to GetExplicitOriginalTarget(aExplicitOriginalTarget); } \
-  NS_IMETHOD GetPreventDefault(bool* aRetval) { return _to GetPreventDefault(aRetval); } \
-  NS_IMETHOD GetIsTrusted(bool* aIsTrusted) { return _to GetIsTrusted(aIsTrusted); } \
-  NS_IMETHOD SetTarget(nsIDOMEventTarget *aTarget) { return _to SetTarget(aTarget); } \
-  NS_IMETHOD_(bool) IsDispatchStopped(void) { return _to IsDispatchStopped(); } \
-  NS_IMETHOD_(WidgetEvent*) GetInternalNSEvent(void) { return _to GetInternalNSEvent(); } \
-  NS_IMETHOD_(void) SetTrusted(bool aTrusted) { _to SetTrusted(aTrusted); } \
-  NS_IMETHOD_(void) SetOwner(EventTarget* aOwner) { _to SetOwner(aOwner); } \
-  NS_IMETHOD_(Event*) InternalDOMEvent() { return _to InternalDOMEvent(); }
+  NS_IMETHOD GetType(nsAString& aType) MOZ_OVERRIDE { return _to GetType(aType); } \
+  NS_IMETHOD GetTarget(nsIDOMEventTarget** aTarget) MOZ_OVERRIDE { return _to GetTarget(aTarget); } \
+  NS_IMETHOD GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget) MOZ_OVERRIDE { return _to GetCurrentTarget(aCurrentTarget); } \
+  NS_IMETHOD GetEventPhase(uint16_t* aEventPhase) MOZ_OVERRIDE { return _to GetEventPhase(aEventPhase); } \
+  NS_IMETHOD GetBubbles(bool* aBubbles) MOZ_OVERRIDE { return _to GetBubbles(aBubbles); } \
+  NS_IMETHOD GetCancelable(bool* aCancelable) MOZ_OVERRIDE { return _to GetCancelable(aCancelable); } \
+  NS_IMETHOD GetTimeStamp(DOMTimeStamp* aTimeStamp) MOZ_OVERRIDE { return _to GetTimeStamp(aTimeStamp); } \
+  NS_IMETHOD StopPropagation(void) MOZ_OVERRIDE { return _to StopPropagation(); } \
+  NS_IMETHOD PreventDefault(void) MOZ_OVERRIDE { return _to PreventDefault(); } \
+  NS_IMETHOD InitEvent(const nsAString& eventTypeArg, bool canBubbleArg, bool cancelableArg) MOZ_OVERRIDE { return _to InitEvent(eventTypeArg, canBubbleArg, cancelableArg); } \
+  NS_IMETHOD GetDefaultPrevented(bool* aDefaultPrevented) MOZ_OVERRIDE { return _to GetDefaultPrevented(aDefaultPrevented); } \
+  NS_IMETHOD StopImmediatePropagation(void) MOZ_OVERRIDE { return _to StopImmediatePropagation(); } \
+  NS_IMETHOD GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget) MOZ_OVERRIDE { return _to GetOriginalTarget(aOriginalTarget); } \
+  NS_IMETHOD GetExplicitOriginalTarget(nsIDOMEventTarget** aExplicitOriginalTarget) MOZ_OVERRIDE { return _to GetExplicitOriginalTarget(aExplicitOriginalTarget); } \
+  NS_IMETHOD GetPreventDefault(bool* aRetval) MOZ_OVERRIDE { return _to GetPreventDefault(aRetval); } \
+  NS_IMETHOD GetIsTrusted(bool* aIsTrusted) MOZ_OVERRIDE { return _to GetIsTrusted(aIsTrusted); } \
+  NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget) MOZ_OVERRIDE { return _to SetTarget(aTarget); } \
+  NS_IMETHOD_(bool) IsDispatchStopped(void) MOZ_OVERRIDE { return _to IsDispatchStopped(); } \
+  NS_IMETHOD_(WidgetEvent*) GetInternalNSEvent(void) MOZ_OVERRIDE { return _to GetInternalNSEvent(); } \
+  NS_IMETHOD_(void) SetTrusted(bool aTrusted) MOZ_OVERRIDE { _to SetTrusted(aTrusted); } \
+  NS_IMETHOD_(void) SetOwner(EventTarget* aOwner) MOZ_OVERRIDE { _to SetOwner(aOwner); } \
+  NS_IMETHOD_(Event*) InternalDOMEvent() MOZ_OVERRIDE { return _to InternalDOMEvent(); }
 
 #define NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION \
   NS_FORWARD_NSIDOMEVENT_NO_SERIALIZATION_NO_DUPLICATION(Event::)
 
 inline nsISupports*
 ToSupports(mozilla::dom::Event* e)
 {
   return static_cast<nsIDOMEvent*>(e);
--- a/dom/events/ScrollAreaEvent.h
+++ b/dom/events/ScrollAreaEvent.h
@@ -26,17 +26,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMSCROLLAREAEVENT
 
   NS_FORWARD_NSIDOMUIEVENT(UIEvent::)
 
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
-  NS_IMETHOD DuplicatePrivateData()
+  NS_IMETHOD DuplicatePrivateData() MOZ_OVERRIDE
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) MOZ_OVERRIDE;
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
   {
--- a/dom/events/UIEvent.h
+++ b/dom/events/UIEvent.h
@@ -172,24 +172,25 @@ protected:
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #define NS_FORWARD_TO_UIEVENT                               \
   NS_FORWARD_NSIDOMUIEVENT(UIEvent::)                       \
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION       \
-  NS_IMETHOD DuplicatePrivateData()                         \
+  NS_IMETHOD DuplicatePrivateData() MOZ_OVERRIDE            \
   {                                                         \
     return UIEvent::DuplicatePrivateData();                 \
   }                                                         \
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg,           \
                               bool aSerializeInterfaceType) \
+    MOZ_OVERRIDE                                            \
   {                                                         \
     UIEvent::Serialize(aMsg, aSerializeInterfaceType);      \
   }                                                         \
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg,   \
-                                void** aIter)               \
+                                void** aIter) MOZ_OVERRIDE  \
   {                                                         \
     return UIEvent::Deserialize(aMsg, aIter);               \
   }
 
 #endif // mozilla_dom_UIEvent_h_
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -46,17 +46,17 @@ interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 interface nsITranslationNodeList;
 interface nsIJSRAIIHelper;
 interface nsIContentPermissionRequest;
 
-[scriptable, uuid(9621eb05-b498-4e87-a012-95d817987624)]
+[scriptable, uuid(4922a706-a17e-48e0-ab6f-9fe1bbe4e5f7)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -194,42 +194,47 @@ interface nsIDOMWindowUtils : nsISupport
   void setDisplayPortBaseForElement(in int32_t aX,
                                     in int32_t aY,
                                     in int32_t aWidth,
                                     in int32_t aHeight,
                                     in nsIDOMElement aElement);
 
   /**
    * Get/set the resolution at which rescalable web content is drawn.
-   * Currently this is only (some) thebes content.
    *
    * Setting a new resolution does *not* trigger reflow.  This API is
    * entirely separate from textZoom and fullZoom; a resolution scale
    * can be applied together with both textZoom and fullZoom.
    *
-   * The effect of is API for gfx code to allocate more or fewer
+   * The effect of this API is for gfx code to allocate more or fewer
    * pixels for rescalable content by a factor of |resolution| in
-   * either or both dimensions.  setResolution() together with
-   * setDisplayport() can be used to implement a non-reflowing
-   * scale-zoom in concert with another entity that can draw with a
-   * scale.  For example, to scale a content |window| inside a
-   * <browser> by a factor of 2.0
-   *
-   *   window.setDisplayport(x, y, oldW / 2.0, oldH / 2.0);
-   *   window.setResolution(2.0, 2.0);
-   *   // elsewhere
-   *   browser.setViewportScale(2.0, 2.0);
+   * either or both dimensions.  The scale at which the content is
+   * displayed does not change; if that is desired, use
+   * setResolutionAndScaleTo() instead.
    *
    * The caller of this method must have chrome privileges.
    */
   void setResolution(in float aXResolution, in float aYResolution);
 
   void getResolution(out float aXResolution, out float aYResolution);
 
   /**
+   * Similar to setResolution(), but also scales the content by the
+   * amount of the resolution, so that it is displayed at a
+   * correspondingly larger or smaller size, without the need for
+   * the caller to set an additional transform.
+   *
+   * This can be used to implement a non-reflowing scale-zoom, e.g.
+   * for pinch-zoom on mobile platforms.
+   *
+   * The caller of this method must have chrome privileges.
+   */
+  void setResolutionAndScaleTo(in float aXResolution, in float aYResolution);
+
+  /**
    * Whether the resolution has been set by the user.
    * This gives a way to check whether the provided resolution is the default
    * value or restored from a previous session.
    *
    * Can only be accessed with chrome privileges.
    */
   readonly attribute boolean isResolutionSet;
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -430,17 +430,17 @@ TabChildBase::HandlePossibleViewportChan
   }
 
   metrics.SetCumulativeResolution(metrics.GetZoom()
                                 / metrics.GetDevPixelsPerCSSPixel()
                                 * ParentLayerToLayerScale(1));
   // This is the root layer, so the cumulative resolution is the same
   // as the resolution.
   metrics.mPresShellResolution = metrics.GetCumulativeResolution().scale;
-  utils->SetResolution(metrics.mPresShellResolution, metrics.mPresShellResolution);
+  utils->SetResolutionAndScaleTo(metrics.mPresShellResolution, metrics.mPresShellResolution);
 
   CSSSize scrollPort = metrics.CalculateCompositedSizeInCssPixels();
   utils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
 
   // The call to GetPageSize forces a resize event to content, so we need to
   // make sure that we have the right CSS viewport and
   // scrollPositionClampingScrollPortSize set up before that happens.
 
--- a/dom/media/fmp4/android/AndroidDecoderModule.cpp
+++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp
@@ -133,17 +133,17 @@ public:
     }
 
     nsRefPtr<layers::Image> img = mImageContainer->CreateImage(ImageFormat::EGLIMAGE);
     layers::EGLImageImage::Data data;
     data.mImage = eglImage;
     data.mSync = eglSync;
     data.mOwns = true;
     data.mSize = gfx::IntSize(mConfig.display_width, mConfig.display_height);
-    data.mOriginPos = gl::OriginPos::TopLeft;
+    data.mOriginPos = gl::OriginPos::BottomLeft;
 
     layers::EGLImageImage* typedImg = static_cast<layers::EGLImageImage*>(img.get());
     typedImg->SetData(data);
 
     bool isSync = !!(MediaCodec::getBUFFER_FLAG_SYNC_FRAME() & aInfo->getFlags());
 
     nsRefPtr<VideoData> v = VideoData::CreateFromImage(videoInfo, mImageContainer, aInfo->getOffset(),
                                                        aInfo->getPresentationTimeUs(),
--- a/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
+++ b/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp
@@ -6,17 +6,17 @@
 #include "mp4_demuxer/mp4_demuxer.h"
 #include "GonkMediaDataDecoder.h"
 #include "VideoUtils.h"
 #include "nsTArray.h"
 #include "MediaCodecProxy.h"
 
 #include "prlog.h"
 #include <android/log.h>
-#define GMDD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkMediaDataDecoder(blake)", __VA_ARGS__)
+#define GMDD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkMediaDataDecoder", __VA_ARGS__)
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetDemuxerLog();
 #define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define LOG(...)
 #endif
 
@@ -84,18 +84,19 @@ GonkMediaDataDecoder::ProcessDecode(mp4_
   }
   ProcessOutput();
 }
 
 void
 GonkMediaDataDecoder::ProcessOutput()
 {
   nsRefPtr<MediaData> output;
-  nsresult rv;
-  while (true && !mDrainComplete) {
+  nsresult rv = NS_ERROR_ABORT;
+
+  while (!mDrainComplete) {
     rv = mManager->Output(mLastStreamOffset, output);
     if (rv == NS_OK) {
       mCallback->Output(output);
       continue;
     } else if (rv == NS_ERROR_NOT_AVAILABLE && mSignaledEOS) {
       // Try to get more frames before getting EOS frame
       continue;
     }
@@ -116,16 +117,17 @@ GonkMediaDataDecoder::ProcessOutput()
       if (output) {
         mCallback->Output(output);
       }
       mCallback->DrainComplete();
       mSignaledEOS = false;
       mDrainComplete = true;
       return;
     }
+    GMDD_LOG("Callback error!");
     mCallback->Error();
   }
 }
 
 nsresult
 GonkMediaDataDecoder::Flush()
 {
   // Flush the input task queue. This cancels all pending Decode() calls.
--- a/dom/plugins/base/PluginPRLibrary.h
+++ b/dom/plugins/base/PluginPRLibrary.h
@@ -40,19 +40,19 @@ public:
         // addref here??
     }
 
     virtual ~PluginPRLibrary()
     {
         // unref here??
     }
 
-    virtual void SetPlugin(nsNPAPIPlugin*) { }
+    virtual void SetPlugin(nsNPAPIPlugin*) MOZ_OVERRIDE { }
 
-    virtual bool HasRequiredFunctions() {
+    virtual bool HasRequiredFunctions() MOZ_OVERRIDE {
         mNP_Initialize = (NP_InitializeFunc)
             PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
         if (!mNP_Initialize)
             return false;
 
         mNP_Shutdown = (NP_ShutdownFunc)
             PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
         if (!mNP_Shutdown)
@@ -77,49 +77,49 @@ public:
             PR_FindFunctionSymbol(mLibrary, "NP_GetEntryPoints");
         if (!mNP_GetEntryPoints)
             return false;
 #endif
         return true;
     }
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
-    virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs,
-                                   NPPluginFuncs* pFuncs, NPError* error);
+    virtual nsresult NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs,
+                                   NPPluginFuncs* aFuncs, NPError* aError) MOZ_OVERRIDE;
 #else
-    virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs,
-                                   NPError* error);
+    virtual nsresult NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs,
+                                   NPError* aError) MOZ_OVERRIDE;
 #endif
 
-    virtual nsresult NP_Shutdown(NPError* error);
-    virtual nsresult NP_GetMIMEDescription(const char** mimeDesc);
+    virtual nsresult NP_Shutdown(NPError* aError) MOZ_OVERRIDE;
+    virtual nsresult NP_GetMIMEDescription(const char** aMimeDesc) MOZ_OVERRIDE;
 
-    virtual nsresult NP_GetValue(void *future, NPPVariable aVariable,
-                                 void *aValue, NPError* error);
+    virtual nsresult NP_GetValue(void* aFuture, NPPVariable aVariable,
+                                 void* aValue, NPError* aError) MOZ_OVERRIDE;
 
 #if defined(XP_WIN) || defined(XP_MACOSX)
-    virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error);
+    virtual nsresult NP_GetEntryPoints(NPPluginFuncs* aFuncs, NPError* aError) MOZ_OVERRIDE;
 #endif
 
-    virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
-                             uint16_t mode, int16_t argc, char* argn[],
-                             char* argv[], NPSavedData* saved,
-                             NPError* error);
+    virtual nsresult NPP_New(NPMIMEType aPluginType, NPP aInstance,
+                             uint16_t aMode, int16_t aArgc, char* aArgn[],
+                             char* aArgv[], NPSavedData* aSaved,
+                             NPError* aError) MOZ_OVERRIDE;
 
-    virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags,
-                                       uint64_t maxAge);
-    virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result);
+    virtual nsresult NPP_ClearSiteData(const char* aSite, uint64_t aFlags,
+                                       uint64_t aMaxAge) MOZ_OVERRIDE;
+    virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& aResult) MOZ_OVERRIDE;
 
-    virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
-    virtual nsresult GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer);
-    virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize);
+    virtual nsresult AsyncSetWindow(NPP aInstance, NPWindow* aWindow) MOZ_OVERRIDE;
+    virtual nsresult GetImageContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) MOZ_OVERRIDE;
+    virtual nsresult GetImageSize(NPP aInstance, nsIntSize* aSize) MOZ_OVERRIDE;
     virtual bool IsOOP() MOZ_OVERRIDE { return false; }
 #if defined(XP_MACOSX)
-    virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
-    virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
+    virtual nsresult IsRemoteDrawingCoreAnimation(NPP aInstance, bool* aDrawing) MOZ_OVERRIDE;
+    virtual nsresult ContentsScaleFactorChanged(NPP aInstance, double aContentsScaleFactor) MOZ_OVERRIDE;
 #endif
     virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE;
     virtual nsresult BeginUpdateBackground(NPP instance,
                                            const nsIntRect&, gfxContext** aCtx) MOZ_OVERRIDE;
     virtual nsresult EndUpdateBackground(NPP instance,
                                          gfxContext* aCtx, const nsIntRect&) MOZ_OVERRIDE;
     virtual void GetLibraryPath(nsACString& aPath) { aPath.Assign(mFilePath); }
 
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -1255,24 +1255,24 @@ public:
     , mNewChannel(newChannel)
   {
   }
 
   ChannelRedirectProxyCallback() {}
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHODIMP OnRedirectVerifyCallback(nsresult result)
+  NS_IMETHODIMP OnRedirectVerifyCallback(nsresult aResult) MOZ_OVERRIDE
   {
-    if (NS_SUCCEEDED(result)) {
+    if (NS_SUCCEEDED(aResult)) {
       nsCOMPtr<nsIStreamListener> listener = do_QueryReferent(mWeakListener);
       if (listener)
         static_cast<nsPluginStreamListenerPeer*>(listener.get())->ReplaceRequest(mOldChannel, mNewChannel);
     }
-    return mParent->OnRedirectVerifyCallback(result);
+    return mParent->OnRedirectVerifyCallback(aResult);
   }
 
 private:
   virtual ~ChannelRedirectProxyCallback() {}
 
   nsWeakPtr mWeakListener;
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mParent;
   nsCOMPtr<nsIChannel> mOldChannel;
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -139,19 +139,19 @@ protected:
 
     virtual bool
     DeallocPPluginScriptableObjectChild(PPluginScriptableObjectChild* aObject) MOZ_OVERRIDE;
 
     virtual bool
     RecvPPluginScriptableObjectConstructor(PPluginScriptableObjectChild* aActor) MOZ_OVERRIDE;
 
     virtual bool
-    RecvPBrowserStreamConstructor(PBrowserStreamChild* aActor, const nsCString& url,
-                                  const uint32_t& length, const uint32_t& lastmodified,
-                                  PStreamNotifyChild* notifyData, const nsCString& headers);
+    RecvPBrowserStreamConstructor(PBrowserStreamChild* aActor, const nsCString& aURL,
+                                  const uint32_t& aLength, const uint32_t& aLastmodified,
+                                  PStreamNotifyChild* aNotifyData, const nsCString& aHeaders) MOZ_OVERRIDE;
 
     virtual bool
     AnswerNPP_NewStream(
             PBrowserStreamChild* actor,
             const nsCString& mimeType,
             const bool& seekable,
             NPError* rv,
             uint16_t* stype) MOZ_OVERRIDE;
@@ -540,17 +540,17 @@ private:
     // Swap mCurrentSurface/mBackSurface and their associated actors
     void SwapSurfaces();
 
     // Clear all surfaces in response to NPP_Destroy
     void ClearAllSurfaces();
 
     void Destroy();
 
-    void ActorDestroy(ActorDestroyReason why);
+    void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
     // Set as true when SetupLayer called
     // and go with different path in InvalidateRect function
     bool mLayersRendering;
 
     // Current surface available for rendering
     nsRefPtr<gfxASurface> mCurrentSurface;
 
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -274,19 +274,19 @@ public:
 #endif
     nsresult SetBackgroundUnknown();
     nsresult BeginUpdateBackground(const nsIntRect& aRect,
                                    gfxContext** aCtx);
     nsresult EndUpdateBackground(gfxContext* aCtx,
                                  const nsIntRect& aRect);
     void DidComposite() { unused << SendNPP_DidComposite(); }
 
-    virtual PluginAsyncSurrogate* GetAsyncSurrogate();
+    virtual PluginAsyncSurrogate* GetAsyncSurrogate() MOZ_OVERRIDE;
 
-    virtual PluginInstanceParent* GetInstance() { return this; }
+    virtual PluginInstanceParent* GetInstance() MOZ_OVERRIDE { return this; }
 
     static PluginInstanceParent* Cast(NPP instance,
                                       PluginAsyncSurrogate** aSurrogate = nullptr);
 
 private:
     // Create an appropriate platform surface for a background of size
     // |aSize|.  Return true if successful.
     bool CreateBackground(const nsIntSize& aSize);
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -109,17 +109,17 @@ public:
     const NPNetscapeFuncs* GetNetscapeFuncs() {
         return mNPNIface;
     }
 
     bool OkToCleanup() const {
         return !IsOnCxxStack();
     }
 
-    void ProcessRemoteNativeEventsInInterruptCall();
+    void ProcessRemoteNativeEventsInInterruptCall() MOZ_OVERRIDE;
 
     virtual bool WaitForIPCConnection() { return true; }
 
     nsCString GetHistogramKey() const {
         return mPluginName + mPluginVersion;
     }
 
 protected:
@@ -209,53 +209,53 @@ protected:
                               NPReason reason, void* notifyData);
     static NPError NPP_GetValue(NPP instance,
                                 NPPVariable variable, void *ret_value);
     static NPError NPP_SetValue(NPP instance, NPNVariable variable,
                                 void *value);
     static void NPP_URLRedirectNotify(NPP instance, const char* url,
                                       int32_t status, void* notifyData);
 
-    virtual bool HasRequiredFunctions();
-    virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
-    virtual nsresult GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer);
-    virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize);
+    virtual bool HasRequiredFunctions() MOZ_OVERRIDE;
+    virtual nsresult AsyncSetWindow(NPP aInstance, NPWindow* aWindow) MOZ_OVERRIDE;
+    virtual nsresult GetImageContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) MOZ_OVERRIDE;
+    virtual nsresult GetImageSize(NPP aInstance, nsIntSize* aSize) MOZ_OVERRIDE;
     virtual bool IsOOP() MOZ_OVERRIDE { return true; }
     virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE;
     virtual nsresult BeginUpdateBackground(NPP instance,
                                            const nsIntRect& aRect,
                                            gfxContext** aCtx) MOZ_OVERRIDE;
     virtual nsresult EndUpdateBackground(NPP instance,
                                          gfxContext* aCtx,
                                          const nsIntRect& aRect) MOZ_OVERRIDE;
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
     virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error);
 #else
-    virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error);
+    virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) MOZ_OVERRIDE;
 #endif
-    virtual nsresult NP_Shutdown(NPError* error);
+    virtual nsresult NP_Shutdown(NPError* error) MOZ_OVERRIDE;
 
-    virtual nsresult NP_GetMIMEDescription(const char** mimeDesc);
+    virtual nsresult NP_GetMIMEDescription(const char** mimeDesc) MOZ_OVERRIDE;
     virtual nsresult NP_GetValue(void *future, NPPVariable aVariable,
-                                 void *aValue, NPError* error);
+                                 void *aValue, NPError* error) MOZ_OVERRIDE;
 #if defined(XP_WIN) || defined(XP_MACOSX)
-    virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error);
+    virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) MOZ_OVERRIDE;
 #endif
     virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
                              uint16_t mode, int16_t argc, char* argn[],
                              char* argv[], NPSavedData* saved,
-                             NPError* error);
+                             NPError* error) MOZ_OVERRIDE;
     virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags,
-                                       uint64_t maxAge);
-    virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result);
+                                       uint64_t maxAge) MOZ_OVERRIDE;
+    virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result) MOZ_OVERRIDE;
 
 #if defined(XP_MACOSX)
-    virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing);
-    virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
+    virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) MOZ_OVERRIDE;
+    virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) MOZ_OVERRIDE;
 #endif
 
     void InitAsyncSurrogates();
 
 protected:
     void NotifyPluginCrashed();
     void OnInitFailure();
 
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -783,23 +783,23 @@ public:
 
   AllResolveHandler(CountdownHolder* aHolder, uint32_t aIndex)
     : mCountdownHolder(aHolder), mIndex(aIndex)
   {
     MOZ_ASSERT(aHolder);
   }
 
   void
-  ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
+  ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) MOZ_OVERRIDE
   {
     mCountdownHolder->SetValue(mIndex, aValue);
   }
 
   void
-  RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
+  RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) MOZ_OVERRIDE
   {
     // Should never be attached to Promise as a reject handler.
     MOZ_ASSERT(false, "AllResolveHandler should never be attached to a Promise's reject handler!");
   }
 
 private:
   ~AllResolveHandler()
   {
--- a/dom/promise/PromiseWorkerProxy.h
+++ b/dom/promise/PromiseWorkerProxy.h
@@ -57,17 +57,17 @@ class WorkerPrivate;
 // thread.
 
 class PromiseWorkerProxy : public PromiseNativeHandler,
                            public workers::WorkerFeature
 {
   friend class PromiseWorkerProxyRunnable;
 
   // This overrides the non-threadsafe refcounting in PromiseNativeHandler.
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PromiseWorkerProxy)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PromiseWorkerProxy, MOZ_OVERRIDE)
 
 public:
   static already_AddRefed<PromiseWorkerProxy>
   Create(workers::WorkerPrivate* aWorkerPrivate,
          Promise* aWorkerPromise,
          const JSStructuredCloneCallbacks* aCallbacks = nullptr);
 
   workers::WorkerPrivate* GetWorkerPrivate() const;
--- a/dom/smil/SMILBoolType.h
+++ b/dom/smil/SMILBoolType.h
@@ -19,23 +19,23 @@ public:
   {
     static SMILBoolType sSingleton;
     return &sSingleton;
   }
 
 protected:
   // nsISMILType Methods
   // -------------------
-  virtual void     Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
-  virtual void     Destroy(nsSMILValue&) const;
+  virtual void Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
+  virtual void Destroy(nsSMILValue& aValue) const MOZ_OVERRIDE;
   virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const MOZ_OVERRIDE;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const MOZ_OVERRIDE;
   virtual bool IsEqual(const nsSMILValue& aLeft,
-                         const nsSMILValue& aRight) const MOZ_OVERRIDE;
+                       const nsSMILValue& aRight) const MOZ_OVERRIDE;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const MOZ_OVERRIDE;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
                                nsSMILValue& aResult) const MOZ_OVERRIDE;
 
--- a/dom/smil/SMILEnumType.h
+++ b/dom/smil/SMILEnumType.h
@@ -20,21 +20,21 @@ public:
   {
     static SMILEnumType sSingleton;
     return &sSingleton;
   }
 
 protected:
   // nsISMILType Methods
   // -------------------
-  virtual void     Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
-  virtual void     Destroy(nsSMILValue&) const;
+  virtual void Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
+  virtual void Destroy(nsSMILValue& aValue) const MOZ_OVERRIDE;
   virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const MOZ_OVERRIDE;
-  virtual bool     IsEqual(const nsSMILValue& aLeft,
-                           const nsSMILValue& aRight) const MOZ_OVERRIDE;
+  virtual bool IsEqual(const nsSMILValue& aLeft,
+                       const nsSMILValue& aRight) const MOZ_OVERRIDE;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const MOZ_OVERRIDE;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const MOZ_OVERRIDE;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
--- a/dom/smil/SMILIntegerType.h
+++ b/dom/smil/SMILIntegerType.h
@@ -9,21 +9,21 @@
 #include "mozilla/Attributes.h"
 #include "nsISMILType.h"
 
 namespace mozilla {
 
 class SMILIntegerType : public nsISMILType
 {
 public:
-  virtual void     Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
-  virtual void     Destroy(nsSMILValue&) const;
+  virtual void Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
+  virtual void Destroy(nsSMILValue& aValue) const MOZ_OVERRIDE;
   virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const MOZ_OVERRIDE;
-  virtual bool     IsEqual(const nsSMILValue& aLeft,
-                           const nsSMILValue& aRight) const MOZ_OVERRIDE;
+  virtual bool IsEqual(const nsSMILValue& aLeft,
+                       const nsSMILValue& aRight) const MOZ_OVERRIDE;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const MOZ_OVERRIDE;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const MOZ_OVERRIDE;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
--- a/dom/smil/SMILStringType.h
+++ b/dom/smil/SMILStringType.h
@@ -20,21 +20,21 @@ public:
   {
     static SMILStringType sSingleton;
     return &sSingleton;
   }
 
 protected:
   // nsISMILType Methods
   // -------------------
-  virtual void     Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
-  virtual void     Destroy(nsSMILValue&) const;
+  virtual void Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
+  virtual void Destroy(nsSMILValue& aValue) const MOZ_OVERRIDE;
   virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const MOZ_OVERRIDE;
-  virtual bool     IsEqual(const nsSMILValue& aLeft,
-                           const nsSMILValue& aRight) const MOZ_OVERRIDE;
+  virtual bool IsEqual(const nsSMILValue& aLeft,
+                       const nsSMILValue& aRight) const MOZ_OVERRIDE;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const MOZ_OVERRIDE;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const MOZ_OVERRIDE;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
--- a/dom/smil/nsSMILFloatType.h
+++ b/dom/smil/nsSMILFloatType.h
@@ -18,21 +18,21 @@ public:
   {
     static nsSMILFloatType sSingleton;
     return &sSingleton;
   }
 
 protected:
   // nsISMILType Methods
   // -------------------
-  virtual void     Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
-  virtual void     Destroy(nsSMILValue&) const;
+  virtual void Init(nsSMILValue& aValue) const MOZ_OVERRIDE;
+  virtual void Destroy(nsSMILValue& aValue) const MOZ_OVERRIDE;
   virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const MOZ_OVERRIDE;
-  virtual bool     IsEqual(const nsSMILValue& aLeft,
-                           const nsSMILValue& aRight) const MOZ_OVERRIDE;
+  virtual bool IsEqual(const nsSMILValue& aLeft,
+                       const nsSMILValue& aRight) const MOZ_OVERRIDE;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const MOZ_OVERRIDE;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const MOZ_OVERRIDE;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
--- a/dom/storage/DOMStorageCache.cpp
+++ b/dom/storage/DOMStorageCache.cpp
@@ -242,17 +242,17 @@ namespace { // anon
 // and keeps it alive for a time.
 class DOMStorageCacheHolder : public nsITimerCallback
 {
   virtual ~DOMStorageCacheHolder() {}
 
   NS_DECL_ISUPPORTS
 
   NS_IMETHODIMP
-  Notify(nsITimer* aTimer)
+  Notify(nsITimer* aTimer) MOZ_OVERRIDE
   {
     mCache = nullptr;
     return NS_OK;
   }
 
   nsRefPtr<DOMStorageCache> mCache;
 
 public:
--- a/dom/storage/DOMStorageIPC.h
+++ b/dom/storage/DOMStorageIPC.h
@@ -169,36 +169,36 @@ public:
   private:
     nsRefPtr<DOMStorageDBParent> mParent;
     nsCString mScope;
   };
 
 private:
   // IPC
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
-  bool RecvAsyncPreload(const nsCString& aScope, const bool& aPriority);
+  bool RecvAsyncPreload(const nsCString& aScope, const bool& aPriority) MOZ_OVERRIDE;
   bool RecvPreload(const nsCString& aScope, const uint32_t& aAlreadyLoadedCount,
                    InfallibleTArray<nsString>* aKeys, InfallibleTArray<nsString>* aValues,
-                   nsresult* aRv);
-  bool RecvAsyncGetUsage(const nsCString& aScope);
-  bool RecvAsyncAddItem(const nsCString& aScope, const nsString& aKey, const nsString& aValue);
-  bool RecvAsyncUpdateItem(const nsCString& aScope, const nsString& aKey, const nsString& aValue);
-  bool RecvAsyncRemoveItem(const nsCString& aScope, const nsString& aKey);
-  bool RecvAsyncClear(const nsCString& aScope);
-  bool RecvAsyncFlush();
+                   nsresult* aRv) MOZ_OVERRIDE;
+  bool RecvAsyncGetUsage(const nsCString& aScope) MOZ_OVERRIDE;
+  bool RecvAsyncAddItem(const nsCString& aScope, const nsString& aKey, const nsString& aValue) MOZ_OVERRIDE;
+  bool RecvAsyncUpdateItem(const nsCString& aScope, const nsString& aKey, const nsString& aValue) MOZ_OVERRIDE;
+  bool RecvAsyncRemoveItem(const nsCString& aScope, const nsString& aKey) MOZ_OVERRIDE;
+  bool RecvAsyncClear(const nsCString& aScope) MOZ_OVERRIDE;
+  bool RecvAsyncFlush() MOZ_OVERRIDE;
 
   // DOMStorageObserverSink
-  virtual nsresult Observe(const char* aTopic, const nsACString& aScopePrefix);
+  virtual nsresult Observe(const char* aTopic, const nsACString& aScopePrefix) MOZ_OVERRIDE;
 
 private:
   CacheParentBridge* NewCache(const nsACString& aScope);
 
   ThreadSafeAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
-	
-	// True when IPC channel is open and Send*() methods are OK to use.
+
+  // True when IPC channel is open and Send*() methods are OK to use.
   bool mIPCOpen;
 };
 
 } // ::dom
 } // ::mozilla
 
 #endif
--- a/dom/storage/DOMStorageManager.h
+++ b/dom/storage/DOMStorageManager.h
@@ -41,17 +41,17 @@ public:
   already_AddRefed<DOMStorageUsage> GetScopeUsage(const nsACString& aScope);
 
 protected:
   explicit DOMStorageManager(DOMStorage::StorageType aType);
   virtual ~DOMStorageManager();
 
 private:
   // DOMStorageObserverSink, handler to various chrome clearing notification
-  virtual nsresult Observe(const char* aTopic, const nsACString& aScopePrefix);
+  virtual nsresult Observe(const char* aTopic, const nsACString& aScopePrefix) MOZ_OVERRIDE;
 
   // Since nsTHashtable doesn't like multiple inheritance, we have to aggregate
   // DOMStorageCache into the entry.
   class DOMStorageCacheHashKey : public nsCStringHashKey
   {
   public:
     explicit DOMStorageCacheHashKey(const nsACString* aKey)
       : nsCStringHashKey(aKey)
--- a/dom/xbl/XBLChildrenElement.cpp
+++ b/dom/xbl/XBLChildrenElement.cpp
@@ -21,28 +21,16 @@ NS_IMPL_RELEASE_INHERITED(XBLChildrenEle
 NS_INTERFACE_TABLE_HEAD(XBLChildrenElement)
   NS_INTERFACE_TABLE_INHERITED(XBLChildrenElement, nsIDOMNode,
                                nsIDOMElement)
   NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
 NS_INTERFACE_MAP_END_INHERITING(Element)
 
 NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
 
-nsIAtom*
-XBLChildrenElement::GetIDAttributeName() const
-{
-  return nullptr;
-}
-
-nsIAtom*
-XBLChildrenElement::DoGetID() const
-{
-  return nullptr;
-}
-
 nsresult
 XBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                               bool aNotify)
 {
   if (aAttribute == nsGkAtoms::includes &&
       aNameSpaceID == kNameSpaceID_None) {
     mIncludes.Clear();
   }
--- a/dom/xbl/XBLChildrenElement.h
+++ b/dom/xbl/XBLChildrenElement.h
@@ -30,31 +30,27 @@ public:
     : nsXMLElement(aNodeInfo)
   {
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsINode interface methods
-  virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
-  virtual nsXPCClassInfo* GetClassInfo() { return nullptr; }
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
+  virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // nsIContent interface methods
-  virtual nsIAtom *GetIDAttributeName() const;
-  virtual nsIAtom* DoGetID() const;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
+                             bool aNotify) MOZ_OVERRIDE;
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
-                              nsAttrValue& aResult);
+                              nsAttrValue& aResult) MOZ_OVERRIDE;
 
   void AppendInsertedChild(nsIContent* aChild)
   {
     mInsertedChildren.AppendElement(aChild);
     aChild->SetXBLInsertionParent(GetParent());
 
     // Appending an inserted child causes the inserted
     // children to be projected instead of default content.
@@ -171,19 +167,19 @@ public:
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsAnonymousContentList)
   // nsIDOMNodeList interface
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList interface
-  virtual int32_t IndexOf(nsIContent* aContent);
-  virtual nsINode* GetParentObject() { return mParent; }
-  virtual nsIContent* Item(uint32_t aIndex);
+  virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
+  virtual nsINode* GetParentObject() MOZ_OVERRIDE { return mParent; }
+  virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
 
   virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
 
   bool IsListFor(nsIContent* aContent) {
     return mParent == aContent;
   }
 
 private:
--- a/dom/xml/CDATASection.h
+++ b/dom/xml/CDATASection.h
@@ -52,17 +52,17 @@ public:
 
   // nsIDOMText
   NS_FORWARD_NSIDOMTEXT(nsGenericDOMDataNode::)
 
   // nsIDOMCDATASection
   // Empty interface
 
   // nsINode
-  virtual bool IsNodeOfType(uint32_t aFlags) const;
+  virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
 
   virtual nsGenericDOMDataNode* CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                                               bool aCloneText) const MOZ_OVERRIDE;
 
   virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 #ifdef DEBUG
   virtual void List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE;
   virtual void DumpContent(FILE* out, int32_t aIndent,bool aDumpAll) const MOZ_OVERRIDE;
--- a/dom/xml/ProcessingInstruction.h
+++ b/dom/xml/ProcessingInstruction.h
@@ -30,17 +30,17 @@ public:
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
   using nsGenericDOMDataNode::SetData; // Prevent hiding overloaded virtual function.
 
   // nsIDOMProcessingInstruction
   NS_DECL_NSIDOMPROCESSINGINSTRUCTION
 
   // nsINode
-  virtual bool IsNodeOfType(uint32_t aFlags) const;
+  virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
 
   virtual nsGenericDOMDataNode* CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                                               bool aCloneText) const MOZ_OVERRIDE;
 
 #ifdef DEBUG
   virtual void List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE;
   virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const MOZ_OVERRIDE;
 #endif
--- a/dom/xml/nsXMLFragmentContentSink.cpp
+++ b/dom/xml/nsXMLFragmentContentSink.cpp
@@ -40,69 +40,69 @@ public:
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLFragmentContentSink,
                                                      nsXMLContentSink)
 
   // nsIExpatSink
-  NS_IMETHOD HandleDoctypeDecl(const nsAString & aSubset, 
-                               const nsAString & aName, 
-                               const nsAString & aSystemId, 
-                               const nsAString & aPublicId,
-                               nsISupports* aCatalogData);
-  NS_IMETHOD HandleProcessingInstruction(const char16_t *aTarget, 
-                                         const char16_t *aData);
-  NS_IMETHOD HandleXMLDeclaration(const char16_t *aVersion,
-                                  const char16_t *aEncoding,
-                                  int32_t aStandalone);
-  NS_IMETHOD ReportError(const char16_t* aErrorText, 
+  NS_IMETHOD HandleDoctypeDecl(const nsAString& aSubset,
+                               const nsAString& aName,
+                               const nsAString& aSystemId,
+                               const nsAString& aPublicId,
+                               nsISupports* aCatalogData) MOZ_OVERRIDE;
+  NS_IMETHOD HandleProcessingInstruction(const char16_t* aTarget,
+                                         const char16_t* aData) MOZ_OVERRIDE;
+  NS_IMETHOD HandleXMLDeclaration(const char16_t* aVersion,
+                                  const char16_t* aEncoding,
+                                  int32_t aStandalone) MOZ_OVERRIDE;
+  NS_IMETHOD ReportError(const char16_t* aErrorText,
                          const char16_t* aSourceText,
-                         nsIScriptError *aError,
-                         bool *_retval);
+                         nsIScriptError* aError,
+                         bool* aRetval) MOZ_OVERRIDE;
 
   // nsIContentSink
-  NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode);
-  NS_IMETHOD DidBuildModel(bool aTerminated);
-  NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
-  virtual nsISupports *GetTarget();
+  NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) MOZ_OVERRIDE;
+  NS_IMETHOD DidBuildModel(bool aTerminated) MOZ_OVERRIDE;
+  NS_IMETHOD SetDocumentCharset(nsACString& aCharset) MOZ_OVERRIDE;
+  virtual nsISupports* GetTarget() MOZ_OVERRIDE;
   NS_IMETHOD DidProcessATokenImpl();
 
   // nsIXMLContentSink
 
   // nsIFragmentContentSink
-  NS_IMETHOD FinishFragmentParsing(nsIDOMDocumentFragment** aFragment);
-  NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
-  NS_IMETHOD WillBuildContent();
-  NS_IMETHOD DidBuildContent();
-  NS_IMETHOD IgnoreFirstContainer();
-  NS_IMETHOD SetPreventScriptExecution(bool aPreventScriptExecution);
+  NS_IMETHOD FinishFragmentParsing(nsIDOMDocumentFragment** aFragment) MOZ_OVERRIDE;
+  NS_IMETHOD SetTargetDocument(nsIDocument* aDocument) MOZ_OVERRIDE;
+  NS_IMETHOD WillBuildContent() MOZ_OVERRIDE;
+  NS_IMETHOD DidBuildContent() MOZ_OVERRIDE;
+  NS_IMETHOD IgnoreFirstContainer() MOZ_OVERRIDE;
+  NS_IMETHOD SetPreventScriptExecution(bool aPreventScriptExecution) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsXMLFragmentContentSink();
 
-  virtual bool SetDocElement(int32_t aNameSpaceID, 
-                               nsIAtom *aTagName,
-                               nsIContent *aContent);
+  virtual bool SetDocElement(int32_t aNameSpaceID,
+                               nsIAtom* aTagName,
+                               nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
                                  mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
                                  nsIContent** aResult, bool* aAppendContent,
-                                 mozilla::dom::FromParser aFromParser);
-  virtual nsresult CloseElement(nsIContent* aContent);
+                                 mozilla::dom::FromParser aFromParser) MOZ_OVERRIDE;
+  virtual nsresult CloseElement(nsIContent* aContent) MOZ_OVERRIDE;
 
-  virtual void MaybeStartLayout(bool aIgnorePendingSheets);
+  virtual void MaybeStartLayout(bool aIgnorePendingSheets) MOZ_OVERRIDE;
 
   // nsContentSink overrides
   virtual nsresult ProcessStyleLink(nsIContent* aElement,
                                     const nsSubstring& aHref,
                                     bool aAlternate,
                                     const nsSubstring& aTitle,
                                     const nsSubstring& aType,
-                                    const nsSubstring& aMedia);
+                                    const nsSubstring& aMedia) MOZ_OVERRIDE;
   nsresult LoadXSLStyleSheet(nsIURI* aUrl);
   void StartLayout();
 
   nsCOMPtr<nsIDocument> mTargetDocument;
   // the fragment
   nsCOMPtr<nsIContent>  mRoot;
   bool                  mParseError;
 };
--- a/dom/xslt/xpath/XPathResult.h
+++ b/dom/xslt/xpath/XPathResult.h
@@ -72,17 +72,17 @@ public:
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(XPathResult,
                                                            nsIXPathResult)
 
     static XPathResult* FromSupports(nsISupports* aSupports)
     {
         return static_cast<XPathResult*>(static_cast<nsIXPathResult*>(aSupports));
     }
 
-    virtual JSObject* WrapObject(JSContext* aCx);
+    virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
     nsINode* GetParentObject() const
     {
         return mParent;
     }
     uint16_t ResultType() const
     {
         return mResultType;
     }
--- a/dom/xslt/xpath/txExpr.h
+++ b/dom/xslt/xpath/txExpr.h
@@ -134,39 +134,38 @@ public:
      * @return the String representation of this Expr.
     **/
     virtual void toString(nsAString& str) = 0;
 #endif
 }; //-- Expr
 
 #ifdef TX_TO_STRING
 #define TX_DECL_TOSTRING \
-    void toString(nsAString& aDest);
+    void toString(nsAString& aDest) MOZ_OVERRIDE;
 #define TX_DECL_GETNAMEATOM \
-    nsresult getNameAtom(nsIAtom** aAtom);
+    nsresult getNameAtom(nsIAtom** aAtom) MOZ_OVERRIDE;
 #else
 #define TX_DECL_TOSTRING
 #define TX_DECL_GETNAMEATOM
 #endif
 
 #define TX_DECL_EXPR_BASE \
-    nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \
-    ResultType getReturnType(); \
-    bool isSensitiveTo(ContextSensitivity aContexts);
+    nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult) MOZ_OVERRIDE; \
+    ResultType getReturnType() MOZ_OVERRIDE; \
+    bool isSensitiveTo(ContextSensitivity aContexts) MOZ_OVERRIDE;
 
 #define TX_DECL_EXPR \
     TX_DECL_EXPR_BASE \
     TX_DECL_TOSTRING \
-    Expr* getSubExprAt(uint32_t aPos); \
-    void setSubExprAt(uint32_t aPos, Expr* aExpr);
+    Expr* getSubExprAt(uint32_t aPos) MOZ_OVERRIDE; \
+    void setSubExprAt(uint32_t aPos, Expr* aExpr) MOZ_OVERRIDE;
 
 #define TX_DECL_OPTIMIZABLE_EXPR \
     TX_DECL_EXPR \
-    ExprType getType();
-    
+    ExprType getType() MOZ_OVERRIDE;
 
 #define TX_DECL_FUNCTION \
     TX_DECL_GETNAMEATOM \
     TX_DECL_EXPR_BASE
 
 #define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)          \
 Expr::ResultType                                              \
 _class::getReturnType()                                       \
@@ -421,19 +420,19 @@ public:
 
 #ifdef TX_TO_STRING
     virtual void toString(nsAString& aDest) = 0;
 #endif
 };
 
 #define TX_DECL_NODE_TEST \
     TX_DECL_TOSTRING \
-    bool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
-    double getDefaultPriority(); \
-    bool isSensitiveTo(Expr::ContextSensitivity aContext);
+    bool matches(const txXPathNode& aNode, txIMatchContext* aContext) MOZ_OVERRIDE; \
+    double getDefaultPriority() MOZ_OVERRIDE; \
+    bool isSensitiveTo(Expr::ContextSensitivity aContext) MOZ_OVERRIDE;
 
 /*
  * This class represents a NameTest as defined by the XPath spec
  */
 class txNameTest : public txNodeTest
 {
 public:
     /*
--- a/dom/xslt/xpath/txXPathObjectAdaptor.h
+++ b/dom/xslt/xpath/txXPathObjectAdaptor.h
@@ -22,17 +22,17 @@ public:
     {
         NS_ASSERTION(aValue,
                      "Don't create a txXPathObjectAdaptor if you don't have a "
                      "txAExprResult");
     }
 
     NS_DECL_ISUPPORTS
 
-    NS_IMETHODIMP_(txAExprResult*) GetResult()
+    NS_IMETHODIMP_(txAExprResult*) GetResult() MOZ_OVERRIDE
     {
         return mValue;
     }
 
 protected:
     txXPathObjectAdaptor() : mValue(nullptr)
     {
     }
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -74,24 +74,24 @@ public:
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIEXPATSINK
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSIINTERFACEREQUESTOR
 
     // nsIContentSink
-    NS_IMETHOD WillParse(void) { return NS_OK; }
-    NS_IMETHOD DidBuildModel(bool aTerminated);
-    NS_IMETHOD WillInterrupt(void) { return NS_OK; }
-    NS_IMETHOD WillResume(void) { return NS_OK; }
-    NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
-    virtual void FlushPendingNotifications(mozFlushType aType) { }
-    NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
-    virtual nsISupports *GetTarget() { return nullptr; }
+    NS_IMETHOD WillParse(void) MOZ_OVERRIDE { return NS_OK; }
+    NS_IMETHOD DidBuildModel(bool aTerminated) MOZ_OVERRIDE;
+    NS_IMETHOD WillInterrupt(void) MOZ_OVERRIDE { return NS_OK; }
+    NS_IMETHOD WillResume(void) MOZ_OVERRIDE { return NS_OK; }
+    NS_IMETHOD SetParser(nsParserBase* aParser) MOZ_OVERRIDE { return NS_OK; }
+    virtual void FlushPendingNotifications(mozFlushType aType) MOZ_OVERRIDE { }
+    NS_IMETHOD SetDocumentCharset(nsACString& aCharset) MOZ_OVERRIDE { return NS_OK; }
+    virtual nsISupports *GetTarget() MOZ_OVERRIDE { return nullptr; }
 
 private:
     nsRefPtr<txStylesheetCompiler> mCompiler;
     nsCOMPtr<nsIStreamListener> mListener;
     bool mCheckedForXML;
 
 protected:
     ~txStylesheetSink() {}
--- a/dom/xslt/xslt/txXSLTPatterns.h
+++ b/dom/xslt/xslt/txXSLTPatterns.h
@@ -83,29 +83,29 @@ public:
      * other #toString() methods for Patterns.
      * @return the String representation of this Pattern.
      */
     virtual void toString(nsAString& aDest) = 0;
 #endif
 };
 
 #define TX_DECL_PATTERN_BASE \
-    bool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
-    double getDefaultPriority(); \
-    virtual Expr* getSubExprAt(uint32_t aPos); \
-    virtual void setSubExprAt(uint32_t aPos, Expr* aExpr); \
-    virtual txPattern* getSubPatternAt(uint32_t aPos); \
-    virtual void setSubPatternAt(uint32_t aPos, txPattern* aPattern)
+    bool matches(const txXPathNode& aNode, txIMatchContext* aContext) MOZ_OVERRIDE; \
+    double getDefaultPriority() MOZ_OVERRIDE; \
+    virtual Expr* getSubExprAt(uint32_t aPos) MOZ_OVERRIDE; \
+    virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) MOZ_OVERRIDE; \
+    virtual txPattern* getSubPatternAt(uint32_t aPos) MOZ_OVERRIDE; \
+    virtual void setSubPatternAt(uint32_t aPos, txPattern* aPattern) MOZ_OVERRIDE
 
 #ifndef TX_TO_STRING
 #define TX_DECL_PATTERN TX_DECL_PATTERN_BASE
 #else
 #define TX_DECL_PATTERN \
     TX_DECL_PATTERN_BASE; \
-    void toString(nsAString& aDest)
+    void toString(nsAString& aDest) MOZ_OVERRIDE
 #endif
 
 #define TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(_class)             \
 Expr*                                                         \
 _class::getSubExprAt(uint32_t aPos)                           \
 {                                                             \
     return nullptr;                                            \
 }                                                             \
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -133,17 +133,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULElementTearoff,
                                            nsIDOMElementCSSInlineStyle)
 
   explicit nsXULElementTearoff(nsXULElement* aElement)
     : mElement(aElement)
   {
   }
 
-  NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
+  NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle) MOZ_OVERRIDE
   {
     nsXULElement* element = static_cast<nsXULElement*>(mElement.get());
     NS_ADDREF(*aStyle = element->Style());
     return NS_OK;
   }
   NS_FORWARD_NSIFRAMELOADEROWNER(static_cast<nsXULElement*>(mElement.get())->)
 private:
   nsCOMPtr<nsIDOMXULElement> mElement;
--- a/dom/xul/templates/nsXULContentBuilder.cpp
+++ b/dom/xul/templates/nsXULContentBuilder.cpp
@@ -67,41 +67,41 @@ using namespace mozilla::dom;
  *
  * If recursion is allowed, generation continues, where the generation node
  * becomes the container to insert into.
  */
 class nsXULContentBuilder : public nsXULTemplateBuilder
 {
 public:
     // nsIXULTemplateBuilder interface
-    NS_IMETHOD CreateContents(nsIContent* aElement, bool aForceCreation);
+    NS_IMETHOD CreateContents(nsIContent* aElement, bool aForceCreation) MOZ_OVERRIDE;
 
     NS_IMETHOD HasGeneratedContent(nsIRDFResource* aResource,
                                    nsIAtom* aTag,
-                                   bool* aGenerated);
+                                   bool* aGenerated) MOZ_OVERRIDE;
 
     NS_IMETHOD GetResultForContent(nsIDOMElement* aContent,
-                                   nsIXULTemplateResult** aResult);
+                                   nsIXULTemplateResult** aResult) MOZ_OVERRIDE;
 
     // nsIMutationObserver interface
     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
     NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
 protected:
     friend nsresult
     NS_NewXULContentBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult);
 
     nsXULContentBuilder();
 
-    void Traverse(nsCycleCollectionTraversalCallback &cb) const
+    void Traverse(nsCycleCollectionTraversalCallback& aCb) const MOZ_OVERRIDE
     {
-        mSortState.Traverse(cb);
+        mSortState.Traverse(aCb);
     }
 
-    virtual void Uninit(bool aIsFinal);
+    virtual void Uninit(bool aIsFinal) MOZ_OVERRIDE;
 
     // Implementation methods
     nsresult
     OpenContainer(nsIContent* aElement);
 
     nsresult
     CloseContainer(nsIContent* aElement);
 
@@ -264,47 +264,47 @@ protected:
      */
     nsresult
     SetContainerAttrs(nsIContent *aElement,
                       nsIXULTemplateResult* aResult,
                       bool aIgnoreNonContainers,
                       bool aNotify);
 
     virtual nsresult
-    RebuildAll();
+    RebuildAll() MOZ_OVERRIDE;
 
     // GetInsertionLocations, ReplaceMatch and SynchronizeResult are inherited
     // from nsXULTemplateBuilder
 
     /**
      * Return true if the result can be inserted into the template as
      * generated content. For the content builder, aLocations will be set
      * to the list of containers where the content should be inserted.
      */
     virtual bool
     GetInsertionLocations(nsIXULTemplateResult* aOldResult,
-                          nsCOMArray<nsIContent>** aLocations);
+                          nsCOMArray<nsIContent>** aLocations) MOZ_OVERRIDE;
 
     /**
      * Remove the content associated with aOldResult which no longer matches,
      * and/or generate content for a new match.
      */
     virtual nsresult
     ReplaceMatch(nsIXULTemplateResult* aOldResult,
                  nsTemplateMatch* aNewMatch,
                  nsTemplateRule* aNewMatchRule,
-                 void *aContext);
+                 void *aContext) MOZ_OVERRIDE;
 
     /**
      * Synchronize a result bindings with the generated content for that
      * result. This will be called as a result of the template builder's
      * ResultBindingChanged method.
      */
     virtual nsresult
-    SynchronizeResult(nsIXULTemplateResult* aResult);
+    SynchronizeResult(nsIXULTemplateResult* aResult) MOZ_OVERRIDE;
 
     /**
      * Compare a result to a content node. If the generated content for the
      * result should come before aContent, set aSortOrder to -1. If it should
      * come after, set sortOrder to 1. If both are equal, set to 0.
      */
     nsresult
     CompareResultToNode(nsIXULTemplateResult* aResult, nsIContent* aContent,
--- a/dom/xul/templates/nsXULTreeBuilder.cpp
+++ b/dom/xul/templates/nsXULTreeBuilder.cpp
@@ -50,43 +50,43 @@ public:
     NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
 
     // nsIXULTreeBuilder
     NS_DECL_NSIXULTREEBUILDER
 
     // nsITreeView
     NS_DECL_NSITREEVIEW
     // nsINativeTreeView: Untrusted code can use us
-    NS_IMETHOD EnsureNative() { return NS_OK; }
+    NS_IMETHOD EnsureNative() MOZ_OVERRIDE { return NS_OK; }
 
     // nsIMutationObserver
     NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
 protected:
     friend nsresult
     NS_NewXULTreeBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult);
 
     friend struct ResultComparator;
 
     nsXULTreeBuilder();
     ~nsXULTreeBuilder();
 
     /**
      * Uninitialize the template builder
      */
-    virtual void Uninit(bool aIsFinal);
+    virtual void Uninit(bool aIsFinal) MOZ_OVERRIDE;
 
     /**
      * Get sort variables from the active <treecol>
      */
     nsresult
     EnsureSortVariables();
 
     virtual nsresult
-    RebuildAll();
+    RebuildAll() MOZ_OVERRIDE;
 
     /**
      * Given a row, use the row's match to figure out the appropriate
      * <treerow> in the rule's <action>.
      */
     nsresult
     GetTemplateActionRowFor(int32_t aRow, nsIContent** aResult);
 
@@ -164,43 +164,43 @@ protected:
      * beneath it.
      */
     nsresult
     SortSubtree(nsTreeRows::Subtree* aSubtree);
 
     NS_IMETHOD
     HasGeneratedContent(nsIRDFResource* aResource,
                         nsIAtom* aTag,
-                        bool* aGenerated);
+                        bool* aGenerated) MOZ_OVERRIDE;
 
     // GetInsertionLocations, ReplaceMatch and SynchronizeResult are inherited
     // from nsXULTemplateBuilder
 
     /**
      * Return true if the result can be inserted into the template as a new
      * row.
      */
     bool
     GetInsertionLocations(nsIXULTemplateResult* aResult,
-                          nsCOMArray<nsIContent>** aLocations);
+                          nsCOMArray<nsIContent>** aLocations) MOZ_OVERRIDE;
 
     /**
      * Implement result replacement
      */
     virtual nsresult
     ReplaceMatch(nsIXULTemplateResult* aOldResult,
                  nsTemplateMatch* aNewMatch,
                  nsTemplateRule* aNewMatchRule,
-                 void *aContext);
+                 void* aContext) MOZ_OVERRIDE;
 
     /**
      * Implement match synchronization
      */
     virtual nsresult
-    SynchronizeResult(nsIXULTemplateResult* aResult);
+    SynchronizeResult(nsIXULTemplateResult* aResult) MOZ_OVERRIDE;
 
     /**
      * The tree's box object, used to communicate with the front-end.
      */
     nsCOMPtr<nsITreeBoxObject> mBoxObject;
 
     /**
      * The tree's selection object.
--- a/editor/composer/nsComposerCommands.h
+++ b/editor/composer/nsComposerCommands.h
@@ -33,18 +33,18 @@ protected:
 public:
 
   nsBaseComposerCommand();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIControllerCommand. Declared longhand so we can make them pure virtual
-  NS_IMETHOD IsCommandEnabled(const char * aCommandName, nsISupports *aCommandRefCon, bool *_retval) = 0;
-  NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandRefCon) = 0;
+  NS_IMETHOD IsCommandEnabled(const char * aCommandName, nsISupports *aCommandRefCon, bool *_retval) MOZ_OVERRIDE = 0;
+  NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandRefCon) MOZ_OVERRIDE = 0;
 
 };
 
 
 #define NS_DECL_COMPOSER_COMMAND(_cmd)                  \
 class _cmd : public nsBaseComposerCommand               \
 {                                                       \
 public:                                                 \
--- a/editor/composer/nsComposerCommandsUpdater.h
+++ b/editor/composer/nsComposerCommandsUpdater.h
@@ -42,31 +42,31 @@ public:
   // nsIDocumentStateListener
   NS_DECL_NSIDOCUMENTSTATELISTENER
 
   // nsITimerCallback interfaces
   NS_DECL_NSITIMERCALLBACK
 
   /** nsITransactionListener interfaces
     */  
-  NS_IMETHOD WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt);
-  NS_IMETHOD DidDo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aDoResult);
-  NS_IMETHOD WillUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt);
-  NS_IMETHOD DidUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aUndoResult);
-  NS_IMETHOD WillRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt);
-  NS_IMETHOD DidRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aRedoResult);
-  NS_IMETHOD WillBeginBatch(nsITransactionManager *aManager, bool *aInterrupt);
-  NS_IMETHOD DidBeginBatch(nsITransactionManager *aManager, nsresult aResult);
-  NS_IMETHOD WillEndBatch(nsITransactionManager *aManager, bool *aInterrupt);
-  NS_IMETHOD DidEndBatch(nsITransactionManager *aManager, nsresult aResult);
+  NS_IMETHOD WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt) MOZ_OVERRIDE;
+  NS_IMETHOD DidDo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aDoResult) MOZ_OVERRIDE;
+  NS_IMETHOD WillUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt) MOZ_OVERRIDE;
+  NS_IMETHOD DidUndo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aUndoResult) MOZ_OVERRIDE;
+  NS_IMETHOD WillRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, bool *aInterrupt) MOZ_OVERRIDE;
+  NS_IMETHOD DidRedo(nsITransactionManager *aManager, nsITransaction *aTransaction, nsresult aRedoResult) MOZ_OVERRIDE;
+  NS_IMETHOD WillBeginBatch(nsITransactionManager *aManager, bool *aInterrupt) MOZ_OVERRIDE;
+  NS_IMETHOD DidBeginBatch(nsITransactionManager *aManager, nsresult aResult) MOZ_OVERRIDE;
+  NS_IMETHOD WillEndBatch(nsITransactionManager *aManager, bool *aInterrupt) MOZ_OVERRIDE;
+  NS_IMETHOD DidEndBatch(nsITransactionManager *aManager, nsresult aResult) MOZ_OVERRIDE;
   NS_IMETHOD WillMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction,
-                       nsITransaction *aTransactionToMerge, bool *aInterrupt);
+                       nsITransaction *aTransactionToMerge, bool *aInterrupt) MOZ_OVERRIDE;
   NS_IMETHOD DidMerge(nsITransactionManager *aManager, nsITransaction *aTopTransaction,
                       nsITransaction *aTransactionToMerge,
-                      bool aDidMerge, nsresult aMergeResult);
+                      bool aDidMerge, nsresult aMergeResult) MOZ_OVERRIDE;
 
 
   nsresult   Init(nsIDOMWindow* aDOMWindow);
 
 protected:
 
   virtual ~nsComposerCommandsUpdater();
 
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -133,32 +133,32 @@ public:
 
   DictionaryFetcher(nsEditorSpellCheck* aSpellCheck,
                     nsIEditorSpellCheckCallback* aCallback,
                     uint32_t aGroup)
     : mCallback(aCallback), mGroup(aGroup), mSpellCheck(aSpellCheck) {}
 
   NS_IMETHOD Fetch(nsIEditor* aEditor);
 
-  NS_IMETHOD HandleResult(nsIContentPref* aPref)
+  NS_IMETHOD HandleResult(nsIContentPref* aPref) MOZ_OVERRIDE
   {
     nsCOMPtr<nsIVariant> value;
     nsresult rv = aPref->GetValue(getter_AddRefs(value));
     NS_ENSURE_SUCCESS(rv, rv);
     value->GetAsAString(mDictionary);
     return NS_OK;
   }
 
-  NS_IMETHOD HandleCompletion(uint16_t reason)
+  NS_IMETHOD HandleCompletion(uint16_t reason) MOZ_OVERRIDE
   {
     mSpellCheck->DictionaryFetched(this);
     return NS_OK;
   }
 
-  NS_IMETHOD HandleError(nsresult error)
+  NS_IMETHOD HandleError(nsresult error) MOZ_OVERRIDE
   {
     return NS_OK;
   }
 
   nsCOMPtr<nsIEditorSpellCheckCallback> mCallback;
   uint32_t mGroup;
   nsString mRootContentLang;
   nsString mRootDocContentLang;
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1191,38 +1191,34 @@ public:
   static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   static TemporaryRef<DrawTarget>
     CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
                                          ID3D10Texture2D *aTextureB,
                                          SurfaceFormat aFormat);
 
   static void SetDirect3D10Device(ID3D10Device1 *aDevice);
   static ID3D10Device1 *GetDirect3D10Device();
-#ifdef USE_D2D1_1
   static TemporaryRef<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
 
   static void SetDirect3D11Device(ID3D11Device *aDevice);
   static ID3D11Device *GetDirect3D11Device();
   static ID2D1Device *GetD2D1Device();
   static bool SupportsD2D1();
-#endif
 
   static TemporaryRef<GlyphRenderingOptions>
     CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams);
 
   static uint64_t GetD2DVRAMUsageDrawTarget();
   static uint64_t GetD2DVRAMUsageSourceSurface();
   static void D2DCleanup();
 
 private:
+  static ID2D1Device *mD2D1Device;
   static ID3D10Device1 *mD3D10Device;
-#ifdef USE_D2D1_1
   static ID3D11Device *mD3D11Device;
-  static ID2D1Device *mD2D1Device;
-#endif
 #endif
 
   static DrawEventRecorder *mRecorder;
 };
 
 }
 }
 
--- a/gfx/2d/DataSourceSurfaceWrapper.h
+++ b/gfx/2d/DataSourceSurfaceWrapper.h
@@ -11,17 +11,17 @@
 namespace mozilla {
 namespace gfx {
 
 // Wraps a DataSourceSurface and forwards all methods except for GetType(),
 // from which it always returns SurfaceType::DATA.
 class DataSourceSurfaceWrapper : public DataSourceSurface
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceWrapper)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceWrapper, MOZ_OVERRIDE)
   explicit DataSourceSurfaceWrapper(DataSourceSurface *aSurface)
    : mSurface(aSurface)
   {}
 
   virtual SurfaceType GetType() const MOZ_OVERRIDE { return SurfaceType::DATA; }
 
   virtual uint8_t *GetData() MOZ_OVERRIDE { return mSurface->GetData(); }
   virtual int32_t Stride() MOZ_OVERRIDE { return mSurface->Stride(); }
--- a/gfx/2d/DrawTargetCG.h
+++ b/gfx/2d/DrawTargetCG.h
@@ -89,102 +89,102 @@ SetStrokeOptions(CGContextRef cg, const 
     CGContextSetLineDash(cg, aStrokeOptions.mDashOffset, dashes, aStrokeOptions.mDashLength);
     delete[] dashes;
   }
 }
 
 class GlyphRenderingOptionsCG : public GlyphRenderingOptions
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsCG)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsCG, MOZ_OVERRIDE)
 
   explicit GlyphRenderingOptionsCG(const Color &aFontSmoothingBackgroundColor)
     : mFontSmoothingBackgroundColor(aFontSmoothingBackgroundColor)
   {}
 
   const Color &FontSmoothingBackgroundColor() const { return mFontSmoothingBackgroundColor; }
 
   virtual FontType GetType() const MOZ_OVERRIDE { return FontType::MAC; }
 
 private:
   Color mFontSmoothingBackgroundColor;
 };
 
 class DrawTargetCG : public DrawTarget
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG, MOZ_OVERRIDE)
   friend class BorrowedCGContext;
   friend class SourceSurfaceCGBitmapContext;
   DrawTargetCG();
   virtual ~DrawTargetCG();
 
   virtual DrawTargetType GetType() const MOZ_OVERRIDE;
-  virtual BackendType GetBackendType() const;
-  virtual TemporaryRef<SourceSurface> Snapshot();
+  virtual BackendType GetBackendType() const MOZ_OVERRIDE;
+  virtual TemporaryRef<SourceSurface> Snapshot() MOZ_OVERRIDE;
 
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
-                        const DrawOptions &aOptions = DrawOptions());
+                        const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
 
   //XXX: why do we take a reference to SurfaceFormat?
   bool Init(BackendType aType, const IntSize &aSize, SurfaceFormat&);
   bool Init(BackendType aType, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
   bool Init(CGContextRef cgContext, const IntSize &aSize);
 
   // Flush if using IOSurface context
-  virtual void Flush();
+  virtual void Flush() MOZ_OVERRIDE;
 
-  virtual void DrawSurfaceWithShadow(SourceSurface *, const Point &, const Color &, const Point &, Float, CompositionOp);
-  virtual void ClearRect(const Rect &);
-  virtual void CopySurface(SourceSurface *, const IntRect&, const IntPoint&);
-  virtual void StrokeRect(const Rect &, const Pattern &, const StrokeOptions&, const DrawOptions&);
-  virtual void StrokeLine(const Point &, const Point &, const Pattern &, const StrokeOptions &, const DrawOptions &);
-  virtual void Stroke(const Path *, const Pattern &, const StrokeOptions &, const DrawOptions &);
-  virtual void Fill(const Path *, const Pattern &, const DrawOptions &);
-  virtual void FillGlyphs(ScaledFont *, const GlyphBuffer&, const Pattern &, const DrawOptions &, const GlyphRenderingOptions *);
+  virtual void DrawSurfaceWithShadow(SourceSurface *, const Point &, const Color &, const Point &, Float, CompositionOp) MOZ_OVERRIDE;
+  virtual void ClearRect(const Rect &) MOZ_OVERRIDE;
+  virtual void CopySurface(SourceSurface *, const IntRect&, const IntPoint&) MOZ_OVERRIDE;
+  virtual void StrokeRect(const Rect &, const Pattern &, const StrokeOptions&, const DrawOptions&) MOZ_OVERRIDE;
+  virtual void StrokeLine(const Point &, const Point &, const Pattern &, const StrokeOptions &, const DrawOptions &) MOZ_OVERRIDE;
+  virtual void Stroke(const Path *, const Pattern &, const StrokeOptions &, const DrawOptions &) MOZ_OVERRIDE;
+  virtual void Fill(const Path *, const Pattern &, const DrawOptions &) MOZ_OVERRIDE;
+  virtual void FillGlyphs(ScaledFont *, const GlyphBuffer&, const Pattern &, const DrawOptions &, const GlyphRenderingOptions *) MOZ_OVERRIDE;
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
-                    const DrawOptions &aOptions = DrawOptions());
-  virtual void PushClip(const Path *);
-  virtual void PushClipRect(const Rect &aRect);
-  virtual void PopClip();
-  virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromNativeSurface(const NativeSurface&) const { return nullptr;}
-  virtual TemporaryRef<DrawTarget> CreateSimilarDrawTarget(const IntSize &, SurfaceFormat) const;
-  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule) const;
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
+  virtual void PushClip(const Path *) MOZ_OVERRIDE;
+  virtual void PushClipRect(const Rect &aRect) MOZ_OVERRIDE;
+  virtual void PopClip() MOZ_OVERRIDE;
+  virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromNativeSurface(const NativeSurface&) const MOZ_OVERRIDE { return nullptr;}
+  virtual TemporaryRef<DrawTarget> CreateSimilarDrawTarget(const IntSize &, SurfaceFormat) const MOZ_OVERRIDE;
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule) const MOZ_OVERRIDE;
   virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *, uint32_t,
-                                                          ExtendMode aExtendMode = ExtendMode::CLAMP) const;
-  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
+                                                          ExtendMode aExtendMode = ExtendMode::CLAMP) const MOZ_OVERRIDE;
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) MOZ_OVERRIDE;
 
-  virtual void *GetNativeSurface(NativeSurfaceType);
+  virtual void *GetNativeSurface(NativeSurfaceType) MOZ_OVERRIDE;
 
-  virtual IntSize GetSize() { return mSize; }
+  virtual IntSize GetSize() MOZ_OVERRIDE { return mSize; }
 
 
   /* This is for creating good compatible surfaces */
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
-                                                            SurfaceFormat aFormat) const;
-  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+                                                            SurfaceFormat aFormat) const MOZ_OVERRIDE;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE;
   CGContextRef GetCGContext() {
       return mCg;
   }
 private:
   void MarkChanged();
 
   IntSize mSize;
   CGColorSpaceRef mColorSpace;
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -47,126 +47,126 @@ class GradientStopsCairo : public Gradie
   private:
     std::vector<GradientStop> mStops;
     ExtendMode mExtendMode;
 };
 
 class DrawTargetCairo : public DrawTarget
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCairo)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCairo, MOZ_OVERRIDE)
   friend class BorrowedCairoContext;
 
   DrawTargetCairo();
   virtual ~DrawTargetCairo();
 
   virtual DrawTargetType GetType() const MOZ_OVERRIDE;
-  virtual BackendType GetBackendType() const { return BackendType::CAIRO; }
-  virtual TemporaryRef<SourceSurface> Snapshot();
-  virtual IntSize GetSize();
+  virtual BackendType GetBackendType() const MOZ_OVERRIDE { return BackendType::CAIRO; }
+  virtual TemporaryRef<SourceSurface> Snapshot() MOZ_OVERRIDE;
+  virtual IntSize GetSize() MOZ_OVERRIDE;
 
-  virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA);
+  virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) MOZ_OVERRIDE;
 
   virtual bool LockBits(uint8_t** aData, IntSize* aSize,
-                        int32_t* aStride, SurfaceFormat* aFormat);
-  virtual void ReleaseBits(uint8_t* aData);
+                        int32_t* aStride, SurfaceFormat* aFormat) MOZ_OVERRIDE;
+  virtual void ReleaseBits(uint8_t* aData) MOZ_OVERRIDE;
 
-  virtual void Flush();
+  virtual void Flush() MOZ_OVERRIDE;
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
-                                     CompositionOp aOperator);
+                                     CompositionOp aOperator) MOZ_OVERRIDE;
 
-  virtual void ClearRect(const Rect &aRect);
+  virtual void ClearRect(const Rect &aRect) MOZ_OVERRIDE;
 
   virtual void CopySurface(SourceSurface *aSurface,
                            const IntRect &aSourceRect,
-                           const IntPoint &aDestination);
+                           const IntPoint &aDestination) MOZ_OVERRIDE;
   virtual void CopyRect(const IntRect &aSourceRect,
-                        const IntPoint &aDestination);
+                        const IntPoint &aDestination) MOZ_OVERRIDE;
 
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
-                        const DrawOptions &aOptions = DrawOptions());
+                        const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void StrokeRect(const Rect &aRect,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void StrokeLine(const Point &aStart,
                           const Point &aEnd,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void Stroke(const Path *aPath,
                       const Pattern &aPattern,
                       const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                      const DrawOptions &aOptions = DrawOptions());
+                      const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void Fill(const Path *aPath,
                     const Pattern &aPattern,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions,
-                          const GlyphRenderingOptions *aRenderingOptions = nullptr);
+                          const GlyphRenderingOptions *aRenderingOptions = nullptr) MOZ_OVERRIDE;
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
-  virtual void PushClip(const Path *aPath);
-  virtual void PushClipRect(const Rect &aRect);
-  virtual void PopClip();
+  virtual void PushClip(const Path *aPath) MOZ_OVERRIDE;
+  virtual void PushClipRect(const Rect &aRect) MOZ_OVERRIDE;
+  virtual void PopClip() MOZ_OVERRIDE;
 
-  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const;
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const MOZ_OVERRIDE;
 
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
-                                                            SurfaceFormat aFormat) const;
-  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+                                                            SurfaceFormat aFormat) const MOZ_OVERRIDE;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE;
   virtual TemporaryRef<SourceSurface>
-    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const MOZ_OVERRIDE;
   virtual TemporaryRef<DrawTarget>
-    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const MOZ_OVERRIDE;
   virtual TemporaryRef<DrawTarget>
     CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
-                           float aSigma) const;
+                           float aSigma) const MOZ_OVERRIDE;
 
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
-                        ExtendMode aExtendMode = ExtendMode::CLAMP) const;
+                        ExtendMode aExtendMode = ExtendMode::CLAMP) const MOZ_OVERRIDE;
 
-  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) MOZ_OVERRIDE;
 
-  virtual void *GetNativeSurface(NativeSurfaceType aType);
+  virtual void *GetNativeSurface(NativeSurfaceType aType) MOZ_OVERRIDE;
 
   bool Init(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
   bool Init(const IntSize& aSize, SurfaceFormat aFormat);
   bool Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
 
-  virtual void SetTransform(const Matrix& aTransform);
+  virtual void SetTransform(const Matrix& aTransform) MOZ_OVERRIDE;
 
   // Call to set up aContext for drawing (with the current transform, etc).
   // Pass the path you're going to be using if you have one.
   // Implicitly calls WillChange(aPath).
   void PrepareForDrawing(cairo_t* aContext, const Path* aPath = nullptr);
 
   static cairo_surface_t *GetDummySurface();
 
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -1,34 +1,30 @@
 /* -*- 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 <initguid.h>
 #include "DrawTargetD2D.h"
 #include "SourceSurfaceD2D.h"
-#ifdef USE_D2D1_1
 #include "SourceSurfaceD2D1.h"
-#endif
 #include "SourceSurfaceD2DTarget.h"
 #include "ShadersD2D.h"
 #include "PathD2D.h"
 #include "GradientStopsD2D.h"
 #include "ScaledFontDWrite.h"
 #include "ImageScaling.h"
 #include "Logging.h"
 #include "Tools.h"
 #include <algorithm>
 #include "mozilla/Constants.h"
 #include "FilterNodeSoftware.h"
 
-#ifdef USE_D2D1_1
 #include "FilterNodeD2D1.h"
-#endif
 
 #include <dwrite.h>
 
 // decltype is not usable for overloaded functions.
 typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
     D2D1_FACTORY_TYPE factoryType,
     REFIID iid,
     CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
@@ -318,28 +314,26 @@ DrawTargetD2D::GetBitmapForSurface(Sourc
       aSource.y -= (uint32_t)aSource.y;
     }
     break;
   }
 
   return bitmap;
 }
 
-#ifdef USE_D2D1_1
 TemporaryRef<ID2D1Image>
 DrawTargetD2D::GetImageForSurface(SourceSurface *aSurface)
 {
   RefPtr<ID2D1Image> image;
 
   Rect r(Point(), Size(aSurface->GetSize()));
   image = GetBitmapForSurface(aSurface, r);
 
   return image;
 }
-#endif
 
 void
 DrawTargetD2D::DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions,
                            const DrawOptions &aOptions)
 {
@@ -364,17 +358,16 @@ DrawTargetD2D::DrawSurface(SourceSurface
 }
 
 void
 DrawTargetD2D::DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
                           const DrawOptions &aOptions)
 {
-#ifdef USE_D2D1_1
   RefPtr<ID2D1DeviceContext> dc;
   HRESULT hr;
   
   hr = mRT->QueryInterface((ID2D1DeviceContext**)byRef(dc));
 
   if (SUCCEEDED(hr) && aNode->GetBackendType() == FILTER_BACKEND_DIRECT2D1_1) {
     ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, ColorPattern(Color()));
   
@@ -390,17 +383,16 @@ DrawTargetD2D::DrawFilter(FilterNode *aN
       dc->DrawImage(node->OutputEffect(), D2DPoint(aDestPoint), D2DRect(aSourceRect));
 
       Rect destRect = aSourceRect;
       destRect.MoveBy(aDestPoint);
       FinalizeRTForOperation(aOptions.mCompositionOp, ColorPattern(Color()), destRect);
       return;
     }
   }
-#endif
 
   if (aNode->GetBackendType() != FILTER_BACKEND_SOFTWARE) {
     gfxWarning() << "Invalid filter backend passed to DrawTargetD2D!";
     return;
   }
 
   FilterNodeSoftware* filter = static_cast<FilterNodeSoftware*>(aNode);
   filter->Draw(this, aSourceRect, aDestPoint, aOptions);
@@ -1309,24 +1301,22 @@ DrawTargetD2D::CreateGradientStops(Gradi
   }
 
   return new GradientStopsD2D(stopCollection);
 }
 
 TemporaryRef<FilterNode>
 DrawTargetD2D::CreateFilter(FilterType aType)
 {
-#ifdef USE_D2D1_1
   RefPtr<ID2D1DeviceContext> dc;
   HRESULT hr = mRT->QueryInterface((ID2D1DeviceContext**)byRef(dc));
 
   if (SUCCEEDED(hr)) {
     return FilterNodeD2D1::Create(dc, aType);
   }
-#endif
   return FilterNodeSoftware::Create(aType);
 }
 
 void*
 DrawTargetD2D::GetNativeSurface(NativeSurfaceType aType)
 {
   if (aType != NativeSurfaceType::D3D10_TEXTURE) {
     return nullptr;
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -137,19 +137,17 @@ public:
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   bool InitD3D10Data();
   uint32_t GetByteSize() const;
   TemporaryRef<ID2D1Layer> GetCachedLayer();
   void PopCachedLayer(ID2D1RenderTarget *aRT);
 
-#ifdef USE_D2D1_1
   TemporaryRef<ID2D1Image> GetImageForSurface(SourceSurface *aSurface);
-#endif
 
   static ID2D1Factory *factory();
   static void CleanupD2D();
   static IDWriteFactory *GetDWriteFactory();
   ID2D1RenderTarget *GetRT() { return mRT; }
 
   operator std::string() const {
     std::stringstream stream;
--- a/gfx/2d/DrawTargetDual.h
+++ b/gfx/2d/DrawTargetDual.h
@@ -13,148 +13,148 @@
      
 #include "2D.h"
 #include "Filters.h"
      
 namespace mozilla {
 namespace gfx {
      
 #define FORWARD_FUNCTION(funcName) \
-  virtual void funcName() { mA->funcName(); mB->funcName(); }
+  virtual void funcName() MOZ_OVERRIDE { mA->funcName(); mB->funcName(); }
 #define FORWARD_FUNCTION1(funcName, var1Type, var1Name) \
-  virtual void funcName(var1Type var1Name) { mA->funcName(var1Name); mB->funcName(var1Name); }
+  virtual void funcName(var1Type var1Name) MOZ_OVERRIDE { mA->funcName(var1Name); mB->funcName(var1Name); }
 
 /* This is a special type of DrawTarget. It duplicates all drawing calls
  * accross two drawtargets. An exception to this is when a snapshot of another
  * dual DrawTarget is used as the source for any surface data. In this case
  * the snapshot of the first source DrawTarget is used as a source for the call
  * to the first destination DrawTarget (mA) and the snapshot of the second
  * source DrawTarget is used at the source for the second destination
  * DrawTarget (mB). This class facilitates black-background/white-background
  * drawing for per-component alpha extraction for backends which do not support
  * native component alpha.
  */
 class DrawTargetDual : public DrawTarget
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetDual)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetDual, MOZ_OVERRIDE)
   DrawTargetDual(DrawTarget *aA, DrawTarget *aB)
     : mA(aA)
     , mB(aB)
   { 
     mFormat = aA->GetFormat();
   }
      
   virtual DrawTargetType GetType() const MOZ_OVERRIDE { return mA->GetType(); }
-  virtual BackendType GetBackendType() const { return mA->GetBackendType(); }
-  virtual TemporaryRef<SourceSurface> Snapshot() { return new SourceSurfaceDual(mA, mB); }
-  virtual IntSize GetSize() { return mA->GetSize(); }
+  virtual BackendType GetBackendType() const MOZ_OVERRIDE { return mA->GetBackendType(); }
+  virtual TemporaryRef<SourceSurface> Snapshot() MOZ_OVERRIDE { return new SourceSurfaceDual(mA, mB); }
+  virtual IntSize GetSize() MOZ_OVERRIDE { return mA->GetSize(); }
      
   FORWARD_FUNCTION(Flush)
   FORWARD_FUNCTION1(PushClip, const Path *, aPath)
   FORWARD_FUNCTION1(PushClipRect, const Rect &, aRect)
   FORWARD_FUNCTION(PopClip)
   FORWARD_FUNCTION1(ClearRect, const Rect &, aRect)
 
-  virtual void SetTransform(const Matrix &aTransform) {
+  virtual void SetTransform(const Matrix &aTransform) MOZ_OVERRIDE {
     mTransform = aTransform;
     mA->SetTransform(aTransform);
     mB->SetTransform(aTransform);
   }
 
   virtual void DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect & aSource,
-                           const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions);
+                           const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions) MOZ_OVERRIDE;
 
   virtual void DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
-                          const DrawOptions &aOptions = DrawOptions())
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE
   {
     mA->DrawFilter(aNode, aSourceRect, aDestPoint, aOptions);
     mB->DrawFilter(aNode, aSourceRect, aDestPoint, aOptions);
   }
 
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
                                      const Color &aColor, const Point &aOffset,
-                                     Float aSigma, CompositionOp aOp);
+                                     Float aSigma, CompositionOp aOp) MOZ_OVERRIDE;
 
   virtual void CopySurface(SourceSurface *aSurface, const IntRect &aSourceRect,
-                           const IntPoint &aDestination);
+                           const IntPoint &aDestination) MOZ_OVERRIDE;
 
-  virtual void FillRect(const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions);
+  virtual void FillRect(const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions) MOZ_OVERRIDE;
 
   virtual void StrokeRect(const Rect &aRect, const Pattern &aPattern,
-                          const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions);
+                          const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) MOZ_OVERRIDE;
 
   virtual void StrokeLine(const Point &aStart, const Point &aEnd, const Pattern &aPattern,
-                          const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions);
+                          const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) MOZ_OVERRIDE;
 
   virtual void Stroke(const Path *aPath, const Pattern &aPattern,
-                      const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions);
+                      const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) MOZ_OVERRIDE;
 
-  virtual void Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions);
+  virtual void Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions) MOZ_OVERRIDE;
 
   virtual void FillGlyphs(ScaledFont *aScaledFont, const GlyphBuffer &aBuffer,
                           const Pattern &aPattern, const DrawOptions &aOptions,
-                          const GlyphRenderingOptions *aRenderingOptions);
+                          const GlyphRenderingOptions *aRenderingOptions) MOZ_OVERRIDE;
   
-  virtual void Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions);
+  virtual void Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions) MOZ_OVERRIDE;
      
   virtual TemporaryRef<SourceSurface>
     CreateSourceSurfaceFromData(unsigned char *aData,
                                 const IntSize &aSize,
                                 int32_t aStride,
-                                SurfaceFormat aFormat) const
+                                SurfaceFormat aFormat) const MOZ_OVERRIDE
   {
     return mA->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
   }
      
-  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE
   {
     return mA->OptimizeSourceSurface(aSurface);
   }
      
   virtual TemporaryRef<SourceSurface>
-    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const MOZ_OVERRIDE
   {
     return mA->CreateSourceSurfaceFromNativeSurface(aSurface);
   }
      
   virtual TemporaryRef<DrawTarget>
-    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const MOZ_OVERRIDE;
      
-  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const MOZ_OVERRIDE
   {
     return mA->CreatePathBuilder(aFillRule);
   }
      
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
-                        ExtendMode aExtendMode = ExtendMode::CLAMP) const
+                        ExtendMode aExtendMode = ExtendMode::CLAMP) const MOZ_OVERRIDE
   {
     return mA->CreateGradientStops(aStops, aNumStops, aExtendMode);
   }
 
-  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType)
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) MOZ_OVERRIDE
   {
     return mA->CreateFilter(aType);
   }
 
-  virtual void *GetNativeSurface(NativeSurfaceType aType)
+  virtual void *GetNativeSurface(NativeSurfaceType aType) MOZ_OVERRIDE
   {
     return nullptr;
   }
 
-  virtual bool IsDualDrawTarget() const
+  virtual bool IsDualDrawTarget() const MOZ_OVERRIDE
   {
     return true;
   }
      
 private:
   RefPtr<DrawTarget> mA;
   RefPtr<DrawTarget> mB;
 };
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -75,50 +75,50 @@ GetGradientStops(GradientStops *aStops)
   }
 
   return static_cast<GradientStopsRecording*>(aStops)->mFinalGradientStops;
 }
 
 class FilterNodeRecording : public FilterNode
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording, MOZ_OVERRIDE)
   using FilterNode::SetAttribute;
 
   FilterNodeRecording(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder)
     : mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder)
   {
   }
 
   ~FilterNodeRecording()
   {
     mRecorder->RecordEvent(RecordedFilterNodeDestruction(this));
   }
 
-  virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface)
+  virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) MOZ_OVERRIDE
   {
     mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface));
     mFinalFilterNode->SetInput(aIndex, GetSourceSurface(aSurface));
   }
-  virtual void SetInput(uint32_t aIndex, FilterNode *aFilter)
+  virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) MOZ_OVERRIDE
   {
     FilterNode *finalNode = aFilter;
     if (aFilter->GetBackendType() != FILTER_BACKEND_RECORDING) {
       gfxWarning() << "Non recording filter node used with recording DrawTarget!";
     } else {
       finalNode = static_cast<FilterNodeRecording*>(aFilter)->mFinalFilterNode;
     }
 
     mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter));
     mFinalFilterNode->SetInput(aIndex, finalNode);
   }
 
 
 #define FORWARD_SET_ATTRIBUTE(type, argtype) \
-  virtual void SetAttribute(uint32_t aIndex, type aValue) { \
+  virtual void SetAttribute(uint32_t aIndex, type aValue) MOZ_OVERRIDE { \
     mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \
     mFinalFilterNode->SetAttribute(aIndex, aValue); \
   }
 
   FORWARD_SET_ATTRIBUTE(bool, BOOL);
   FORWARD_SET_ATTRIBUTE(uint32_t, UINT32);
   FORWARD_SET_ATTRIBUTE(Float, FLOAT);
   FORWARD_SET_ATTRIBUTE(const Size&, SIZE);
@@ -128,17 +128,17 @@ public:
   FORWARD_SET_ATTRIBUTE(const IntRect&, INTRECT);
   FORWARD_SET_ATTRIBUTE(const Point&, POINT);
   FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4);
   FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D);
   FORWARD_SET_ATTRIBUTE(const Color&, COLOR);
 
 #undef FORWARD_SET_ATTRIBUTE
 
-  virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) {
+  virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE {
     mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize));
     mFinalFilterNode->SetAttribute(aIndex, aFloat, aSize);
   }
 
   virtual FilterBackend GetBackendType() MOZ_OVERRIDE { return FILTER_BACKEND_RECORDING; }
 
   RefPtr<FilterNode> mFinalFilterNode;
   RefPtr<DrawEventRecorderPrivate> mRecorder;
--- a/gfx/2d/DrawTargetRecording.h
+++ b/gfx/2d/DrawTargetRecording.h
@@ -10,54 +10,54 @@
 #include "DrawEventRecorder.h"
 
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetRecording : public DrawTarget
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording, MOZ_OVERRIDE)
   DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData = false);
   ~DrawTargetRecording();
 
   virtual DrawTargetType GetType() const MOZ_OVERRIDE { return mFinalDT->GetType(); }
-  virtual BackendType GetBackendType() const { return mFinalDT->GetBackendType(); }
+  virtual BackendType GetBackendType() const MOZ_OVERRIDE { return mFinalDT->GetBackendType(); }
 
-  virtual TemporaryRef<SourceSurface> Snapshot();
+  virtual TemporaryRef<SourceSurface> Snapshot() MOZ_OVERRIDE;
 
-  virtual IntSize GetSize() { return mFinalDT->GetSize(); }
+  virtual IntSize GetSize() MOZ_OVERRIDE { return mFinalDT->GetSize(); }
 
   /* Ensure that the DrawTarget backend has flushed all drawing operations to
    * this draw target. This must be called before using the backing surface of
    * this draw target outside of GFX 2D code.
    */
-  virtual void Flush() { mFinalDT->Flush(); }
+  virtual void Flush() MOZ_OVERRIDE { mFinalDT->Flush(); }
 
   /*
    * Draw a surface to the draw target. Possibly doing partial drawing or
    * applying scaling. No sampling happens outside the source.
    *
    * aSurface Source surface to draw
    * aDest Destination rectangle that this drawing operation should draw to
    * aSource Source rectangle in aSurface coordinates, this area of aSurface
    *         will be stretched to the size of aDest.
    * aOptions General draw options that are applied to the operation
    * aSurfOptions DrawSurface options that are applied
    */
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   /*
    * Blend a surface to the draw target with a shadow. The shadow is drawn as a
    * gaussian blur using a specified sigma. The shadow is clipped to the size
    * of the input surface, so the input surface should contain a transparent
    * border the size of the approximate coverage of the blur (3 * aSigma).
    * NOTE: This function works in device space!
    *
@@ -68,215 +68,215 @@ public:
    * aSigma Sigma used for the guassian filter kernel
    * aOperator Composition operator used
    */
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
-                                     CompositionOp aOperator);
+                                     CompositionOp aOperator) MOZ_OVERRIDE;
 
   /* 
    * Clear a rectangle on the draw target to transparent black. This will
    * respect the clipping region and transform.
    *
    * aRect Rectangle to clear
    */
-  virtual void ClearRect(const Rect &aRect);
+  virtual void ClearRect(const Rect &aRect) MOZ_OVERRIDE;
 
   /*
    * This is essentially a 'memcpy' between two surfaces. It moves a pixel
    * aligned area from the source surface unscaled directly onto the
    * drawtarget. This ignores both transform and clip.
    *
    * aSurface Surface to copy from
    * aSourceRect Source rectangle to be copied
    * aDest Destination point to copy the surface to
    */
   virtual void CopySurface(SourceSurface *aSurface,
                            const IntRect &aSourceRect,
-                           const IntPoint &aDestination);
+                           const IntPoint &aDestination) MOZ_OVERRIDE;
 
   /*
    * Fill a rectangle on the DrawTarget with a certain source pattern.
    *
    * aRect Rectangle that forms the mask of this filling operation
    * aPattern Pattern that forms the source of this filling operation
    * aOptions Options that are applied to this operation
    */
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
-                        const DrawOptions &aOptions = DrawOptions());
+                        const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   /*
    * Stroke a rectangle on the DrawTarget with a certain source pattern.
    *
    * aRect Rectangle that forms the mask of this stroking operation
    * aPattern Pattern that forms the source of this stroking operation
    * aOptions Options that are applied to this operation
    */
   virtual void StrokeRect(const Rect &aRect,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   /*
    * Stroke a line on the DrawTarget with a certain source pattern.
    *
    * aStart Starting point of the line
    * aEnd End point of the line
    * aPattern Pattern that forms the source of this stroking operation
    * aOptions Options that are applied to this operation
    */
   virtual void StrokeLine(const Point &aStart,
                           const Point &aEnd,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   /*
    * Stroke a path on the draw target with a certain source pattern.
    *
    * aPath Path that is to be stroked
    * aPattern Pattern that should be used for the stroke
    * aStrokeOptions Stroke options used for this operation
    * aOptions Draw options used for this operation
    */
   virtual void Stroke(const Path *aPath,
                       const Pattern &aPattern,
                       const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                      const DrawOptions &aOptions = DrawOptions());
+                      const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   
   /*
    * Fill a path on the draw target with a certain source pattern.
    *
    * aPath Path that is to be filled
    * aPattern Pattern that should be used for the fill
    * aOptions Draw options used for this operation
    */
   virtual void Fill(const Path *aPath,
                     const Pattern &aPattern,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   /*
    * Fill a series of clyphs on the draw target with a certain source pattern.
    */
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions = DrawOptions(),
-                          const GlyphRenderingOptions *aRenderingOptions = nullptr);
+                          const GlyphRenderingOptions *aRenderingOptions = nullptr) MOZ_OVERRIDE;
 
   /*
    * This takes a source pattern and a mask, and composites the source pattern
    * onto the destination surface using the alpha channel of the mask pattern
    * as a mask for the operation.
    *
    * aSource Source pattern
    * aMask Mask pattern
    * aOptions Drawing options
    */
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   /*
    * Push a clip to the DrawTarget.
    *
    * aPath The path to clip to
    */
-  virtual void PushClip(const Path *aPath);
+  virtual void PushClip(const Path *aPath) MOZ_OVERRIDE;
 
   /*
    * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
    * is specified in user space.
    *
    * aRect The rect to clip to
    */
-  virtual void PushClipRect(const Rect &aRect);
+  virtual void PushClipRect(const Rect &aRect) MOZ_OVERRIDE;
 
   /* Pop a clip from the DrawTarget. A pop without a corresponding push will
    * be ignored.
    */
-  virtual void PopClip();
+  virtual void PopClip() MOZ_OVERRIDE;
 
   /*
    * Create a SourceSurface optimized for use with this DrawTarget from
    * existing bitmap data in memory.
    *
    * The SourceSurface does not take ownership of aData, and may be freed at any time.
    */
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                                   const IntSize &aSize,
                                                                   int32_t aStride,
-                                                                  SurfaceFormat aFormat) const;
+                                                                  SurfaceFormat aFormat) const MOZ_OVERRIDE;
 
   /*
    * Create a SourceSurface optimized for use with this DrawTarget from
    * an arbitrary other SourceSurface. This may return aSourceSurface or some
    * other existing surface.
    */
-  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE;
 
   /*
    * Create a SourceSurface for a type of NativeSurface. This may fail if the
    * draw target does not know how to deal with the type of NativeSurface passed
    * in.
    */
   virtual TemporaryRef<SourceSurface>
-    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const MOZ_OVERRIDE;
 
   /*
    * Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
    */
   virtual TemporaryRef<DrawTarget>
-    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const MOZ_OVERRIDE;
 
   /*
    * Create a path builder with the specified fillmode.
    *
    * We need the fill mode up front because of Direct2D.
    * ID2D1SimplifiedGeometrySink requires the fill mode
    * to be set before calling BeginFigure().
    */
-  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const;
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const MOZ_OVERRIDE;
 
   /*
    * Create a GradientStops object that holds information about a set of
    * gradient stops, this object is required for linear or radial gradient
    * patterns to represent the color stops in the gradient.
    *
    * aStops An array of gradient stops
    * aNumStops Number of stops in the array aStops
    * aExtendNone This describes how to extend the stop color outside of the
    *             gradient area.
    */
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
-                        ExtendMode aExtendMode = ExtendMode::CLAMP) const;
+                        ExtendMode aExtendMode = ExtendMode::CLAMP) const MOZ_OVERRIDE;
 
-  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) MOZ_OVERRIDE;
 
   /*
    * Set a transform on the surface, this transform is applied at drawing time
    * to both the mask and source of the operation.
    */
-  virtual void SetTransform(const Matrix &aTransform);
+  virtual void SetTransform(const Matrix &aTransform) MOZ_OVERRIDE;
 
   /* Tries to get a native surface for a DrawTarget, this may fail if the
    * draw target cannot convert to this surface type.
    */
-  virtual void *GetNativeSurface(NativeSurfaceType aType) { return mFinalDT->GetNativeSurface(aType); }
+  virtual void *GetNativeSurface(NativeSurfaceType aType) MOZ_OVERRIDE { return mFinalDT->GetNativeSurface(aType); }
 
 private:
   Path *GetPathForPathRecording(const Path *aPath) const;
   void EnsureStored(const Path *aPath);
 
   RefPtr<DrawEventRecorderPrivate> mRecorder;
   RefPtr<DrawTarget> mFinalDT;
 };
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -23,92 +23,92 @@
 namespace mozilla {
 namespace gfx {
 
 class SourceSurfaceSkia;
 
 class DrawTargetSkia : public DrawTarget
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetSkia)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetSkia, MOZ_OVERRIDE)
   DrawTargetSkia();
   virtual ~DrawTargetSkia();
 
   virtual DrawTargetType GetType() const MOZ_OVERRIDE;
-  virtual BackendType GetBackendType() const { return BackendType::SKIA; }
-  virtual TemporaryRef<SourceSurface> Snapshot();
-  virtual IntSize GetSize() { return mSize; }
-  virtual void Flush();
+  virtual BackendType GetBackendType() const MOZ_OVERRIDE { return BackendType::SKIA; }
+  virtual TemporaryRef<SourceSurface> Snapshot() MOZ_OVERRIDE;
+  virtual IntSize GetSize() MOZ_OVERRIDE { return mSize; }
+  virtual void Flush() MOZ_OVERRIDE;
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
-                                     CompositionOp aOperator);
-  virtual void ClearRect(const Rect &aRect);
+                                     CompositionOp aOperator) MOZ_OVERRIDE;
+  virtual void ClearRect(const Rect &aRect) MOZ_OVERRIDE;
   virtual void CopySurface(SourceSurface *aSurface,
                            const IntRect &aSourceRect,
-                           const IntPoint &aDestination);
+                           const IntPoint &aDestination) MOZ_OVERRIDE;
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
-                        const DrawOptions &aOptions = DrawOptions());
+                        const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void StrokeRect(const Rect &aRect,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void StrokeLine(const Point &aStart,
                           const Point &aEnd,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void Stroke(const Path *aPath,
                       const Pattern &aPattern,
                       const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                      const DrawOptions &aOptions = DrawOptions());
+                      const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void Fill(const Path *aPath,
                     const Pattern &aPattern,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions = DrawOptions(),
-                          const GlyphRenderingOptions *aRenderingOptions = nullptr);
+                          const GlyphRenderingOptions *aRenderingOptions = nullptr) MOZ_OVERRIDE;
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions());
-  virtual void PushClip(const Path *aPath);
-  virtual void PushClipRect(const Rect& aRect);
-  virtual void PopClip();
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
+  virtual void PushClip(const Path *aPath) MOZ_OVERRIDE;
+  virtual void PushClipRect(const Rect& aRect) MOZ_OVERRIDE;
+  virtual void PopClip() MOZ_OVERRIDE;
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
-                                                            SurfaceFormat aFormat) const;
-  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
+                                                            SurfaceFormat aFormat) const MOZ_OVERRIDE;
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE;
   virtual TemporaryRef<SourceSurface>
-    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const MOZ_OVERRIDE;
   virtual TemporaryRef<DrawTarget>
-    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
-  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const;
-  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = ExtendMode::CLAMP) const;
-  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
-  virtual void SetTransform(const Matrix &aTransform);
-  virtual void *GetNativeSurface(NativeSurfaceType aType);
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const MOZ_OVERRIDE;
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const MOZ_OVERRIDE;
+  virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = ExtendMode::CLAMP) const MOZ_OVERRIDE;
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) MOZ_OVERRIDE;
+  virtual void SetTransform(const Matrix &aTransform) MOZ_OVERRIDE;
+  virtual void *GetNativeSurface(NativeSurfaceType aType) MOZ_OVERRIDE;
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
 
 #ifdef USE_SKIA_GPU
   bool InitWithGrContext(GrContext* aGrContext,
                          const IntSize &aSize,
                          SurfaceFormat aFormat) MOZ_OVERRIDE;
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -30,123 +30,123 @@ struct TileInternal : public Tile {
 
 class DrawTargetTiled : public DrawTarget
 {
 public:
   DrawTargetTiled();
 
   bool Init(const TileSet& mTiles);
 
-  virtual bool IsTiledDrawTarget() const { return true; }
+  virtual bool IsTiledDrawTarget() const MOZ_OVERRIDE { return true; }
 
   virtual DrawTargetType GetType() const MOZ_OVERRIDE { return mTiles[0].mDrawTarget->GetType(); }
-  virtual BackendType GetBackendType() const { return mTiles[0].mDrawTarget->GetBackendType(); }
-  virtual TemporaryRef<SourceSurface> Snapshot();
-  virtual IntSize GetSize() {
+  virtual BackendType GetBackendType() const MOZ_OVERRIDE { return mTiles[0].mDrawTarget->GetBackendType(); }
+  virtual TemporaryRef<SourceSurface> Snapshot() MOZ_OVERRIDE;
+  virtual IntSize GetSize() MOZ_OVERRIDE {
     MOZ_ASSERT(mRect.width > 0 && mRect.height > 0);
     return IntSize(mRect.XMost(), mRect.YMost());
   }
 
-  virtual void Flush();
+  virtual void Flush() MOZ_OVERRIDE;
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions,
-                           const DrawOptions &aOptions);
+                           const DrawOptions &aOptions) MOZ_OVERRIDE;
   virtual void DrawFilter(FilterNode *aNode,
                           const Rect &aSourceRect,
                           const Point &aDestPoint,
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
-                                     CompositionOp aOperator) { /* Not implemented */ MOZ_CRASH(); }
+                                     CompositionOp aOperator) MOZ_OVERRIDE { /* Not implemented */ MOZ_CRASH(); }
 
-  virtual void ClearRect(const Rect &aRect);
+  virtual void ClearRect(const Rect &aRect) MOZ_OVERRIDE;
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
-                           const DrawOptions &aOptions = DrawOptions());
+                           const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
 
   virtual void CopySurface(SourceSurface *aSurface,
                            const IntRect &aSourceRect,
-                           const IntPoint &aDestination);
+                           const IntPoint &aDestination) MOZ_OVERRIDE;
 
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
-                        const DrawOptions &aOptions = DrawOptions());
+                        const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void StrokeRect(const Rect &aRect,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void StrokeLine(const Point &aStart,
                           const Point &aEnd,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                          const DrawOptions &aOptions = DrawOptions());
+                          const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void Stroke(const Path *aPath,
                       const Pattern &aPattern,
                       const StrokeOptions &aStrokeOptions = StrokeOptions(),
-                      const DrawOptions &aOptions = DrawOptions());
+                      const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void Fill(const Path *aPath,
                     const Pattern &aPattern,
-                    const DrawOptions &aOptions = DrawOptions());
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
   virtual void FillGlyphs(ScaledFont *aFont,
                           const GlyphBuffer &aBuffer,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions = DrawOptions(),
-                          const GlyphRenderingOptions *aRenderingOptions = nullptr);
+                          const GlyphRenderingOptions *aRenderingOptions = nullptr) MOZ_OVERRIDE;
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
-                    const DrawOptions &aOptions = DrawOptions());
-  virtual void PushClip(const Path *aPath);
-  virtual void PushClipRect(const Rect &aRect);
-  virtual void PopClip();
+                    const DrawOptions &aOptions = DrawOptions()) MOZ_OVERRIDE;
+  virtual void PushClip(const Path *aPath) MOZ_OVERRIDE;
+  virtual void PushClipRect(const Rect &aRect) MOZ_OVERRIDE;
+  virtual void PopClip() MOZ_OVERRIDE;
 
-  virtual void SetTransform(const Matrix &aTransform);
+  virtual void SetTransform(const Matrix &aTransform) MOZ_OVERRIDE;
 
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                                   const IntSize &aSize,
                                                                   int32_t aStride,
-                                                                  SurfaceFormat aFormat) const
+                                                                  SurfaceFormat aFormat) const MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
   }
-  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const
+  virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->OptimizeSourceSurface(aSurface);
   }
 
   virtual TemporaryRef<SourceSurface>
-    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
+    CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->CreateSourceSurfaceFromNativeSurface(aSurface);
   }
 
   virtual TemporaryRef<DrawTarget>
-    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
+    CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->CreateSimilarDrawTarget(aSize, aFormat);
   }
 
-  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const
+  virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->CreatePathBuilder(aFillRule);
   }
 
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
-                        ExtendMode aExtendMode = ExtendMode::CLAMP) const
+                        ExtendMode aExtendMode = ExtendMode::CLAMP) const MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->CreateGradientStops(aStops, aNumStops, aExtendMode);
   }
-  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType)
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) MOZ_OVERRIDE
   {
     return mTiles[0].mDrawTarget->CreateFilter(aType);
   }
 
 private:
   std::vector<TileInternal> mTiles;
   std::vector<std::vector<uint32_t> > mClippedOutTilesStack;
   IntRect mRect;
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -29,19 +29,17 @@
 
 
 #ifdef XP_MACOSX
 #include "DrawTargetCG.h"
 #endif
 
 #ifdef WIN32
 #include "DrawTargetD2D.h"
-#ifdef USE_D2D1_1
 #include "DrawTargetD2D1.h"
-#endif
 #include "ScaledFontDWrite.h"
 #include <d3d10_1.h>
 #include "HelpersD2D.h"
 #endif
 
 #include "DrawTargetDual.h"
 #include "DrawTargetTiled.h"
 #include "DrawTargetRecording.h"
@@ -179,21 +177,19 @@ void PreferenceAccess::SetAccess(Prefere
   if (sAccess) {
     RegisterAll();
   }
 }
 
 
 #ifdef WIN32
 ID3D10Device1 *Factory::mD3D10Device;
-#ifdef USE_D2D1_1
 ID3D11Device *Factory::mD3D11Device;
 ID2D1Device *Factory::mD2D1Device;
 #endif
-#endif
 
 DrawEventRecorder *Factory::mRecorder;
 
 bool
 Factory::HasSSE2()
 {
 #if defined(__SSE2__) || defined(_M_X64) || \
     (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
@@ -289,27 +285,25 @@ Factory::CreateDrawTarget(BackendType aB
     {
       RefPtr<DrawTargetD2D> newTarget;
       newTarget = new DrawTargetD2D();
       if (newTarget->Init(aSize, aFormat)) {
         retVal = newTarget;
       }
       break;
     }
-#ifdef USE_D2D1_1
   case BackendType::DIRECT2D1_1:
     {
       RefPtr<DrawTargetD2D1> newTarget;
       newTarget = new DrawTargetD2D1();
       if (newTarget->Init(aSize, aFormat)) {
         retVal = newTarget;
       }
       break;
     }
-#endif
 #elif defined XP_MACOSX
   case BackendType::COREGRAPHICS:
   case BackendType::COREGRAPHICS_ACCELERATED:
     {
       RefPtr<DrawTargetCG> newTarget;
       newTarget = new DrawTargetCG();
       if (newTarget->Init(aBackend, aSize, aFormat)) {
         retVal = newTarget;
@@ -597,17 +591,16 @@ Factory::GetDirect3D10Device()
   if (mD3D10Device) {
     UINT mode = mD3D10Device->GetExceptionMode();
     MOZ_ASSERT(0 == mode);
   }
 #endif
   return mD3D10Device;
 }
 
-#ifdef USE_D2D1_1
 TemporaryRef<DrawTarget>
 Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat)
 {
   MOZ_ASSERT(aTexture);
 
   RefPtr<DrawTargetD2D1> newTarget;
 
   newTarget = new DrawTargetD2D1();
@@ -656,17 +649,16 @@ Factory::GetD2D1Device()
   return mD2D1Device;
 }
 
 bool
 Factory::SupportsD2D1()
 {
   return !!D2DFactory1();
 }
-#endif
 
 TemporaryRef<GlyphRenderingOptions>
 Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams)
 {
   return new GlyphRenderingOptionsDWrite(aParams);
 }
 
 uint64_t
@@ -679,23 +671,21 @@ uint64_t
 Factory::GetD2DVRAMUsageSourceSurface()
 {
   return DrawTargetD2D::mVRAMUsageSS;
 }
 
 void
 Factory::D2DCleanup()
 {
-#ifdef USE_D2D1_1
   if (mD2D1Device) {
     mD2D1Device->Release();
     mD2D1Device = nullptr;
   }
   DrawTargetD2D1::CleanupD2D();
-#endif
   DrawTargetD2D::CleanupD2D();
 }
 
 #endif // XP_WIN
 
 #ifdef USE_SKIA_GPU
 TemporaryRef<DrawTarget>
 Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
--- a/gfx/2d/FilterNodeSoftware.h
+++ b/gfx/2d/FilterNodeSoftware.h
@@ -33,17 +33,17 @@ public:
  * This is the base class for the software (i.e. pure CPU, non-accelerated)
  * FilterNode implementation. The software implementation is backend-agnostic,
  * so it can be used as a fallback for all DrawTarget implementations.
  */
 class FilterNodeSoftware : public FilterNode,
                            public FilterInvalidationListener
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeSoftware, MOZ_OVERRIDE)
   virtual ~FilterNodeSoftware();
 
   // Factory method, intended to be called from DrawTarget*::CreateFilter.
   static TemporaryRef<FilterNode> Create(FilterType aType);
 
   // Draw the filter, intended to be called by DrawTarget*::DrawFilter.
   void Draw(DrawTarget* aDrawTarget, const Rect &aSourceRect,
             const Point &aDestPoint, const DrawOptions &aOptions);
@@ -53,17 +53,17 @@ public:
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) MOZ_OVERRIDE;
 
   virtual const char* GetName() { return "Unknown"; }
 
   virtual void AddInvalidationListener(FilterInvalidationListener* aListener);
   virtual void RemoveInvalidationListener(FilterInvalidationListener* aListener);
 
   // FilterInvalidationListener implementation
-  virtual void FilterInvalidated(FilterNodeSoftware* aFilter);
+  virtual void FilterInvalidated(FilterNodeSoftware* aFilter) MOZ_OVERRIDE;
 
 protected:
 
   // The following methods are intended to be overriden by subclasses.
 
   /**
    * Translates a *FilterInputs enum value into an index for the
    * mInputFilters / mInputSurfaces arrays. Returns -1 for invalid inputs.
@@ -213,17 +213,17 @@ protected:
   RefPtr<DataSourceSurface> mCachedOutput;
 };
 
 // Subclasses for specific filters.
 
 class FilterNodeTransformSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTransformSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTransformSoftware, MOZ_OVERRIDE)
   FilterNodeTransformSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Transform"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aGraphicsFilter) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Matrix &aMatrix) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -235,17 +235,17 @@ protected:
 private:
   Matrix mMatrix;
   Filter mFilter;
 };
 
 class FilterNodeBlendSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlendSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlendSoftware, MOZ_OVERRIDE)
   FilterNodeBlendSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Blend"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlendMode) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -254,17 +254,17 @@ protected:
 
 private:
   BlendMode mBlendMode;
 };
 
 class FilterNodeMorphologySoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeMorphologySoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeMorphologySoftware, MOZ_OVERRIDE)
   FilterNodeMorphologySoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Morphology"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aRadii) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -275,17 +275,17 @@ protected:
 private:
   IntSize mRadii;
   MorphologyOperator mOperator;
 };
 
 class FilterNodeColorMatrixSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeColorMatrixSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeColorMatrixSoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "ColorMatrix"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Matrix5x4 &aMatrix) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aAlphaMode) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -295,34 +295,34 @@ protected:
 private:
   Matrix5x4 mMatrix;
   AlphaMode mAlphaMode;
 };
 
 class FilterNodeFloodSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeFloodSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeFloodSoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "Flood"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Color &aColor) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> GetOutput(const IntRect &aRect) MOZ_OVERRIDE;
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
 
 private:
   Color mColor;
 };
 
 class FilterNodeTileSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTileSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTileSoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "Tile"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -333,17 +333,17 @@ private:
 };
 
 /**
  * Baseclass for the four different component transfer filters.
  */
 class FilterNodeComponentTransferSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeComponentTransferSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeComponentTransferSoftware, MOZ_OVERRIDE)
   FilterNodeComponentTransferSoftware();
 
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, bool aDisable) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -357,17 +357,17 @@ protected:
   bool mDisableG;
   bool mDisableB;
   bool mDisableA;
 };
 
 class FilterNodeTableTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTableTransferSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTableTransferSoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "TableTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
@@ -377,17 +377,17 @@ private:
   std::vector<Float> mTableG;
   std::vector<Float> mTableB;
   std::vector<Float> mTableA;
 };
 
 class FilterNodeDiscreteTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDiscreteTransferSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDiscreteTransferSoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "DiscreteTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
@@ -397,17 +397,17 @@ private:
   std::vector<Float> mTableG;
   std::vector<Float> mTableB;
   std::vector<Float> mTableA;
 };
 
 class FilterNodeLinearTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeLinearTransformSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeLinearTransformSoftware, MOZ_OVERRIDE)
   FilterNodeLinearTransferSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "LinearTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
@@ -422,17 +422,17 @@ private:
   Float mInterceptG;
   Float mInterceptB;
   Float mInterceptA;
 };
 
 class FilterNodeGammaTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGammaTransferSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGammaTransferSoftware, MOZ_OVERRIDE)
   FilterNodeGammaTransferSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "GammaTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
@@ -451,17 +451,17 @@ private:
   Float mOffsetG;
   Float mOffsetB;
   Float mOffsetA;
 };
 
 class FilterNodeConvolveMatrixSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeConvolveMatrixSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeConvolveMatrixSoftware, MOZ_OVERRIDE)
   FilterNodeConvolveMatrixSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "ConvolveMatrix"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aKernelSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Float* aMatrix, uint32_t aSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Size &aKernelUnitLength) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) MOZ_OVERRIDE;
@@ -493,17 +493,17 @@ private:
   ConvolveMatrixEdgeMode mEdgeMode;
   Size mKernelUnitLength;
   bool mPreserveAlpha;
 };
 
 class FilterNodeDisplacementMapSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDisplacementMapSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDisplacementMapSoftware, MOZ_OVERRIDE)
   FilterNodeDisplacementMapSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "DisplacementMap"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aScale) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -517,17 +517,17 @@ private:
   Float mScale;
   ColorChannel mChannelX;
   ColorChannel mChannelY;
 };
 
 class FilterNodeTurbulenceSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTurbulenceSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTurbulenceSoftware, MOZ_OVERRIDE)
   FilterNodeTurbulenceSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Turbulence"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Size &aSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aRenderRect) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, bool aStitchable) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) MOZ_OVERRIDE;
 
@@ -543,17 +543,17 @@ private:
   uint32_t mSeed;
   bool mStitchable;
   TurbulenceType mType;
 };
 
 class FilterNodeArithmeticCombineSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeArithmeticCombineSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeArithmeticCombineSoftware, MOZ_OVERRIDE)
   FilterNodeArithmeticCombineSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "ArithmeticCombine"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -565,17 +565,17 @@ private:
   Float mK2;
   Float mK3;
   Float mK4;
 };
 
 class FilterNodeCompositeSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCompositeSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCompositeSoftware, MOZ_OVERRIDE)
   FilterNodeCompositeSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Composite"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -586,48 +586,48 @@ private:
   CompositeOperator mOperator;
 };
 
 // Base class for FilterNodeGaussianBlurSoftware and
 // FilterNodeDirectionalBlurSoftware.
 class FilterNodeBlurXYSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlurXYSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlurXYSoftware, MOZ_OVERRIDE)
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   IntRect InflatedSourceOrDestRect(const IntRect &aDestRect);
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 
   // Implemented by subclasses.
   virtual Size StdDeviationXY() = 0;
 };
 
 class FilterNodeGaussianBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGaussianBlurSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGaussianBlurSoftware, MOZ_OVERRIDE)
   FilterNodeGaussianBlurSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "GaussianBlur"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) MOZ_OVERRIDE;
 
 protected:
   virtual Size StdDeviationXY() MOZ_OVERRIDE;
 
 private:
   Float mStdDeviation;
 };
 
 class FilterNodeDirectionalBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDirectionalBlurSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDirectionalBlurSoftware, MOZ_OVERRIDE)
   FilterNodeDirectionalBlurSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "DirectionalBlur"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlurDirection) MOZ_OVERRIDE;
 
 protected:
   virtual Size StdDeviationXY() MOZ_OVERRIDE;
@@ -635,17 +635,17 @@ protected:
 private:
   Float mStdDeviation;
   BlurDirection mBlurDirection;
 };
 
 class FilterNodeCropSoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCropSoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCropSoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "Crop"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Rect &aSourceRect) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -653,29 +653,29 @@ protected:
 
 private:
   IntRect mCropRect;
 };
 
 class FilterNodePremultiplySoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodePremultiplySoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodePremultiplySoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "Premultiply"; }
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 };
 
 class FilterNodeUnpremultiplySoftware : public FilterNodeSoftware
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeUnpremultiplySoftware)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeUnpremultiplySoftware, MOZ_OVERRIDE)
   virtual const char* GetName() MOZ_OVERRIDE { return "Unpremultiply"; }
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 };
 
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -1,21 +1,17 @@
 /* -*- 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/. */
 
 #ifndef MOZILLA_GFX_HELPERSD2D_H_
 #define MOZILLA_GFX_HELPERSD2D_H_
 
-#ifndef USE_D2D1_1
-#include "moz-d2d1-1.h"
-#else
 #include <d2d1_1.h>
-#endif
 
 #include <vector>
 
 #include <dwrite.h>
 #include "2D.h"
 #include "Logging.h"
 #include "Tools.h"
 #include "ImageScaling.h"
@@ -25,19 +21,17 @@
 #undef min
 #undef max
 
 namespace mozilla {
 namespace gfx {
 
 ID2D1Factory* D2DFactory();
 
-#ifdef USE_D2D1_1
 ID2D1Factory1* D2DFactory1();
-#endif
 
 static inline D2D1_POINT_2F D2DPoint(const Point &aPoint)
 {
   return D2D1::Point2F(aPoint.x, aPoint.y);
 }
 
 static inline D2D1_SIZE_U D2DIntSize(const IntSize &aSize)
 {
@@ -72,17 +66,16 @@ static inline D2D1_BITMAP_INTERPOLATION_
   switch (aFilter) {
   case Filter::POINT:
     return D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
   default:
     return D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
   }
 }
 
-#ifdef USE_D2D1_1
 static inline D2D1_INTERPOLATION_MODE D2DInterpolationMode(const Filter &aFilter)
 {
   switch (aFilter) {
   case Filter::POINT:
     return D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
   default:
     return D2D1_INTERPOLATION_MODE_LINEAR;
   }
@@ -97,18 +90,16 @@ static inline D2D1_MATRIX_5X4_F D2DMatri
                           aMatrix._51, aMatrix._52, aMatrix._53, aMatrix._54);
 }
 
 static inline D2D1_VECTOR_3F D2DVector3D(const Point3D &aPoint)
 {
   return D2D1::Vector3F(aPoint.x, aPoint.y, aPoint.z);
 }
 
-#endif
-
 static inline D2D1_ANTIALIAS_MODE D2DAAMode(AntialiasMode aMode)
 {
   switch (aMode) {
   case AntialiasMode::NONE:
     return D2D1_ANTIALIAS_MODE_ALIASED;
   default:
     return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
   }
@@ -188,17 +179,16 @@ static inline D2D1_ALPHA_MODE D2DAlphaMo
   }
 }
 
 static inline D2D1_PIXEL_FORMAT D2DPixelFormat(SurfaceFormat aFormat)
 {
   return D2D1::PixelFormat(DXGIFormat(aFormat), D2DAlphaModeForFormat(aFormat));
 }
 
-#ifdef USE_D2D1_1
 static inline bool D2DSupportsCompositeMode(CompositionOp aOp)
 {
   switch(aOp) {
   case CompositionOp::OP_OVER:
   case CompositionOp::OP_ADD:
   case CompositionOp::OP_ATOP:
   case CompositionOp::OP_OUT:
   case CompositionOp::OP_IN:
@@ -276,17 +266,16 @@ static inline D2D1_BLEND_MODE D2DBlendMo
   case CompositionOp::OP_COLOR:
     return D2D1_BLEND_MODE_COLOR;
   case CompositionOp::OP_LUMINOSITY:
     return D2D1_BLEND_MODE_LUMINOSITY;
   default:
     return D2D1_BLEND_MODE_MULTIPLY;
   }
 }
-#endif
 
 static inline bool IsPatternSupportedByD2D(const Pattern &aPattern)
 {
   if (aPattern.GetType() != PatternType::RADIAL_GRADIENT) {
     return true;
   }
 
   const RadialGradientPattern *pat =
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -47,32 +47,27 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
         'DrawTargetCG.cpp',
         'PathCG.cpp',
         'ScaledFontMac.cpp',
         'SourceSurfaceCG.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'DrawTargetD2D.cpp',
+        'DrawTargetD2D1.cpp',
+        'FilterNodeD2D1.cpp',
         'PathD2D.cpp',
+        'RadialGradientEffectD2D1.cpp',
         'ScaledFontDWrite.cpp',
         'ScaledFontWin.cpp',
         'SourceSurfaceD2D.cpp',
+        'SourceSurfaceD2D1.cpp',
         'SourceSurfaceD2DTarget.cpp',
     ]
     DEFINES['WIN32'] = True
-    # For Direct2D 1.1 we require WINSDK_MAXVER 0x06020000 or higher.
-    if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
-        SOURCES += [
-            'DrawTargetD2D1.cpp',
-            'FilterNodeD2D1.cpp',
-            'RadialGradientEffectD2D1.cpp',
-            'SourceSurfaceD2D1.cpp'
-        ]
-        DEFINES['USE_D2D1_1'] = True
 
 if CONFIG['MOZ_ENABLE_SKIA']:
     UNIFIED_SOURCES += [
         'convolver.cpp',
         'DrawTargetSkia.cpp',
         'PathSkia.cpp',
         'SourceSurfaceSkia.cpp',
     ]
--- a/gfx/gl/GLContextCGL.h
+++ b/gfx/gl/GLContextCGL.h
@@ -22,17 +22,17 @@ namespace gl {
 
 class GLContextCGL : public GLContext
 {
     friend class GLContextProviderCGL;
 
     NSOpenGLContext *mContext;
 
 public:
-    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL)
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, MOZ_OVERRIDE)
     GLContextCGL(const SurfaceCaps& caps,
                  GLContext *shareContext,
                  NSOpenGLContext *context,
                  bool isOffscreen = false);
 
     ~GLContextCGL();
 
     virtual GLContextType GetContextType() const MOZ_OVERRIDE { return GLContextType::CGL; }
--- a/gfx/gl/GLContextEGL.h
+++ b/gfx/gl/GLContextEGL.h
@@ -24,17 +24,17 @@ class GLContextEGL : public GLContext
     static already_AddRefed<GLContextEGL>
     CreateGLContext(const SurfaceCaps& caps,
                     GLContextEGL *shareContext,
                     bool isOffscreen,
                     EGLConfig config,
                     EGLSurface surface);
 
 public:
-    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL)
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL, MOZ_OVERRIDE)
     GLContextEGL(const SurfaceCaps& caps,
                  GLContext* shareContext,
                  bool isOffscreen,
                  EGLConfig config,
                  EGLSurface surface,
                  EGLContext context);
 
     ~GLContextEGL();
--- a/gfx/gl/GfxTexturesReporter.h
+++ b/gfx/gl/GfxTexturesReporter.h
@@ -44,17 +44,17 @@ public:
     static void UpdateAmount(MemoryUse action, GLenum format, GLenum type,
                              int32_t tileWidth, int32_t tileHeight);
 
     static void UpdateWasteAmount(int32_t delta) {
       sTileWasteAmount += delta;
     }
 
     NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
-                              nsISupports* aData, bool aAnonymize)
+                              nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE
     {
         MOZ_COLLECT_REPORT("gfx-tiles-waste", KIND_OTHER, UNITS_BYTES,
             sTileWasteAmount,
             "Memory lost due to tiles extending past content boundaries");
         return MOZ_COLLECT_REPORT(
             "gfx-textures", KIND_OTHER, UNITS_BYTES, sAmount,
             "Memory used for storing GL textures.");
     }
--- a/gfx/layers/GLImages.cpp
+++ b/gfx/layers/GLImages.cpp
@@ -56,17 +56,17 @@ GLImage::GetAsSourceSurface()
                                 LOCAL_GL_RGBA,
                                 LOCAL_GL_UNSIGNED_BYTE,
                                 nullptr);
 
   ScopedFramebufferForTexture fb(sSnapshotContext, scopedTex.Texture());
 
   GLBlitHelper helper(sSnapshotContext);
 
-  helper.BlitImageToFramebuffer(this, size, fb.FB(), false);
+  helper.BlitImageToFramebuffer(this, size, fb.FB(), true);
 
   ScopedBindFramebuffer bind(sSnapshotContext, fb.FB());
 
   RefPtr<gfx::DataSourceSurface> source =
         gfx::Factory::CreateDataSourceSurface(size, gfx::SurfaceFormat::B8G8R8A8);
   if (NS_WARN_IF(!source)) {
     return nullptr;
   }
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -732,33 +732,33 @@ Layer::IsScrollInfoLayer() const
       && HasScrollableFrameMetrics()
       && !GetFirstChild();
 }
 
 const Matrix4x4
 Layer::GetTransform() const
 {
   Matrix4x4 transform = mTransform;
-  transform.PostScale(mPostXScale, mPostYScale, 1.0f);
+  transform.PostScale(GetPostXScale(), GetPostYScale(), 1.0f);
   if (const ContainerLayer* c = AsContainerLayer()) {
     transform.PreScale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
   }
   return transform;
 }
 
 const Matrix4x4
 Layer::GetLocalTransform()
 {
   Matrix4x4 transform;
   if (LayerComposite* shadow = AsLayerComposite())
     transform = shadow->GetShadowTransform();
   else
     transform = mTransform;
 
-  transform.PostScale(mPostXScale, mPostYScale, 1.0f);
+  transform.PostScale(GetPostXScale(), GetPostYScale(), 1.0f);
   if (ContainerLayer* c = AsContainerLayer()) {
     transform.PreScale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
   }
 
   return transform;
 }
 
 void
@@ -853,16 +853,18 @@ Layer::TransformRectToRenderTarget(const
 ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
   : Layer(aManager, aImplData),
     mFirstChild(nullptr),
     mLastChild(nullptr),
     mPreXScale(1.0f),
     mPreYScale(1.0f),
     mInheritedXScale(1.0f),
     mInheritedYScale(1.0f),
+    mPresShellResolution(1.0f),
+    mScaleToResolution(false),
     mUseIntermediateSurface(false),
     mSupportsComponentAlphaChildren(false),
     mMayHaveReadbackChild(false),
     mChildrenChanged(false)
 {
   mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
 }
 
@@ -1012,16 +1014,17 @@ ContainerLayer::RepositionChild(Layer* a
   return true;
 }
 
 void
 ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
 {
   aAttrs = ContainerLayerAttributes(mPreXScale, mPreYScale,
                                     mInheritedXScale, mInheritedYScale,
+                                    mPresShellResolution, mScaleToResolution,
                                     reinterpret_cast<uint64_t>(mHMDInfo.get()));
 }
 
 bool
 ContainerLayer::HasMultipleChildren()
 {
   uint32_t count = 0;
   for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
@@ -1676,16 +1679,19 @@ ContainerLayer::PrintInfo(std::stringstr
 {
   Layer::PrintInfo(aStream, aPrefix);
   if (UseIntermediateSurface()) {
     aStream << " [usesTmpSurf]";
   }
   if (1.0 != mPreXScale || 1.0 != mPreYScale) {
     aStream << nsPrintfCString(" [preScale=%g, %g]", mPreXScale, mPreYScale).get();
   }
+  if (mScaleToResolution) {
+    aStream << nsPrintfCString(" [presShellResolution=%g]", mPresShellResolution).get();
+  }
   if (mHMDInfo) {
     aStream << nsPrintfCString(" [hmd=%p]", mHMDInfo.get()).get();
   }
 }
 
 void
 ContainerLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
 {
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1221,18 +1221,19 @@ public:
   Layer* GetNextSibling() { return mNextSibling; }
   const Layer* GetNextSibling() const { return mNextSibling; }
   Layer* GetPrevSibling() { return mPrevSibling; }
   const Layer* GetPrevSibling() const { return mPrevSibling; }
   virtual Layer* GetFirstChild() const { return nullptr; }
   virtual Layer* GetLastChild() const { return nullptr; }
   const gfx::Matrix4x4 GetTransform() const;
   const gfx::Matrix4x4& GetBaseTransform() const { return mTransform; }
-  float GetPostXScale() const { return mPostXScale; }
-  float GetPostYScale() const { return mPostYScale; }
+  // Note: these are virtual because ContainerLayerComposite overrides them.
+  virtual float GetPostXScale() const { return mPostXScale; }
+  virtual float GetPostYScale() const { return mPostYScale; }
   bool GetIsFixedPosition() { return mIsFixedPosition; }
   bool GetIsStickyPosition() { return mStickyPositionData; }
   LayerPoint GetFixedPositionAnchor() { return mAnchor; }
   const LayerMargin& GetFixedPositionMargins() { return mMargins; }
   FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
   const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
   const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
   FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; }
@@ -1850,31 +1851,45 @@ public:
     }
 
     MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) InheritedScale", this));
     mInheritedXScale = aXScale;
     mInheritedYScale = aYScale;
     Mutated();
   }
 
+  void SetScaleToResolution(bool aScaleToResolution, float aResolution)
+  {
+    if (mScaleToResolution == aScaleToResolution && mPresShellResolution == aResolution) {
+      return;
+    }
+
+    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScaleToResolution", this));
+    mScaleToResolution = aScaleToResolution;
+    mPresShellResolution = aResolution;
+    Mutated();
+  }
+
   virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) MOZ_OVERRIDE;
 
   void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray);
 
   // These getters can be used anytime.
 
   virtual ContainerLayer* AsContainerLayer() MOZ_OVERRIDE { return this; }
   virtual const ContainerLayer* AsContainerLayer() const MOZ_OVERRIDE { return this; }
 
   virtual Layer* GetFirstChild() const MOZ_OVERRIDE { return mFirstChild; }
   virtual Layer* GetLastChild() const MOZ_OVERRIDE { return mLastChild; }
   float GetPreXScale() const { return mPreXScale; }
   float GetPreYScale() const { return mPreYScale; }
   float GetInheritedXScale() const { return mInheritedXScale; }
   float GetInheritedYScale() const { return mInheritedYScale; }
+  float GetPresShellResolution() const { return mPresShellResolution; }
+  bool ScaleToResolution() const { return mScaleToResolution; }
 
   MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER)
 
   /**
    * ContainerLayer backends need to override ComputeEffectiveTransforms
    * since the decision about whether to use a temporary surface for the
    * container is backend-specific. ComputeEffectiveTransforms must also set
    * mUseIntermediateSurface.
@@ -1963,16 +1978,21 @@ protected:
   Layer* mFirstChild;
   Layer* mLastChild;
   float mPreXScale;
   float mPreYScale;
   // The resolution scale inherited from the parent layer. This will already
   // be part of mTransform.
   float mInheritedXScale;
   float mInheritedYScale;
+  // For layers corresponding to an nsDisplayResolution, the resolution of the
+  // associated pres shell; for other layers, 1.0.
+  float mPresShellResolution;
+  // Whether the compositor should scale to mPresShellResolution.
+  bool mScaleToResolution;
   bool mUseIntermediateSurface;
   bool mSupportsComponentAlphaChildren;
   bool mMayHaveReadbackChild;
   // This is updated by ComputeDifferences. This will be true if we need to invalidate
   // the intermediate surface.
   bool mChildrenChanged;
   nsRefPtr<gfx::VRHMDInfo> mHMDInfo;
 };
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -623,17 +623,17 @@ APZCTreeManager::ReceiveInputEvent(Input
           apzc,
           /* aTargetConfirmed = */ hitResult == ApzcHitRegion,
           wheelInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 transformToGecko = transformToApzc * GetApzcToGeckoTransform(apzc);
         wheelInput.mOrigin =
-          TransformTo<ScreenPixel>(transformToGecko, wheelInput.mLocalOrigin);
+          TransformTo<ScreenPixel>(transformToGecko, wheelInput.mOrigin);
       }
       break;
     } case PANGESTURE_INPUT: {
       PanGestureInput& panInput = aEvent.AsPanGestureInput();
       nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
                                                             &hitResult);
       if (apzc) {
         MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -2634,47 +2634,29 @@ ViewTransform AsyncPanZoomController::Ge
     if (minScrollOffset.x < maxScrollOffset.x) {
       currentScrollOffset.x = clamped(currentScrollOffset.x, minScrollOffset.x, maxScrollOffset.x);
     }
     if (minScrollOffset.y < maxScrollOffset.y) {
       currentScrollOffset.y = clamped(currentScrollOffset.y, minScrollOffset.y, maxScrollOffset.y);
     }
   }
 
-  LayerToParentLayerScale scale(mFrameMetrics.mPresShellResolution      // non-transient portion
-                                * mFrameMetrics.GetAsyncZoom().scale);  // transient portion
   ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
                                * mFrameMetrics.GetZoom();
 
-  return ViewTransform(scale, -translation);
-}
-
-Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
-  return Matrix4x4::Scaling(mLastContentPaintMetrics.mPresShellResolution,
-                            mLastContentPaintMetrics.mPresShellResolution,
-                            1.0f);
+  return ViewTransform(mFrameMetrics.GetAsyncZoom(), -translation);
 }
 
 Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
   ReentrantMonitorAutoEnter lock(mMonitor);
 
   LayerPoint scrollChange =
     (mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
     * mLastContentPaintMetrics.GetDevPixelsPerCSSPixel()
-    * mLastContentPaintMetrics.GetCumulativeResolution()
-      // This transform ("LD" in the terminology of the comment above
-      // GetScreenToApzcTransform() in APZCTreeManager.h) is applied in a
-      // coordinate space that includes the APZC's CSS transform ("LC").
-      // This CSS transform is the identity unless this APZC sets a pres-shell
-      // resolution, in which case the transform has a post-scale that cancels
-      // out the pres-shell resolution. We simulate applying the "LC" transform
-      // by dividing by the pres-shell resolution. This will go away once
-      // bug 1076192 is fixed.
-    / mLastContentPaintMetrics.mPresShellResolution;
+    * mLastContentPaintMetrics.GetCumulativeResolution();
 
   float zoomChange = mLastContentPaintMetrics.GetZoom().scale / mLastDispatchedPaintMetrics.GetZoom().scale;
 
   return Matrix4x4::Translation(scrollChange.x, scrollChange.y, 0).
            PostScale(zoomChange, zoomChange, 1);
 }
 
 bool AsyncPanZoomController::IsCurrentlyCheckerboarding() const {
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -213,23 +213,16 @@ public:
    * Returns the incremental transformation corresponding to the async pan/zoom
    * in progress. That is, when this transform is multiplied with the layer's
    * existing transform, it will make the layer appear with the desired pan/zoom
    * amount.
    */
   ViewTransform GetCurrentAsyncTransform() const;
 
   /**
-   * Returns the part of the async transform that will remain once Gecko does a
-   * repaint at the desired metrics. That is, in the steady state:
-   * Matrix4x4(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
-   */
-  Matrix4x4 GetNontransientAsyncTransform() const;
-
-  /**
    * Returns the transform to take something from the coordinate space of the
    * last thing we know gecko painted, to the coordinate space of the last thing
    * we asked gecko to paint. In cases where that last request has not yet been
    * processed, this is needed to transform input events properly into a space
    * gecko will understand.
    */
   Matrix4x4 GetTransformToLastDispatchedPaint() const;
 
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -140,17 +140,17 @@ APZCCallbackHelper::UpdateRootFrame(nsID
     }
 
     aMetrics.SetScrollOffset(actualScrollOffset);
 
     // The pres shell resolution is updated by the the async zoom since the
     // last paint.
     float presShellResolution = aMetrics.mPresShellResolution
                               * aMetrics.GetAsyncZoom().scale;
-    aUtils->SetResolution(presShellResolution, presShellResolution);
+    aUtils->SetResolutionAndScaleTo(presShellResolution, presShellResolution);
 
     // Finally, we set the displayport.
     nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
     if (!content) {
         return;
     }
     nsCOMPtr<nsIDOMElement> element = do_QueryInterface(content);
     if (!element) {
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -67,18 +67,18 @@ static gfx::Matrix4x4
 GetTransformToAncestorsParentLayer(Layer* aStart, const LayerMetricsWrapper& aAncestor)
 {
   gfx::Matrix4x4 transform;
   const LayerMetricsWrapper& ancestorParent = aAncestor.GetParent();
   for (LayerMetricsWrapper iter(aStart, LayerMetricsWrapper::StartAt::BOTTOM);
        ancestorParent ? iter != ancestorParent : iter.IsValid();
        iter = iter.GetParent()) {
     transform = transform * iter.GetTransform();
-    // If the layer has a non-transient async transform then we need to apply it here
-    // because it will get applied by the APZ in the compositor as well
+    // If the layer has a pres shell resolution, the compositor will apply
+    // a scale to scale to this transform. Apply it here too.
     const FrameMetrics& metrics = iter.Metrics();
     transform.PostScale(metrics.mPresShellResolution, metrics.mPresShellResolution, 1.f);
   }
   return transform;
 }
 
 void
 ClientTiledPaintedLayer::GetAncestorLayers(LayerMetricsWrapper* aOutScrollAncestor,
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -146,21 +146,19 @@ FuzzyEquals(float a, float b) {
 
 static ViewTransform
 ComputeViewTransform(const FrameMetrics& aContentMetrics, const FrameMetrics& aCompositorMetrics)
 {
   // This is basically the same code as AsyncPanZoomController::GetCurrentAsyncTransform
   // but with aContentMetrics used in place of mLastContentPaintMetrics, because they
   // should be equivalent, modulo race conditions while transactions are inflight.
 
-  LayerToParentLayerScale scale(aCompositorMetrics.mPresShellResolution
-                                * aCompositorMetrics.GetAsyncZoom().scale);
   ParentLayerPoint translation = (aCompositorMetrics.GetScrollOffset() - aContentMetrics.GetScrollOffset())
                                * aCompositorMetrics.GetZoom();
-  return ViewTransform(scale, -translation);
+  return ViewTransform(aCompositorMetrics.GetAsyncZoom(), -translation);
 }
 
 bool
 SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics(
     const LayerMetricsWrapper& aLayer,
     bool aHasPendingNewThebesContent,
     bool aLowPrecision,
     ViewTransform& aViewTransform)
@@ -1313,43 +1311,28 @@ ClientTiledLayerBuffer::ValidateTile(Til
   return aTile;
 }
 
 /**
  * This function takes the transform stored in aTransformToCompBounds
  * (which was generated in GetTransformToAncestorsParentLayer), and
  * modifies it with the ViewTransform from the compositor side so that
  * it reflects what the compositor is actually rendering. This operation
- * basically replaces the nontransient async transform that was injected
- * in GetTransformToAncestorsParentLayer with the complete async transform.
+ * basically adds in the layer's async transform.
  * This function then returns the scroll ancestor's composition bounds,
  * transformed into the painted layer's LayerPixel coordinates, accounting
  * for the compositor state.
  */
 static LayerRect
 GetCompositorSideCompositionBounds(const LayerMetricsWrapper& aScrollAncestor,
                                    const Matrix4x4& aTransformToCompBounds,
                                    const ViewTransform& aAPZTransform)
 {
-  Matrix4x4 nonTransientAPZUntransform = Matrix4x4::Scaling(
-    aScrollAncestor.Metrics().mPresShellResolution,
-    aScrollAncestor.Metrics().mPresShellResolution,
-    1.f);
-  nonTransientAPZUntransform.Invert();
-
-  // Take off the last "term" of aTransformToCompBounds, which
-  // is the APZ's nontransient async transform. Replace it with
-  // the APZ's async transform (this includes the nontransient
-  // component as well).
-  Matrix4x4 transform = aTransformToCompBounds
-                      * nonTransientAPZUntransform
-                      * Matrix4x4(aAPZTransform);
-  transform.Invert();
-
-  return TransformTo<LayerPixel>(transform,
+  Matrix4x4 transform = aTransformToCompBounds * Matrix4x4(aAPZTransform);
+  return TransformTo<LayerPixel>(transform.Inverse(),
             aScrollAncestor.Metrics().mCompositionBounds);
 }
 
 bool
 ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvalidRegion,
                                                        const nsIntRegion& aOldValidRegion,
                                                        nsIntRegion& aRegionToPaint,
                                                        BasicTiledLayerPaintData* aPaintData,
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -690,75 +690,89 @@ ApplyAsyncTransformToScrollbarForContent
   if (aContent.IsScrollInfoLayer()) {
     return;
   }
 
   const FrameMetrics& metrics = aContent.Metrics();
   AsyncPanZoomController* apzc = aContent.GetApzc();
 
   Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform();
-  Matrix4x4 nontransientTransform = apzc->GetNontransientAsyncTransform();
-  Matrix4x4 transientTransform = nontransientTransform.Inverse() * asyncTransform;
 
-  // |transientTransform| represents the amount by which we have scrolled and
+  // |asyncTransform| represents the amount by which we have scrolled and
   // zoomed since the last paint. Because the scrollbar was sized and positioned based
-  // on the painted content, we need to adjust it based on transientTransform so that
+  // on the painted content, we need to adjust it based on asyncTransform so that
   // it reflects what the user is actually seeing now.
   // - The scroll thumb needs to be scaled in the direction of scrolling by the inverse
-  //   of the transientTransform scale (representing the zoom). This is because zooming
+  //   of the asyncTransform scale (representing the zoom). This is because zooming
   //   in decreases the fraction of the whole scrollable rect that is in view.
-  // - It needs to be translated in opposite direction of the transientTransform
+  // - It needs to be translated in opposite direction of the asyncTransform
   //   translation (representing the scroll). This is because scrolling down, which
   //   translates the layer content up, should result in moving the scroll thumb down.
   //   The amount of the translation to the scroll thumb should be such that the ratio
   //   of the translation to the size of the scroll port is the same as the ratio
   //   of the scroll amount to the size of the scrollable rect.
   Matrix4x4 scrollbarTransform;
   if (aScrollbar->GetScrollbarDirection() == Layer::VERTICAL) {
     float scale = metrics.CalculateCompositedSizeInCssPixels().height / metrics.GetScrollableRect().height;
     if (aScrollbarIsDescendant) {
       // In cases where the scrollbar is a descendant of the content, the
       // scrollbar gets painted at the same resolution as the content. Since the
       // coordinate space we apply this transform in includes the resolution, we
       // need to adjust for it as well here. Note that in another
-      // aScrollbarIsDescendant hunk below we unapply the entire async
-      // transform, which includes the nontransientasync transform and would
-      // normally account for the resolution.
+      // aScrollbarIsDescendant hunk below we apply a resolution-cancelling
+      // transform which ensures the scroll thumb isn't actually rendered
+      // at a larger scale.
       scale *= metrics.mPresShellResolution;
     }
-    scrollbarTransform.PostScale(1.f, 1.f / transientTransform._22, 1.f);
-    scrollbarTransform.PostTranslate(0, -transientTransform._42 * scale, 0);
+    scrollbarTransform.PostScale(1.f, 1.f / asyncTransform._22, 1.f);
+    scrollbarTransform.PostTranslate(0, -asyncTransform._42 * scale, 0);
   }
   if (aScrollbar->GetScrollbarDirection() == Layer::HORIZONTAL) {
     float scale = metrics.CalculateCompositedSizeInCssPixels().width / metrics.GetScrollableRect().width;
     if (aScrollbarIsDescendant) {
       scale *= metrics.mPresShellResolution;
     }
-    scrollbarTransform.PostScale(1.f / transientTransform._11, 1.f, 1.f);
-    scrollbarTransform.PostTranslate(-transientTransform._41 * scale, 0, 0);
+    scrollbarTransform.PostScale(1.f / asyncTransform._11, 1.f, 1.f);
+    scrollbarTransform.PostTranslate(-asyncTransform._41 * scale, 0, 0);
   }
 
   Matrix4x4 transform = scrollbarTransform * aScrollbar->GetTransform();
 
   if (aScrollbarIsDescendant) {
-    // If the scrollbar layer is a child of the content it is a scrollbar for, then we
-    // need to do an extra untransform to cancel out the async transform on
-    // the content. This is needed because layout positions and sizes the
-    // scrollbar on the assumption that there is no async transform, and without
-    // this code the scrollbar will end up in the wrong place.
+    // If the scrollbar layer is a child of the content it is a scrollbar for,
+    // then we need to make a couple of adjustments to the scrollbar's transform.
+    //
+    //  - First, the content's resolution applies to the scrollbar as well.
+    //    Since we don't actually want the scroll thumb's size to vary with
+    //    the zoom (other than its length reflecting the fraction of the
+    //    scrollable length that's in view, which is taken care of above),
+    //    we apply a transform to cancel out this resolution.
     //
-    // Since the async transform is applied on top of the content's regular
-    // transform, we need to make sure to unapply the async transform in the
-    // same coordinate space. This requires applying the content transform and
-    // then unapplying it after unapplying the async transform.
+    //  - Second, if there is any async transform (including an overscroll
+    //    transform) on the content, this needs to be cancelled out because
+    //    layout positions and sizes the scrollbar on the assumption that there
+    //    is no async transform, and without this adjustment the scrollbar will
+    //    end up in the wrong place.
+    //
+    //    Note that since the async transform is applied on top of the content's
+    //    regular transform, we need to make sure to unapply the async transform
+    //    in the same coordinate space. This requires applying the content
+    //    transform and then unapplying it after unapplying the async transform.
+    Matrix4x4 resolutionCancellingTransform =
+        Matrix4x4::Scaling(metrics.mPresShellResolution,
+                           metrics.mPresShellResolution,
+                           1.0f).Inverse();
     Matrix4x4 asyncUntransform = (asyncTransform * apzc->GetOverscrollTransform()).Inverse();
     Matrix4x4 contentTransform = aContent.GetTransform();
     Matrix4x4 contentUntransform = contentTransform.Inverse();
 
-    Matrix4x4 compensation = contentTransform * asyncUntransform * contentUntransform;
+    Matrix4x4 compensation = resolutionCancellingTransform
+                           * contentTransform
+                           * asyncUntransform
+                           * contentUntransform;
     transform = transform * compensation;
 
     // We also need to make a corresponding change on the clip rect of all the
     // layers on the ancestor chain from the scrollbar layer up to but not
     // including the layer with the async transform. Otherwise the scrollbar
     // shifts but gets clipped and so appears to flicker.
     for (Layer* ancestor = aScrollbar; ancestor != aContent.GetLayer(); ancestor = ancestor->GetParent()) {
       TransformClipRect(ancestor, compensation);
@@ -889,20 +903,18 @@ AsyncCompositionManager::TransformScroll
   // offset in the view transform we obtained from Java in order to compute the
   // transformation we need to apply.
   ParentLayerPoint geckoScroll(0, 0);
   if (metrics.IsScrollable()) {
     geckoScroll = metrics.GetScrollOffset() * userZoom;
   }
 
   LayerToParentLayerScale asyncZoom = userZoom / metrics.LayersPixelsPerCSSPixel();
-  LayerToParentLayerScale scale(metrics.mPresShellResolution
-                                * asyncZoom.scale);
   ParentLayerPoint translation = userScroll - geckoScroll;
-  Matrix4x4 treeTransform = ViewTransform(scale, -translation);
+  Matrix4x4 treeTransform = ViewTransform(asyncZoom, -translation);
 
   SetShadowTransform(aLayer, oldTransform * treeTransform);
   NS_ASSERTION(!aLayer->AsLayerComposite()->GetShadowTransformSetByAnimation(),
                "overwriting animated transform!");
 
   // Apply resolution scaling to the old transform - the layer tree as it is
   // doesn't have the necessary transform to display correctly.
   oldTransform.PreScale(metrics.mPresShellResolution, metrics.mPresShellResolution, 1);
--- a/gfx/layers/composite/ContainerLayerComposite.h
+++ b/gfx/layers/composite/ContainerLayerComposite.h
@@ -87,16 +87,34 @@ public:
 
   virtual void CleanupResources() MOZ_OVERRIDE;
 
   virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; }
 
   // container layers don't use a compositable
   CompositableHost* GetCompositableHost() MOZ_OVERRIDE { return nullptr; }
 
+  // If the layer is marked as scale-to-resolution, add a post-scale
+  // to the layer's transform equal to the pres shell resolution we're
+  // scaling to. This cancels out the post scale of '1 / resolution'
+  // added by Layout. TODO: It would be nice to get rid of both of these
+  // post-scales.
+  virtual float GetPostXScale() const MOZ_OVERRIDE {
+    if (mScaleToResolution) {
+      return mPostXScale * mPresShellResolution;
+    }
+    return mPostXScale;
+  }
+  virtual float GetPostYScale() const MOZ_OVERRIDE {
+    if (mScaleToResolution) {
+      return mPostYScale * mPresShellResolution;
+    }
+    return mPostYScale;
+  }
+
   virtual const char* Name() const MOZ_OVERRIDE { return "ContainerLayerComposite"; }
   UniquePtr<PreparedData> mPrepared;
 
   RefPtr<CompositingRenderTarget> mLastIntermediateSurface;
 };
 
 class RefLayerComposite : public RefLayer,
                           public LayerComposite
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -342,21 +342,19 @@ TextureClientD3D11::BorrowDrawTarget()
     return nullptr;
   }
 
   if (mDrawTarget) {
     return mDrawTarget;
   }
 
   // This may return a null DrawTarget
-#if USE_D2D1_1
   if (mTexture) {
     mDrawTarget = Factory::CreateDrawTargetForD3D11Texture(mTexture, mFormat);
   } else
-#endif
   {
     MOZ_ASSERT(mTexture10);
     mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture10, mFormat);
   }
   return mDrawTarget;
 }
 
 bool
@@ -365,30 +363,28 @@ TextureClientD3D11::AllocateForSurface(g
   mSize = aSize;
   HRESULT hr;
 
   if (mFormat == SurfaceFormat::A8) {
     // Currently TextureClientD3D11 does not support A8 surfaces. Fallback.
     return false;
   }
 
-#ifdef USE_D2D1_1
   ID3D11Device* d3d11device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
 
   if (gfxPrefs::Direct2DUse1_1() && d3d11device) {
 
     CD3D11_TEXTURE2D_DESC newDesc(mFormat == SurfaceFormat::A8 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM,
                                   aSize.width, aSize.height, 1, 1,
                                   D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
 
     newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
 
     hr = d3d11device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
   } else
-#endif
   {
     ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
 
     CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
       aSize.width, aSize.height, 1, 1,
       D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
 
     newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -377,16 +377,18 @@ LayerTransactionParent::RecvUpdate(const
         ContainerLayerComposite* containerLayer = layerParent->AsContainerLayerComposite();
         if (!containerLayer) {
           return false;
         }
         const ContainerLayerAttributes& attrs =
           specific.get_ContainerLayerAttributes();
         containerLayer->SetPreScale(attrs.preXScale(), attrs.preYScale());
         containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale());
+        containerLayer->SetScaleToResolution(attrs.scaleToResolution(),
+                                             attrs.presShellResolution());
 
         if (attrs.hmdInfo()) {
           if (!IsSameProcess()) {
             NS_WARNING("VR layers currently not supported with cross-process compositing");
             return false;
           }
           containerLayer->SetVRHMDInfo(reinterpret_cast<mozilla::gfx::VRHMDInfo*>(attrs.hmdInfo()));
         }
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -227,16 +227,18 @@ struct CommonLayerAttributes {
 struct PaintedLayerAttributes {
   nsIntRegion validRegion;
 };
 struct ContainerLayerAttributes {
   float preXScale;
   float preYScale;
   float inheritedXScale;
   float inheritedYScale;
+  float presShellResolution;
+  bool scaleToResolution;
   // This is a bare pointer; LayerTransactionParent::RecvUpdate prevents this
   // from being used when !IsSameProcess(), but we should make this truly
   // cross process at some point by passing the HMDConfig
   uint64_t hmdInfo;
 };
 struct ColorLayerAttributes     { LayerColor color; nsIntRect bounds; };
 struct CanvasLayerAttributes    { GraphicsFilterType filter; nsIntRect bounds; };
 struct RefLayerAttributes       { int64_t id; };
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -93,18 +93,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
             'd3d10/ReadbackManagerD3D10.cpp',
             'd3d11/TextureD3D11.cpp',
             'ipc/ShadowLayerUtilsD3D10.cpp',
         ]
         SOURCES += [
             'd3d11/CompositorD3D11.cpp',
             'd3d11/ReadbackManagerD3D11.cpp',
         ]
-        if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
-            DEFINES['USE_D2D1_1'] = True
 
 EXPORTS.gfxipc += [
     'ipc/ShadowLayerUtils.h',
 ]
 
 EXPORTS.mozilla.layers += [
     'apz/public/GeckoContentController.h',
     # exporting things from apz/src is temporary until we extract a
--- a/gfx/skia/trunk/include/effects/SkLayerRasterizer.h
+++ b/gfx/skia/trunk/include/effects/SkLayerRasterizer.h
@@ -70,17 +70,17 @@ protected:
     SkLayerRasterizer();
     SkLayerRasterizer(SkDeque* layers);
     SkLayerRasterizer(SkReadBuffer&);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // override from SkRasterizer
     virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                              const SkIRect* clipBounds,
-                             SkMask* mask, SkMask::CreateMode mode) const;
+                             SkMask* mask, SkMask::CreateMode mode) const SK_OVERRIDE;
 
 private:
     const SkDeque* const fLayers;
 
     static SkDeque* ReadLayers(SkReadBuffer& buffer);
 
     friend class LayerRasterizerTester;
 
--- a/gfx/skia/trunk/include/gpu/SkGpuDevice.h
+++ b/gfx/skia/trunk/include/gpu/SkGpuDevice.h
@@ -92,17 +92,17 @@ public:
                           bool pathIsMutable) SK_OVERRIDE;
     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
                             const SkMatrix&, const SkPaint&) SK_OVERRIDE;
     virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
                                 const SkRect* srcOrNull, const SkRect& dst,
                                 const SkPaint& paint,
                                 SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
-                            int x, int y, const SkPaint& paint);
+                            int x, int y, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawText(const SkDraw&, const void* text, size_t len,
                           SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                              const SkScalar pos[], SkScalar constY,
                              int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                 const SkPath& path, const SkMatrix* matrix,
                                 const SkPaint&) SK_OVERRIDE;
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -836,49 +836,49 @@ TEST_F(APZCBasicTester, ComplexTransform
 
   // Both the parent and child layer should behave exactly the same here, because
   // the CSS transform on the child layer does not affect the SampleContentTransformForFrame code
 
   // initial transform
   apzc->SetFrameMetrics(metrics);
   apzc->NotifyLayersUpdated(metrics, true);
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
-  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint()), viewTransformOut);
+  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
 
   childApzc->SetFrameMetrics(childMetrics);
   childApzc->NotifyLayersUpdated(childMetrics, true);
   childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
-  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint()), viewTransformOut);
+  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
 
   // do an async scroll by 5 pixels and check the transform
   metrics.ScrollBy(CSSPoint(5, 0));
   apzc->SetFrameMetrics(metrics);
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
-  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint(-30, 0)), viewTransformOut);
+  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
 
   childMetrics.ScrollBy(CSSPoint(5, 0));
   childApzc->SetFrameMetrics(childMetrics);
   childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
-  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint(-30, 0)), viewTransformOut);
+  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
 
   // do an async zoom of 1.5x and check the transform
   metrics.ZoomBy(1.5f);
   apzc->SetFrameMetrics(metrics);
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
-  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(3), ParentLayerPoint(-45, 0)), viewTransformOut);
+  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
 
   childMetrics.ZoomBy(1.5f);
   childApzc->SetFrameMetrics(childMetrics);
   childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
-  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(3), ParentLayerPoint(-45, 0)), viewTransformOut);
+  EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
 }
 
 class APZCPanningTester : public APZCBasicTester {
 protected:
   void DoPanTest(bool aShouldTriggerScroll, bool aShouldBeConsumed, uint32_t aBehavior)
   {
     if (aShouldTriggerScroll) {
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -583,17 +583,17 @@ static int64_t gSurfaceMemoryUsed[size_t
 class SurfaceMemoryReporter MOZ_FINAL : public nsIMemoryReporter
 {
     ~SurfaceMemoryReporter() {}
 
 public:
     NS_DECL_ISUPPORTS
 
     NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
-                              nsISupports *aClosure, bool aAnonymize)
+                              nsISupports *aClosure, bool aAnonymize) MOZ_OVERRIDE
     {
         const size_t len = ArrayLength(sSurfaceMemoryReporterAttrs);
         for (size_t i = 0; i < len; i++) {
             int64_t amount = gSurfaceMemoryUsed[i];
 
             if (amount != 0) {
                 const char *path = sSurfaceMemoryReporterAttrs[i].path;
                 const char *desc = sSurfaceMemoryReporterAttrs[i].description;
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -91,24 +91,18 @@ GetDirectWriteFontName(IDWriteFont *aFon
     if (FAILED(hr)) {
         return hr;
     }
 
     aFontName.Assign(faceName.Elements());
     return S_OK;
 }
 
-// These strings are only defined in Win SDK 8+, so use #ifdef for now
-#if MOZ_WINSDK_TARGETVER > 0x08000000
 #define FULLNAME_ID   DWRITE_INFORMATIONAL_STRING_FULL_NAME
 #define PSNAME_ID     DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME
-#else
-#define FULLNAME_ID   DWRITE_INFORMATIONAL_STRING_ID(DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT + 1)
-#define PSNAME_ID     DWRITE_INFORMATIONAL_STRING_ID(DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT + 2)
-#endif
 
 // for use in reading postscript or fullname
 static HRESULT
 GetDirectWriteFaceName(IDWriteFont *aFont,
                        DWRITE_INFORMATIONAL_STRING_ID aWhichName,
                        nsAString& aFontName)
 {
     HRESULT hr;
--- a/gfx/thebes/gfxFontInfoLoader.cpp
+++ b/gfx/thebes/gfxFontInfoLoader.cpp
@@ -30,33 +30,33 @@ class FontInfoLoadCompleteEvent : public
     virtual ~FontInfoLoadCompleteEvent() {}
 
     NS_DECL_ISUPPORTS_INHERITED
 
     explicit FontInfoLoadCompleteEvent(FontInfoData *aFontInfo) :
         mFontInfo(aFontInfo)
     {}
 
-    NS_IMETHOD Run();
+    NS_IMETHOD Run() MOZ_OVERRIDE;
 
     nsRefPtr<FontInfoData> mFontInfo;
 };
 
 class AsyncFontInfoLoader : public nsRunnable {
     virtual ~AsyncFontInfoLoader() {}
 
     NS_DECL_ISUPPORTS_INHERITED
 
     explicit AsyncFontInfoLoader(FontInfoData *aFontInfo) :
         mFontInfo(aFontInfo)
     {
         mCompleteEvent = new FontInfoLoadCompleteEvent(aFontInfo);
     }
 
-    NS_IMETHOD Run();
+    NS_IMETHOD Run() MOZ_OVERRIDE;
 
     nsRefPtr<FontInfoData> mFontInfo;
     nsRefPtr<FontInfoLoadCompleteEvent> mCompleteEvent;
 };
 
 // runs on main thread after async font info loading is done
 nsresult
 FontInfoLoadCompleteEvent::Run()
--- a/gfx/thebes/gfxImageSurface.h
+++ b/gfx/thebes/gfxImageSurface.h
@@ -71,17 +71,17 @@ public:
 
     explicit gfxImageSurface(cairo_surface_t *csurf);
 
     virtual ~gfxImageSurface();
 
     // ImageSurface methods
     gfxImageFormat Format() const { return mFormat; }
 
-    virtual const gfxIntSize GetSize() const { return mSize; }
+    virtual const gfxIntSize GetSize() const MOZ_OVERRIDE { return mSize; }
     int32_t Width() const { return mSize.width; }
     int32_t Height() const { return mSize.height; }
 
     /**
      * Distance in bytes between the start of a line and the start of the
      * next line.
      */
     int32_t Stride() const { return mStride; }
@@ -116,17 +116,17 @@ public:
      */
     virtual mozilla::TemporaryRef<mozilla::gfx::DataSourceSurface> CopyToB8G8R8A8DataSourceSurface();
 
     /* return new Subimage with pointing to original image starting from aRect.pos
      * and size of aRect.size. New subimage keeping current image reference
      */
     already_AddRefed<gfxSubimageSurface> GetSubimage(const gfxRect& aRect);
 
-    virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
+    virtual already_AddRefed<gfxImageSurface> GetAsImageSurface() MOZ_OVERRIDE;
 
     /** See gfxASurface.h. */
     static long ComputeStride(const gfxIntSize&, gfxImageFormat);
 
     virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
         MOZ_OVERRIDE;
     virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
         MOZ_OVERRIDE;
--- a/gfx/thebes/gfxMacFont.h
+++ b/gfx/thebes/gfxMacFont.h
@@ -50,19 +50,19 @@ public:
 
     virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont>
     GetScaledFont(mozilla::gfx::DrawTarget *aTarget) MOZ_OVERRIDE;
 
     virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions>
       GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) MOZ_OVERRIDE;
 
     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
-                                        FontCacheSizes* aSizes) const;
+                                        FontCacheSizes* aSizes) const MOZ_OVERRIDE;
     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
-                                        FontCacheSizes* aSizes) const;
+                                        FontCacheSizes* aSizes) const MOZ_OVERRIDE;
 
     virtual FontType GetType() const MOZ_OVERRIDE { return FONT_TYPE_MAC; }
 
 protected:
     virtual const Metrics& GetHorizontalMetrics() MOZ_OVERRIDE {
         return mMetrics;
     }
 
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -41,28 +41,28 @@ public:
 
     virtual CGFontRef GetFontRef();
 
     // override gfxFontEntry table access function to bypass table cache,
     // use CGFontRef API to get direct access to system font data
     virtual hb_blob_t *GetFontTable(uint32_t aTag) MOZ_OVERRIDE;
 
     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
-                                        FontListSizes* aSizes) const;
+                                        FontListSizes* aSizes) const MOZ_OVERRIDE;
 
-    nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr);
+    nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) MOZ_OVERRIDE;
 
     bool RequiresAATLayout() const { return mRequiresAAT; }
 
     bool IsCFF();
 
 protected:
-    virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold);
+    virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) MOZ_OVERRIDE;
 
-    virtual bool HasFontTable(uint32_t aTableTag);
+    virtual bool HasFontTable(uint32_t aTableTag) MOZ_OVERRIDE;
 
     static void DestroyBlobFunc(void* aUserData);
 
     CGFontRef mFontRef; // owning reference to the CGFont, released on destruction
 
     bool mFontRefInitialized;
     bool mRequiresAAT;
     bool mIsCFF;
--- a/gfx/thebes/gfxPlatformMac.h
+++ b/gfx/thebes/gfxPlatformMac.h
@@ -25,64 +25,64 @@ public:
         return (gfxPlatformMac*) gfxPlatform::GetPlatform();
     }
 
     virtual already_AddRefed<gfxASurface>
       CreateOffscreenSurface(const IntSize& size,
                              gfxContentType contentType) MOZ_OVERRIDE;
 
     mozilla::TemporaryRef<mozilla::gfx::ScaledFont>
-      GetScaledFontForFont(mozilla::gfx::DrawTarget* aTarget, gfxFont *aFont);
+      GetScaledFontForFont(mozilla::gfx::DrawTarget* aTarget, gfxFont *aFont) MOZ_OVERRIDE;
 
-    nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
+    nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) MOZ_OVERRIDE;
 
     gfxFontGroup*
     CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
                     const gfxFontStyle *aStyle,
-                    gfxUserFontSet *aUserFontSet);
+                    gfxUserFontSet *aUserFontSet) MOZ_OVERRIDE;
 
     virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
                                           uint16_t aWeight,
                                           int16_t aStretch,
-                                          bool aItalic);
+                                          bool aItalic) MOZ_OVERRIDE;
 
-    virtual gfxPlatformFontList* CreatePlatformFontList();
+    virtual gfxPlatformFontList* CreatePlatformFontList() MOZ_OVERRIDE;
 
     virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
                                            uint16_t aWeight,
                                            int16_t aStretch,
                                            bool aItalic,
                                            const uint8_t* aFontData,
-                                           uint32_t aLength);
+                                           uint32_t aLength) MOZ_OVERRIDE;
 
-    bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags);
+    bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) MOZ_OVERRIDE;
 
     nsresult GetFontList(nsIAtom *aLangGroup,
                          const nsACString& aGenericFamily,
-                         nsTArray<nsString>& aListOfFonts);
-    nsresult UpdateFontList();
+                         nsTArray<nsString>& aListOfFonts) MOZ_OVERRIDE;
+    nsresult UpdateFontList() MOZ_OVERRIDE;
 
     virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
                                         int32_t aRunScript,
-                                        nsTArray<const char*>& aFontList);
+                                        nsTArray<const char*>& aFontList) MOZ_OVERRIDE;
 
     virtual bool CanRenderContentToDataSurface() const MOZ_OVERRIDE {
       return true;
     }
 
     bool UseAcceleratedCanvas();
 
     virtual bool UseProgressivePaint() MOZ_OVERRIDE;
     virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() MOZ_OVERRIDE;
 
     // lower threshold on font anti-aliasing
     uint32_t GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; }
 
 private:
-    virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
+    virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size) MOZ_OVERRIDE;
 
     // read in the pref value for the lower threshold on font anti-aliasing
     static uint32_t ReadAntiAliasingThreshold();
 
     uint32_t mFontAntiAliasingThreshold;
 };
 
 #endif /* GFX_PLATFORM_MAC_H */
--- a/gfx/thebes/gfxReusableImageSurfaceWrapper.h
+++ b/gfx/thebes/gfxReusableImageSurfaceWrapper.h
@@ -21,17 +21,17 @@ protected:
 
 public:
   const unsigned char* GetReadOnlyData() const MOZ_OVERRIDE;
   gfxImageFormat Format() MOZ_OVERRIDE;
   gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface) MOZ_OVERRIDE;
   void ReadLock() MOZ_OVERRIDE;
   void ReadUnlock() MOZ_OVERRIDE;
 
-  Type GetType()
+  Type GetType() MOZ_OVERRIDE
   {
     return TYPE_IMAGE;
   }
 
 private:
   nsRefPtr<gfxImageSurface>         mSurface;
 };
 
--- a/gfx/thebes/gfxReusableSharedImageSurfaceWrapper.h
+++ b/gfx/thebes/gfxReusableSharedImageSurfaceWrapper.h
@@ -32,17 +32,17 @@ protected:
 
 public:
   const unsigned char* GetReadOnlyData() const MOZ_OVERRIDE;
   gfxImageFormat Format() MOZ_OVERRIDE;
   gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface) MOZ_OVERRIDE;
   void ReadLock() MOZ_OVERRIDE;
   void ReadUnlock() MOZ_OVERRIDE;
 
-  Type GetType()
+  Type GetType() MOZ_OVERRIDE
   {
     return TYPE_SHARED_IMAGE;
   }
 
   /**
    * Returns the shared memory segment that backs the shared image surface.
    */
   mozilla::ipc::Shmem& GetShmem();
--- a/gfx/thebes/gfxVR.cpp
+++ b/gfx/thebes/gfxVR.cpp
@@ -190,45 +190,45 @@ class FakeScreen : public nsIScreen
 {
 public:
   explicit FakeScreen(const IntRect& aScreenRect)
     : mScreenRect(aScreenRect)
   { }
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) {
+  NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) MOZ_OVERRIDE {
     *l = mScreenRect.x;
     *t = mScreenRect.y;
     *w = mScreenRect.width;
     *h = mScreenRect.height;
     return NS_OK;
   }
-  NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) {
+  NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) MOZ_OVERRIDE {
     return GetRect(l, t, w, h);
   }
-  NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) {
+  NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) MOZ_OVERRIDE {
     return GetRect(l, t, w, h);
   }
-  NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) {
+  NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) MOZ_OVERRIDE {
     return GetAvailRect(l, t, w, h);
   }
 
-  NS_IMETHOD GetId(uint32_t* aId) { *aId = (uint32_t)-1; return NS_OK; }
-  NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) { *aPixelDepth = 24; return NS_OK; }
-  NS_IMETHOD GetColorDepth(int32_t* aColorDepth) { *aColorDepth = 24; return NS_OK; }
+  NS_IMETHOD GetId(uint32_t* aId) MOZ_OVERRIDE { *aId = (uint32_t)-1; return NS_OK; }
+  NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) MOZ_OVERRIDE { *aPixelDepth = 24; return NS_OK; }
+  NS_IMETHOD GetColorDepth(int32_t* aColorDepth) MOZ_OVERRIDE { *aColorDepth = 24; return NS_OK; }
 
-  NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD GetRotation(uint32_t* aRotation) {
+  NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) MOZ_OVERRIDE { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) MOZ_OVERRIDE { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD GetRotation(uint32_t* aRotation) MOZ_OVERRIDE {
     *aRotation = nsIScreen::ROTATION_0_DEG;
     return NS_OK;
   }
-  NS_IMETHOD SetRotation(uint32_t aRotation) { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) {
+  NS_IMETHOD SetRotation(uint32_t aRotation) MOZ_OVERRIDE { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) MOZ_OVERRIDE {
     *aContentsScaleFactor = 1.0;
     return NS_OK;
   }
 
 protected:
   virtual ~FakeScreen() {}
 
   IntRect mScreenRect;
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -480,28 +480,24 @@ gfxWindowsPlatform::UpdateRenderMode()
 #endif
 
     uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO);
     uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
     BackendType defaultBackend = BackendType::CAIRO;
     if (mRenderMode == RENDER_DIRECT2D) {
       canvasMask |= BackendTypeBit(BackendType::DIRECT2D);
       contentMask |= BackendTypeBit(BackendType::DIRECT2D);
-#ifdef USE_D2D1_1
       if (gfxPrefs::Direct2DUse1_1() && Factory::SupportsD2D1() &&
           GetD3D11ContentDevice()) {
         contentMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
         canvasMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
         defaultBackend = BackendType::DIRECT2D1_1;
       } else {
-#endif
         defaultBackend = BackendType::DIRECT2D;
-#ifdef USE_D2D1_1
       }
-#endif
     } else {
       canvasMask |= BackendTypeBit(BackendType::SKIA);
     }
     contentMask |= BackendTypeBit(BackendType::SKIA);
     InitBackendPrefs(canvasMask, defaultBackend,
                      contentMask, defaultBackend);
 }
 
@@ -614,24 +610,22 @@ gfxWindowsPlatform::VerifyD2DDevice(bool
         mD2DDevice = cairo_d2d_create_device();
     }
 
     if (mD2DDevice) {
         reporter.SetSuccessful();
         mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice));
     }
 
-#ifdef USE_D2D1_1
     ScopedGfxFeatureReporter reporter1_1("D2D1.1");
 
     if (Factory::SupportsD2D1()) {
       reporter1_1.SetSuccessful();
     }
 #endif
-#endif
 }
 
 gfxPlatformFontList*
 gfxWindowsPlatform::CreatePlatformFontList()
 {
     mUsingGDIFonts = false;
     gfxPlatformFontList *pfl;
 #ifdef CAIRO_HAS_DWRITE_FONT
@@ -1820,17 +1814,16 @@ gfxWindowsPlatform::InitD3D11Devices()
       MOZ_CRASH();
     }
 
     reporterWARP.SetSuccessful();
   }
 
   mD3D11Device->SetExceptionMode(0);
 
-#ifdef USE_D2D1_1
   // We create our device for D2D content drawing here. Normally we don't use
   // D2D content drawing when using WARP. However when WARP is forced by
   // default we will let Direct2D use WARP as well.
   if (Factory::SupportsD2D1() && (!useWARP || gfxPrefs::LayersD3D11ForceWARP())) {
     MOZ_ASSERT((useWARP && !adapter) || !useWARP);
 
     hr = E_INVALIDARG;
     MOZ_SEH_TRY {
@@ -1846,15 +1839,14 @@ gfxWindowsPlatform::InitD3D11Devices()
       d3d11Module.disown();
       return;
     }
 
     mD3D11ContentDevice->SetExceptionMode(0);
 
     Factory::SetDirect3D11Device(mD3D11ContentDevice);
   }
-#endif
 
   // We leak these everywhere and we need them our entire runtime anyway, let's
   // leak it here as well.
   d3d11Module.disown();
 }
 
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -183,18 +183,16 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wi
         UNIFIED_SOURCES += [
             'gfxDWriteFontList.cpp',
         ]
         SOURCES += [
             'gfxD2DSurface.cpp',
             'gfxDWriteCommon.cpp',
             'gfxDWriteFonts.cpp',
         ]
-    if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
-        DEFINES['USE_D2D1_1'] = True
 
 # Are we targeting x86 or x64?  If so, build gfxAlphaRecoverySSE2.cpp.
 if CONFIG['INTEL_ARCHITECTURE']:
     SOURCES += ['gfxAlphaRecoverySSE2.cpp']
     # The file uses SSE2 intrinsics, so it needs special compile flags on some
     # compilers.
     SOURCES['gfxAlphaRecoverySSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
 
--- a/image/src/ClippedImage.cpp
+++ b/image/src/ClippedImage.cpp
@@ -160,26 +160,16 @@ ClippedImage::ShouldClip()
   }
 
   MOZ_ASSERT(mShouldClip.isSome(), "Should have computed a result");
   return *mShouldClip;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(ClippedImage, ImageWrapper)
 
-nsIntRect
-ClippedImage::FrameRect(uint32_t aWhichFrame)
-{
-  if (!ShouldClip()) {
-    return InnerImage()->FrameRect(aWhichFrame);
-  }
-
-  return nsIntRect(0, 0, mClip.width, mClip.height);
-}
-
 NS_IMETHODIMP
 ClippedImage::GetWidth(int32_t* aWidth)
 {
   if (!ShouldClip()) {
     return InnerImage()->GetWidth(aWidth);
   }
 
   *aWidth = mClip.width;
--- a/image/src/ClippedImage.h
+++ b/image/src/ClippedImage.h
@@ -26,18 +26,16 @@ class DrawSingleTileCallback;
  */
 class ClippedImage : public ImageWrapper
 {
   typedef gfx::SourceSurface SourceSurface;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  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_(TemporaryRef<SourceSurface>)
     GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
                                layers::ImageContainer** _retval) MOZ_OVERRIDE;
--- a/image/src/DecodePool.cpp
+++ b/image/src/DecodePool.cpp
@@ -7,16 +7,17 @@
 
 #include <algorithm>
 
 #include "mozilla/ClearOnShutdown.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIObserverService.h"
 #include "nsIThreadPool.h"
+#include "nsProxyRelease.h"
 #include "nsXPCOMCIDInternal.h"
 #include "prsystem.h"
 
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
 
 #include "gfxPrefs.h"
--- a/image/src/DynamicImage.cpp
+++ b/image/src/DynamicImage.cpp
@@ -31,23 +31,16 @@ DynamicImage::Init(const char* aMimeType
 }
 
 already_AddRefed<ProgressTracker>
 DynamicImage::GetProgressTracker()
 {
   return nullptr;
 }
 
-nsIntRect
-DynamicImage::FrameRect(uint32_t aWhichFrame)
-{
-  gfxIntSize size(mDrawable->Size());
-  return nsIntRect(0, 0, size.width, size.height);
-}
-
 size_t
 DynamicImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
 {
   return 0;
 }
 
 size_t
 DynamicImage::SizeOfDecoded(gfxMemoryLocation aLocation,
@@ -87,22 +80,16 @@ nsresult
 DynamicImage::OnImageDataComplete(nsIRequest* aRequest,
                                   nsISupports* aContext,
                                   nsresult aStatus,
                                   bool aLastPart)
 {
   return NS_OK;
 }
 
-nsresult
-DynamicImage::OnNewSourceData()
-{
-  return NS_OK;
-}
-
 void
 DynamicImage::OnSurfaceDiscarded()
 { }
 
 void
 DynamicImage::SetInnerWindowID(uint64_t aInnerWindowId)
 { }
 
--- a/image/src/DynamicImage.h
+++ b/image/src/DynamicImage.h
@@ -29,17 +29,16 @@ public:
   {
     MOZ_ASSERT(aDrawable, "Must have a gfxDrawable to wrap");
   }
 
   // Inherited methods from Image.
   virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
 
   virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
-  virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
   virtual size_t SizeOfSourceWithComputedFallback(
                                  MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
                                MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
 
   virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
   virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
 #ifdef DEBUG
@@ -50,17 +49,16 @@ public:
                                         nsISupports* aContext,
                                         nsIInputStream* aInStr,
                                         uint64_t aSourceOffset,
                                         uint32_t aCount) MOZ_OVERRIDE;
   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        nsresult aStatus,
                                        bool aLastPart) MOZ_OVERRIDE;
-  virtual nsresult OnNewSourceData() MOZ_OVERRIDE;
 
   virtual void OnSurfaceDiscarded() MOZ_OVERRIDE;
 
   virtual void SetInnerWindowID(uint64_t aInnerWindowId) MOZ_OVERRIDE;
   virtual uint64_t InnerWindowID() const MOZ_OVERRIDE;
 
   virtual bool HasError() MOZ_OVERRIDE;
   virtual void SetHasError() MOZ_OVERRIDE;
--- a/image/src/FrameAnimator.cpp
+++ b/image/src/FrameAnimator.cpp
@@ -1,45 +1,37 @@
 /* -*- 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 "FrameAnimator.h"
 #include "FrameBlender.h"
+#include "RasterImage.h"
 
 #include "imgIContainer.h"
 
 namespace mozilla {
 namespace image {
 
-FrameAnimator::FrameAnimator(FrameBlender& aFrameBlender,
-                             uint16_t aAnimationMode)
-  : mCurrentAnimationFrameIndex(0)
-  , mLoopCounter(-1)
-  , mFrameBlender(aFrameBlender)
-  , mAnimationMode(aAnimationMode)
-  , mDoneDecoding(false)
-{ }
-
 int32_t
 FrameAnimator::GetSingleLoopTime() const
 {
   // If we aren't done decoding, we don't know the image's full play time.
   if (!mDoneDecoding) {
     return -1;
   }
 
   // If we're not looping, a single loop time has no meaning
   if (mAnimationMode != imgIContainer::kNormalAnimMode) {
     return -1;
   }
 
   uint32_t looptime = 0;
-  for (uint32_t i = 0; i < mFrameBlender.GetNumFrames(); ++i) {
+  for (uint32_t i = 0; i < mImage->GetNumFrames(); ++i) {
     int32_t timeout = mFrameBlender.GetTimeoutForFrame(i);
     if (timeout >= 0) {
       looptime += static_cast<uint32_t>(timeout);
     } else {
       // If we have a frame that never times out, we're probably in an error
       // case, but let's handle it more gracefully.
       NS_WARNING("Negative frame timeout - how did this happen?");
       return -1;
@@ -80,37 +72,37 @@ FrameAnimator::AdvanceFrame(TimeStamp aT
   NS_ASSERTION(aTime <= TimeStamp::Now(),
                "Given time appears to be in the future");
 
   uint32_t currentFrameIndex = mCurrentAnimationFrameIndex;
   uint32_t nextFrameIndex = currentFrameIndex + 1;
   int32_t timeout = 0;
 
   RefreshResult ret;
-  nsRefPtr<imgFrame> nextFrame = mFrameBlender.RawGetFrame(nextFrameIndex);
+  RawAccessFrameRef nextFrame = mFrameBlender.GetRawFrame(nextFrameIndex);
 
   // If we're done decoding, we know we've got everything we're going to get.
   // If we aren't, we only display fully-downloaded frames; everything else
   // gets delayed.
   bool canDisplay = mDoneDecoding || (nextFrame && nextFrame->ImageComplete());
 
   if (!canDisplay) {
     // Uh oh, the frame we want to show is currently being decoded (partial)
     // Wait until the next refresh driver tick and try again
     return ret;
   }
 
   // If we're done decoding the next frame, go ahead and display it now and
   // reinit with the next frame's delay time.
-  if (mFrameBlender.GetNumFrames() == nextFrameIndex) {
+  if (mImage->GetNumFrames() == nextFrameIndex) {
     // End of an animation loop...
 
     // If we are not looping forever, initialize the loop counter
-    if (mLoopCounter < 0 && mFrameBlender.GetLoopCount() >= 0) {
-      mLoopCounter = mFrameBlender.GetLoopCount();
+    if (mLoopCounter < 0 && mFrameBlender.LoopCount() >= 0) {
+      mLoopCounter = mFrameBlender.LoopCount();
     }
 
     // If animation mode is "loop once", or we're at end of loop counter,
     // it's time to stop animating
     if (mAnimationMode == imgIContainer::kLoopOnceAnimMode ||
         mLoopCounter == 0) {
       ret.animationFinished = true;
     }
@@ -135,17 +127,17 @@ FrameAnimator::AdvanceFrame(TimeStamp aT
     ret.error = true;
   }
 
   if (nextFrameIndex == 0) {
     ret.dirtyRect = mFirstFrameRefreshArea;
   } else {
     // Change frame
     if (nextFrameIndex != currentFrameIndex + 1) {
-      nextFrame = mFrameBlender.RawGetFrame(nextFrameIndex);
+      nextFrame = mFrameBlender.GetRawFrame(nextFrameIndex);
     }
 
     if (!mFrameBlender.DoBlend(&ret.dirtyRect, currentFrameIndex,
                                nextFrameIndex)) {
       // something went wrong, move on to next
       NS_WARNING("FrameAnimator::AdvanceFrame(): Compositing of frame failed");
       nextFrame->SetCompositingFailed(true);
       mCurrentAnimationFrameTime = GetCurrentImgFrameEndTime();
--- a/image/src/FrameAnimator.h
+++ b/image/src/FrameAnimator.h
@@ -9,21 +9,31 @@
 
 #include "mozilla/TimeStamp.h"
 #include "nsRect.h"
 
 namespace mozilla {
 namespace image {
 
 class FrameBlender;
+class RasterImage;
 
 class FrameAnimator
 {
 public:
-  FrameAnimator(FrameBlender& aBlender, uint16_t aAnimationMode);
+  FrameAnimator(RasterImage* aImage,
+                FrameBlender& aFrameBlender,
+                uint16_t aAnimationMode)
+    : mCurrentAnimationFrameIndex(0)
+    , mLoopCounter(-1)
+    , mImage(aImage)
+    , mFrameBlender(aFrameBlender)
+    , mAnimationMode(aAnimationMode)
+    , mDoneDecoding(false)
+  { }
 
   /**
    * Return value from RequestRefresh. Tells callers what happened in that call
    * to RequestRefresh.
    */
   struct RefreshResult
   {
     // The dirty rectangle to be re-drawn after this RequestRefresh().
@@ -153,16 +163,19 @@ private: // data
   TimeStamp mCurrentAnimationFrameTime;
 
   //! The current frame index we're on. 0 to (numFrames - 1).
   uint32_t mCurrentAnimationFrameIndex;
 
   //! number of loops remaining before animation stops (-1 no stop)
   int32_t mLoopCounter;
 
+  //! A weak pointer to our owner.
+  RasterImage* mImage;
+
   //! All the frames of the image, shared with our owner
   FrameBlender& mFrameBlender;
 
   //! The animation mode of this image. Constants defined in imgIContainer.
   uint16_t mAnimationMode;
 
   //! Whether this image is done being decoded.
   bool mDoneDecoding;
--- a/image/src/FrameBlender.cpp
+++ b/image/src/FrameBlender.cpp
@@ -12,62 +12,53 @@
 #include "pixman.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace image {
 
-FrameBlender::FrameBlender()
- : mAnim(nullptr)
- , mLoopCount(-1)
+DrawableFrameRef
+FrameBlender::GetCompositedFrame(uint32_t aFrameNum)
 {
-}
+  MOZ_ASSERT(aFrameNum != 0, "First frame is never composited");
+
+  // If we have a composited version of this frame, return that.
+  if (mLastCompositedFrameIndex == int32_t(aFrameNum)) {
+    return mCompositingFrame->DrawableRef();
+  }
 
-FrameBlender::~FrameBlender()
-{
-  delete mAnim;
+  // Otherwise return the raw frame. DoBlend is required to ensure that we only
+  // hit this case if the frame is not paletted and doesn't require compositing.
+  DrawableFrameRef ref =
+    SurfaceCache::Lookup(mImageKey,
+                         RasterSurfaceKey(mSize,
+                                          0,  // Default decode flags.
+                                          aFrameNum));
+  MOZ_ASSERT(!ref || !ref->GetIsPaletted(), "About to return a paletted frame");
+  return ref;
 }
 
-already_AddRefed<imgFrame>
-FrameBlender::GetFrame(uint32_t aFrameNum)
-{
-  if (mAnim && mAnim->lastCompositedFrameIndex == int32_t(aFrameNum)) {
-    nsRefPtr<imgFrame> frame = mAnim->compositingFrame.get();
-    return frame.forget();
-  }
-  return RawGetFrame(aFrameNum);
-}
-
-already_AddRefed<imgFrame>
-FrameBlender::RawGetFrame(uint32_t aFrameNum)
+RawAccessFrameRef
+FrameBlender::GetRawFrame(uint32_t aFrameNum)
 {
-  if (!mAnim) {
-    NS_ASSERTION(aFrameNum == 0,
-                 "Don't ask for a frame > 0 if we're not animated!");
-    aFrameNum = 0;
-  }
-  if (aFrameNum >= mFrames.Length()) {
-    return nullptr;
-  }
-  nsRefPtr<imgFrame> frame = mFrames[aFrameNum].get();
-  return frame.forget();
-}
-
-uint32_t
-FrameBlender::GetNumFrames() const
-{
-  return mFrames.Length();
+  DrawableFrameRef ref =
+    SurfaceCache::Lookup(mImageKey,
+                         RasterSurfaceKey(mSize,
+                                          0,  // Default decode flags.
+                                          aFrameNum));
+  return ref ? ref->RawAccessRef()
+             : RawAccessFrameRef();
 }
 
 int32_t
 FrameBlender::GetTimeoutForFrame(uint32_t aFrameNum)
 {
-  nsRefPtr<imgFrame> frame = RawGetFrame(aFrameNum);
+  RawAccessFrameRef frame = GetRawFrame(aFrameNum);
   const int32_t timeout = frame->GetRawTimeout();
 
   // Ensure a minimal time between updates so we don't throttle the UI thread.
   // consider 0 == unspecified and make it fast but not too fast.  Unless we
   // have a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug
   // 207059. The behavior of recent IE and Opera versions seems to be:
   // IE 6/Win:
   //   10 - 50ms go 100ms
@@ -80,74 +71,32 @@ FrameBlender::GetTimeoutForFrame(uint32_
   // range.
   if (timeout >= 0 && timeout <= 10 && mLoopCount != 0) {
     return 100;
   }
 
   return timeout;
 }
 
-void
-FrameBlender::SetLoopCount(int32_t aLoopCount)
-{
-  mLoopCount = aLoopCount;
-}
-
-int32_t
-FrameBlender::GetLoopCount() const
-{
-  return mLoopCount;
-}
-
-void
-FrameBlender::RemoveFrame(uint32_t aFrameNum)
-{
-  MOZ_ASSERT(aFrameNum < GetNumFrames(), "Deleting invalid frame!");
-  mFrames.RemoveElementAt(aFrameNum);
-}
-
-void
-FrameBlender::ClearFrames()
-{
-  mFrames.Clear();
-  mFrames.Compact();
-}
-
-void
-FrameBlender::InsertFrame(uint32_t aFrameNum, RawAccessFrameRef&& aRef)
-{
-  MOZ_ASSERT(aRef, "Need a reference to a frame");
-  MOZ_ASSERT(aFrameNum <= GetNumFrames(), "Inserting invalid frame");
-
-  mFrames.InsertElementAt(aFrameNum, Move(aRef));
-  if (GetNumFrames() == 2) {
-    MOZ_ASSERT(!mAnim, "Shouldn't have an animation context yet");
-    mAnim = new Anim();
-  }
-
-  MOZ_ASSERT(GetNumFrames() < 2 || mAnim,
-             "If we're animated we should have an animation context now");
-}
-
 //******************************************************************************
 // DoBlend gets called when the timer for animation get fired and we have to
 // update the composited frame of the animation.
 bool
 FrameBlender::DoBlend(nsIntRect* aDirtyRect,
                       uint32_t aPrevFrameIndex,
                       uint32_t aNextFrameIndex)
 {
-  nsRefPtr<imgFrame> prevFrame = RawGetFrame(aPrevFrameIndex);
-  nsRefPtr<imgFrame> nextFrame = RawGetFrame(aNextFrameIndex);
+  RawAccessFrameRef prevFrame = GetRawFrame(aPrevFrameIndex);
+  RawAccessFrameRef nextFrame = GetRawFrame(aNextFrameIndex);
 
   MOZ_ASSERT(prevFrame && nextFrame, "Should have frames here");
 
   int32_t prevFrameDisposalMethod = prevFrame->GetFrameDisposalMethod();
   if (prevFrameDisposalMethod == FrameBlender::kDisposeRestorePrevious &&
-      !mAnim->compositingPrevFrame) {
+      !mCompositingPrevFrame) {
     prevFrameDisposalMethod = FrameBlender::kDisposeClear;
   }
 
   nsIntRect prevFrameRect = prevFrame->GetRect();
   bool isFullPrevFrame = (prevFrameRect.x == 0 && prevFrameRect.y == 0 &&
                           prevFrameRect.width == mSize.width &&
                           prevFrameRect.height == mSize.height);
 
@@ -212,33 +161,34 @@ FrameBlender::DoBlend(nsIntRect* aDirtyR
   }
 
   // Optimization:
   //   Skip compositing if the last composited frame is this frame
   //   (Only one composited frame was made for this animation.  Example:
   //    Only Frame 3 of a 10 frame image required us to build a composite frame
   //    On the second loop, we do not need to rebuild the frame
   //    since it's still sitting in compositingFrame)
-  if (mAnim->lastCompositedFrameIndex == int32_t(aNextFrameIndex)) {
+  if (mLastCompositedFrameIndex == int32_t(aNextFrameIndex)) {
     return true;
   }
 
   bool needToBlankComposite = false;
 
   // Create the Compositing Frame
-  if (!mAnim->compositingFrame) {
+  if (!mCompositingFrame) {
     nsRefPtr<imgFrame> newFrame = new imgFrame;
-    nsresult rv = newFrame->InitForDecoder(mSize, SurfaceFormat::B8G8R8A8);
+    nsresult rv = newFrame->InitForDecoder(ThebesIntSize(mSize),
+                                           SurfaceFormat::B8G8R8A8);
     if (NS_FAILED(rv)) {
-      mAnim->compositingFrame.reset();
+      mCompositingFrame.reset();
       return false;
     }
-    mAnim->compositingFrame = newFrame->RawAccessRef();
+    mCompositingFrame = newFrame->RawAccessRef();
     needToBlankComposite = true;
-  } else if (int32_t(aNextFrameIndex) != mAnim->lastCompositedFrameIndex+1) {
+  } else if (int32_t(aNextFrameIndex) != mLastCompositedFrameIndex+1) {
 
     // If we are not drawing on top of last composited frame,
     // then we are building a new composite frame, so let's clear it first.
     needToBlankComposite = true;
   }
 
   // More optimizations possible when next frame is not transparent
   // But if the next frame has FrameBlender::kDisposeRestorePrevious,
@@ -271,136 +221,137 @@ FrameBlender::DoBlend(nsIntRect* aDirtyR
 
   if (doDisposal) {
     // Dispose of previous: clear, restore, or keep (copy)
     switch (prevFrameDisposalMethod) {
       case FrameBlender::kDisposeClear:
         if (needToBlankComposite) {
           // If we just created the composite, it could have anything in its
           // buffer. Clear whole frame
-          ClearFrame(mAnim->compositingFrame->GetRawData(),
-                     mAnim->compositingFrame->GetRect());
+          ClearFrame(mCompositingFrame->GetRawData(),
+                     mCompositingFrame->GetRect());
         } else {
           // Only blank out previous frame area (both color & Mask/Alpha)
-          ClearFrame(mAnim->compositingFrame->GetRawData(),
-                     mAnim->compositingFrame->GetRect(),
+          ClearFrame(mCompositingFrame->GetRawData(),
+                     mCompositingFrame->GetRect(),
                      prevFrameRect);
         }
         break;
 
       case FrameBlender::kDisposeClearAll:
-        ClearFrame(mAnim->compositingFrame->GetRawData(),
-                   mAnim->compositingFrame->GetRect());
+        ClearFrame(mCompositingFrame->GetRawData(),
+                   mCompositingFrame->GetRect());
         break;
 
       case FrameBlender::kDisposeRestorePrevious:
         // It would be better to copy only the area changed back to
         // compositingFrame.
-        if (mAnim->compositingPrevFrame) {
-          CopyFrameImage(mAnim->compositingPrevFrame->GetRawData(),
-                         mAnim->compositingPrevFrame->GetRect(),
-                         mAnim->compositingFrame->GetRawData(),
-                         mAnim->compositingFrame->GetRect());
+        if (mCompositingPrevFrame) {
+          CopyFrameImage(mCompositingPrevFrame->GetRawData(),
+                         mCompositingPrevFrame->GetRect(),
+                         mCompositingFrame->GetRawData(),
+                         mCompositingFrame->GetRect());
 
           // destroy only if we don't need it for this frame's disposal
           if (nextFrameDisposalMethod !=
               FrameBlender::kDisposeRestorePrevious) {
-            mAnim->compositingPrevFrame.reset();
+            mCompositingPrevFrame.reset();
           }
         } else {
-          ClearFrame(mAnim->compositingFrame->GetRawData(),
-                     mAnim->compositingFrame->GetRect());
+          ClearFrame(mCompositingFrame->GetRawData(),
+                     mCompositingFrame->GetRect());
         }
         break;
 
       default:
         // Copy previous frame into compositingFrame before we put the new
         // frame on top
         // Assumes that the previous frame represents a full frame (it could be
         // smaller in size than the container, as long as the frame before it
         // erased itself)
         // Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1)
         // will always be a valid frame number.
-        if (mAnim->lastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
+        if (mLastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
           if (isFullPrevFrame && !prevFrame->GetIsPaletted()) {
             // Just copy the bits
             CopyFrameImage(prevFrame->GetRawData(),
                            prevFrame->GetRect(),
-                           mAnim->compositingFrame->GetRawData(),
-                           mAnim->compositingFrame->GetRect());
+                           mCompositingFrame->GetRawData(),
+                           mCompositingFrame->GetRect());
           } else {
             if (needToBlankComposite) {
               // Only blank composite when prev is transparent or not full.
               if (prevFrame->GetHasAlpha() || !isFullPrevFrame) {
-                ClearFrame(mAnim->compositingFrame->GetRawData(),
-                           mAnim->compositingFrame->GetRect());
+                ClearFrame(mCompositingFrame->GetRawData(),
+                           mCompositingFrame->GetRect());
               }
             }
             DrawFrameTo(prevFrame->GetRawData(), prevFrameRect,
                         prevFrame->PaletteDataLength(),
                         prevFrame->GetHasAlpha(),
-                        mAnim->compositingFrame->GetRawData(),
-                        mAnim->compositingFrame->GetRect(),
+                        mCompositingFrame->GetRawData(),
+                        mCompositingFrame->GetRect(),
                         FrameBlendMethod(prevFrame->GetBlendMethod()));
           }
         }
     }
   } else if (needToBlankComposite) {
     // If we just created the composite, it could have anything in its
     // buffers. Clear them
-    ClearFrame(mAnim->compositingFrame->GetRawData(),
-               mAnim->compositingFrame->GetRect());
+    ClearFrame(mCompositingFrame->GetRawData(),
+               mCompositingFrame->GetRect());
   }
 
   // Check if the frame we are composing wants the previous image restored after
   // it is done. Don't store it (again) if last frame wanted its image restored
   // too
   if ((nextFrameDisposalMethod == FrameBlender::kDisposeRestorePrevious) &&
       (prevFrameDisposalMethod != FrameBlender::kDisposeRestorePrevious)) {
     // We are storing the whole image.
     // It would be better if we just stored the area that nextFrame is going to
     // overwrite.
-    if (!mAnim->compositingPrevFrame) {
+    if (!mCompositingPrevFrame) {
       nsRefPtr<imgFrame> newFrame = new imgFrame;
-      nsresult rv = newFrame->InitForDecoder(mSize, SurfaceFormat::B8G8R8A8);
+      nsresult rv = newFrame->InitForDecoder(ThebesIntSize(mSize),
+                                             SurfaceFormat::B8G8R8A8);
       if (NS_FAILED(rv)) {
-        mAnim->compositingPrevFrame.reset();
+        mCompositingPrevFrame.reset();
         return false;
       }
 
-      mAnim->compositingPrevFrame = newFrame->RawAccessRef();
+      mCompositingPrevFrame = newFrame->RawAccessRef();
     }
 
-    CopyFrameImage(mAnim->compositingFrame->GetRawData(),
-                   mAnim->compositingFrame->GetRect(),
-                   mAnim->compositingPrevFrame->GetRawData(),
-                   mAnim->compositingPrevFrame->GetRect());
+    CopyFrameImage(mCompositingFrame->GetRawData(),
+                   mCompositingFrame->GetRect(),
+                   mCompositingPrevFrame->GetRawData(),
+                   mCompositingPrevFrame->GetRect());
   }
 
   // blit next frame into it's correct spot
   DrawFrameTo(nextFrame->GetRawData(), nextFrameRect,
               nextFrame->PaletteDataLength(),
               nextFrame->GetHasAlpha(),
-              mAnim->compositingFrame->GetRawData(),
-              mAnim->compositingFrame->GetRect(),
+              mCompositingFrame->GetRawData(),
+              mCompositingFrame->GetRect(),
               FrameBlendMethod(nextFrame->GetBlendMethod()));
 
   // Set timeout of CompositeFrame to timeout of frame we just composed
   // Bug 177948
   int32_t timeout = nextFrame->GetRawTimeout();
-  mAnim->compositingFrame->SetRawTimeout(timeout);
+  mCompositingFrame->SetRawTimeout(timeout);
 
   // Tell the image that it is fully 'downloaded'.
   nsresult rv =
-    mAnim->compositingFrame->ImageUpdated(mAnim->compositingFrame->GetRect());
+    mCompositingFrame->ImageUpdated(mCompositingFrame->GetRect());
   if (NS_FAILED(rv)) {
     return false;
   }
 
-  mAnim->lastCompositedFrameIndex = int32_t(aNextFrameIndex);
+  mLastCompositedFrameIndex = int32_t(aNextFrameIndex);
 
   return true;
 }
 
 //******************************************************************************
 // Fill aFrame with black. Does also clears the mask.
 void
 FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect)
@@ -543,55 +494,32 @@ FrameBlender::DrawFrameTo(const uint8_t*
 
     pixman_image_unref(src);
     pixman_image_unref(dst);
   }
 
   return NS_OK;
 }
 
-void
-FrameBlender::Discard()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // As soon as an image becomes animated, it becomes non-discardable and any
-  // timers are cancelled.
-  NS_ABORT_IF_FALSE(!mAnim, "Asked to discard for animated image!");
-
-  // Delete all the decoded frames, then clear the array.
-  ClearFrames();
-}
-
 size_t
 FrameBlender::SizeOfDecoded(gfxMemoryLocation aLocation,
                             MallocSizeOf aMallocSizeOf) const
 {
   size_t n = 0;
 
-  for (uint32_t i = 0; i < mFrames.Length(); ++i) {
-    n += mFrames[i]->SizeOfExcludingThis(aLocation, aMallocSizeOf);
+  if (mCompositingFrame) {
+    n += mCompositingFrame->SizeOfExcludingThis(aLocation, aMallocSizeOf);
   }
-
-  if (mAnim) {
-    if (mAnim->compositingFrame) {
-      n += mAnim->compositingFrame
-                ->SizeOfExcludingThis(aLocation, aMallocSizeOf);
-    }
-    if (mAnim->compositingPrevFrame) {
-      n += mAnim->compositingPrevFrame
-                ->SizeOfExcludingThis(aLocation, aMallocSizeOf);
-    }
+  if (mCompositingPrevFrame) {
+    n += mCompositingPrevFrame->SizeOfExcludingThis(aLocation, aMallocSizeOf);
   }
 
   return n;
 }
 
 void
 FrameBlender::ResetAnimation()
 {
-  if (mAnim) {
-    mAnim->lastCompositedFrameIndex = -1;
-  }
+  mLastCompositedFrameIndex = -1;
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/src/FrameBlender.h
+++ b/image/src/FrameBlender.h
@@ -3,80 +3,70 @@
  * 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_FrameBlender_h_
 #define mozilla_imagelib_FrameBlender_h_
 
 #include "mozilla/MemoryReporting.h"
+#include "gfx2DGlue.h"
 #include "gfxTypes.h"
 #include "imgFrame.h"
 #include "nsCOMPtr.h"
+#include "SurfaceCache.h"
 
 namespace mozilla {
 namespace image {
 
 /**
  * FrameBlender stores and gives access to imgFrames. It also knows how to
  * blend frames from previous to next, looping if necessary.
  *
  * All logic about when and whether to blend are external to FrameBlender.
  */
 class FrameBlender
 {
 public:
-
-  /**
-   * Create a new FrameBlender with a given frame sequence.
-   *
-   * If aSequenceToUse is not specified, it will be allocated automatically.
-   */
-  FrameBlender();
-  ~FrameBlender();
+  FrameBlender(ImageKey aImageKey, gfx::IntSize aSize)
+   : mImageKey(aImageKey)
+   , mSize(aSize)
+   , mLastCompositedFrameIndex(-1)
+   , mLoopCount(-1)
+  { }
 
   bool DoBlend(nsIntRect* aDirtyRect, uint32_t aPrevFrameIndex,
                uint32_t aNextFrameIndex);
 
   /**
-   * Get the @aIndex-th frame, including (if applicable) any results of
-   * blending.
+   * If we have a composited frame for @aFrameNum, returns it. Otherwise, returns
+   * an empty DrawableFrameRef. It is an error to call this method with
+   * aFrameNum == 0, because the first frame is never composited.
    */
-  already_AddRefed<imgFrame> GetFrame(uint32_t aIndex);
+  DrawableFrameRef GetCompositedFrame(uint32_t aFrameNum);
 
   /**
    * Get the @aIndex-th frame in the frame index, ignoring results of blending.
    */
-  already_AddRefed<imgFrame> RawGetFrame(uint32_t aIndex);
-
-  void InsertFrame(uint32_t aFrameNum, RawAccessFrameRef&& aRef);
-  void RemoveFrame(uint32_t aFrameNum);
-  void ClearFrames();
-
-  /* The total number of frames in this image. */
-  uint32_t GetNumFrames() const;
+  RawAccessFrameRef GetRawFrame(uint32_t aFrameNum);
 
   /*
    * Returns the frame's adjusted timeout. If the animation loops and the
    * timeout falls in between a certain range then the timeout is adjusted so
    * that it's never 0. If the animation does not loop then no adjustments are
    * made.
    */
   int32_t GetTimeoutForFrame(uint32_t aFrameNum);
 
   /*
    * Set number of times to loop the image.
    * @note -1 means loop forever.
    */
-  void SetLoopCount(int32_t aLoopCount);
-  int32_t GetLoopCount() const;
-
-  void Discard();
-
-  void SetSize(nsIntSize aSize) { mSize = aSize; }
+  void SetLoopCount(int32_t aLoopCount) { mLoopCount = aLoopCount; }
+  int32_t LoopCount() const { return mLoopCount; }
 
   size_t SizeOfDecoded(gfxMemoryLocation aLocation,
                        MallocSizeOf aMallocSizeOf) const;
 
   void ResetAnimation();
 
   // "Blend" method indicates how the current image is combined with the
   // previous image.
@@ -102,43 +92,16 @@ public:
   // A hint as to whether an individual frame is entirely opaque, or requires
   // alpha blending.
   enum FrameAlpha {
     kFrameHasAlpha,
     kFrameOpaque
   };
 
 private:
-
-  struct Anim
-  {
-    //! Track the last composited frame for Optimizations (See DoComposite code)
-    int32_t lastCompositedFrameIndex;
-
-    /** For managing blending of frames
-     *
-     * Some animations will use the compositingFrame to composite images
-     * and just hand this back to the caller when it is time to draw the frame.
-     * NOTE: When clearing compositingFrame, remember to set
-     *       lastCompositedFrameIndex to -1.  Code assume that if
-     *       lastCompositedFrameIndex >= 0 then compositingFrame exists.
-     */
-    RawAccessFrameRef compositingFrame;
-
-    /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
-     *
-     * The Previous Frame (all frames composited up to the current) needs to be
-     * stored in cases where the image specifies it wants the last frame back
-     * when it's done with the current frame.
-     */
-    RawAccessFrameRef compositingPrevFrame;
-
-    Anim() : lastCompositedFrameIndex(-1) { }
-  };
-
   /** Clears an area of <aFrame> with transparent black.
    *
    * @param aFrameData Target Frame data
    * @param aFrameRect The rectangle of the data pointed ot by aFrameData
    *
    * @note Does also clears the transparency mask
    */
   static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect);
@@ -169,19 +132,39 @@ private:
    */
   static nsresult DrawFrameTo(const uint8_t* aSrcData,
                               const nsIntRect& aSrcRect,
                               uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
                               uint8_t* aDstPixels, const nsIntRect& aDstRect,
                               FrameBlendMethod aBlendMethod);
 
 private: // data
-  //! All the frames of the image
-  nsTArray<RawAccessFrameRef> mFrames;
-  nsIntSize mSize;
-  Anim* mAnim;
+  ImageKey mImageKey;
+  gfx::IntSize mSize;
+
+  //! Track the last composited frame for Optimizations (See DoComposite code)
+  int32_t mLastCompositedFrameIndex;
+
+  /** For managing blending of frames
+   *
+   * Some animations will use the compositingFrame to composite images
+   * and just hand this back to the caller when it is time to draw the frame.
+   * NOTE: When clearing compositingFrame, remember to set
+   *       lastCompositedFrameIndex to -1.  Code assume that if
+   *       lastCompositedFrameIndex >= 0 then compositingFrame exists.
+   */
+  RawAccessFrameRef mCompositingFrame;
+
+  /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
+   *
+   * The Previous Frame (all frames composited up to the current) needs to be
+   * stored in cases where the image specifies it wants the last frame back
+   * when it's done with the current frame.
+   */
+  RawAccessFrameRef mCompositingPrevFrame;
+
   int32_t mLoopCount;
 };
 
 } // namespace image
 } // namespace mozilla
 
 #endif /* mozilla_imagelib_FrameBlender_h_ */
--- a/image/src/FrozenImage.cpp
+++ b/image/src/FrozenImage.cpp
@@ -8,22 +8,16 @@
 namespace mozilla {
 
 using namespace gfx;
 
 namespace image {
 
 NS_IMPL_ISUPPORTS_INHERITED0(FrozenImage, ImageWrapper)
 
-nsIntRect
-FrozenImage::FrameRect(uint32_t /* aWhichFrame - ignored */)
-{
-  return InnerImage()->FrameRect(FRAME_FIRST);
-}
-
 void
 FrozenImage::IncrementAnimationConsumers()
 {
   // Do nothing. This will prevent animation from starting if there are no other
   // instances of this image.
 }
 
 void
--- a/image/src/FrozenImage.h
+++ b/image/src/FrozenImage.h
@@ -26,17 +26,16 @@ namespace image {
  */
 class FrozenImage : public ImageWrapper
 {
   typedef gfx::SourceSurface SourceSurface;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  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_(TemporaryRef<SourceSurface>)
     GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
                                layers::ImageContainer** _retval) MOZ_OVERRIDE;
new file mode 100644
--- /dev/null
+++ b/image/src/IProgressObserver.h
@@ -0,0 +1,59 @@
+/* -*- 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_IMAGELIB_PROGRESSOBSERVER_H_
+#define MOZILLA_IMAGELIB_PROGRESSOBSERVER_H_
+
+#include "mozilla/WeakPtr.h"
+#include "nsISupports.h"
+#include "nsRect.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An interface for observing changes to image state, as reported by
+ * ProgressTracker.
+ * 
+ * This is the ImageLib-internal version of imgINotificationObserver,
+ * essentially, with implementation details that code outside of ImageLib
+ * shouldn't see.
+ *
+ * XXX(seth): It's preferable to avoid adding anything to this interface if
+ * possible.  In the long term, it would be ideal to get to a place where we can
+ * just use the imgINotificationObserver interface internally as well.
+ */
+class IProgressObserver : public SupportsWeakPtr<IProgressObserver>
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(IProgressObserver)
+
+  // Subclasses may or may not be XPCOM classes, so we just require that they
+  // implement AddRef and Release.
+  NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
+  NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
+
+  // imgINotificationObserver methods:
+  virtual void Notify(int32_t aType, const nsIntRect* aRect = nullptr) = 0;
+  virtual void OnLoadComplete(bool aLastPart) = 0;
+
+  // imgIOnloadBlocker methods:
+  virtual void BlockOnload() = 0;
+  virtual void UnblockOnload() = 0;
+
+  // Other, internal-only methods:
+  virtual void SetHasImage() = 0;
+  virtual void OnStartDecode() = 0;
+  virtual bool NotificationsDeferred() const = 0;
+  virtual void SetNotificationsDeferred(bool aDeferNotifications) = 0;
+
+protected:
+  virtual ~IProgressObserver() { }
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // MOZILLA_IMAGELIB_PROGRESSOBSERVER_H_
--- a/image/src/Image.h
+++ b/image/src/Image.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_IMAGELIB_IMAGE_H_
 #define MOZILLA_IMAGELIB_IMAGE_H_
 
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/TimeStamp.h"
 #include "gfx2DGlue.h"                // for gfxMemoryLocation
 #include "imgIContainer.h"
 #include "ProgressTracker.h"
 #include "ImageURL.h"
 #include "nsStringFwd.h"
 
 class nsIRequest;
 class nsIInputStream;
@@ -41,43 +42,40 @@ public:
    *
    * INIT_FLAG_NONE: Lack of flags
    *
    * INIT_FLAG_DISCARDABLE: The container should be discardable
    *
    * INIT_FLAG_DECODE_ON_DRAW: The container should decode on draw rather than
    * decoding on load.
    *
-   * INIT_FLAG_MULTIPART: The container will be used to display a stream of
-   * images in a multipart channel. If this flag is set, INIT_FLAG_DISCARDABLE
-   * and INIT_FLAG_DECODE_ON_DRAW must not be set.
+   * INIT_FLAG_TRANSIENT: The container is likely to exist for only a short time
+   * before being destroyed. (For example, containers for
+   * multipart/x-mixed-replace image parts fall into this category.) If this
+   * flag is set, INIT_FLAG_DISCARDABLE and INIT_FLAG_DECODE_ON_DRAW must not be
+   * set.
    */
   static const uint32_t INIT_FLAG_NONE           = 0x0;
   static const uint32_t INIT_FLAG_DISCARDABLE    = 0x1;
   static const uint32_t INIT_FLAG_DECODE_ON_DRAW = 0x2;
-  static const uint32_t INIT_FLAG_MULTIPART      = 0x4;
+  static const uint32_t INIT_FLAG_TRANSIENT      = 0x4;
 
   /**
    * Creates a new image container.
    *
    * @param aMimeType The mimetype of the image.
    * @param aFlags Initialization flags of the INIT_FLAG_* variety.
    */
   virtual nsresult Init(const char* aMimeType,
                         uint32_t aFlags) = 0;
 
   virtual already_AddRefed<ProgressTracker> GetProgressTracker() = 0;
   virtual void SetProgressTracker(ProgressTracker* aProgressTracker) {}
 
   /**
-   * The rectangle defining the location and size of the given frame.
-   */
-  virtual nsIntRect FrameRect(uint32_t aWhichFrame) = 0;
-
-  /**
    * The size, in bytes, occupied by the compressed source data of the image.
    * If MallocSizeOf does not work on this platform, uses a fallback approach to
    * ensure that something reasonable is always returned.
    */
   virtual size_t SizeOfSourceWithComputedFallback(
                                           MallocSizeOf aMallocSizeOf) const = 0;
 
   /**
@@ -118,22 +116,16 @@ public:
    * @param aLastPart Whether this is the final part of the underlying request.
    */
   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        nsresult aStatus,
                                        bool aLastPart) = 0;
 
   /**
-   * Called for multipart images to allow for any necessary reinitialization
-   * when there's a new part to add.
-   */
-  virtual nsresult OnNewSourceData() = 0;
-
-  /**
    * Called when the SurfaceCache discards a persistent surface belonging to
    * this image.
    */
   virtual void OnSurfaceDiscarded() = 0;
 
   virtual void SetInnerWindowID(uint64_t aInnerWindowId) = 0;
   virtual uint64_t InnerWindowID() const = 0;
 
--- a/image/src/ImageFactory.cpp
+++ b/image/src/ImageFactory.cpp
@@ -66,17 +66,17 @@ ComputeImageFlags(ImageURL* uri, bool is
   uint32_t imageFlags = Image::INIT_FLAG_NONE;
   if (isDiscardable) {
     imageFlags |= Image::INIT_FLAG_DISCARDABLE;
   }
   if (doDecodeOnDraw) {
     imageFlags |= Image::INIT_FLAG_DECODE_ON_DRAW;
   }
   if (isMultiPart) {
-    imageFlags |= Image::INIT_FLAG_MULTIPART;
+    imageFlags |= Image::INIT_FLAG_TRANSIENT;
   }
 
   return imageFlags;
 }
 
 /* static */ bool
 ImageFactory::CanRetargetOnDataAvailable(ImageURL* aURI, bool aIsMultiPart)
 {
--- a/image/src/ImageWrapper.cpp
+++ b/image/src/ImageWrapper.cpp
@@ -28,22 +28,16 @@ ImageWrapper::Init(const char* aMimeType
 }
 
 already_AddRefed<ProgressTracker>
 ImageWrapper::GetProgressTracker()
 {
   return mInnerImage->GetProgressTracker();
 }
 
-nsIntRect
-ImageWrapper::FrameRect(uint32_t aWhichFrame)
-{
-  return mInnerImage->FrameRect(aWhichFrame);
-}
-
 size_t
 ImageWrapper::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
 {
   return mInnerImage->SizeOfSourceWithComputedFallback(aMallocSizeOf);
 }
 
 size_t
 ImageWrapper::SizeOfDecoded(gfxMemoryLocation aLocation,
@@ -92,22 +86,16 @@ ImageWrapper::OnImageDataComplete(nsIReq
                                   nsISupports* aContext,
                                   nsresult aStatus,
                                   bool aLastPart)
 {
   return mInnerImage->OnImageDataComplete(aRequest, aContext, aStatus,
                                           aLastPart);
 }
 
-nsresult
-ImageWrapper::OnNewSourceData()
-{
-  return mInnerImage->OnNewSourceData();
-}
-
 void
 ImageWrapper::OnSurfaceDiscarded()
 {
   return mInnerImage->OnSurfaceDiscarded();
 }
 
 void
 ImageWrapper::SetInnerWindowID(uint64_t aInnerWindowId)
--- a/image/src/ImageWrapper.h
+++ b/image/src/ImageWrapper.h
@@ -20,17 +20,16 @@ class ImageWrapper : public Image
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGICONTAINER
 
   // Inherited methods from Image.
   virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
 
   virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
-  virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   virtual size_t
   SizeOfSourceWithComputedFallback( MallocSizeOf aMallocSizeOf) const
       MOZ_OVERRIDE;
   virtual size_t
   SizeOfDecoded(gfxMemoryLocation aLocation,
                 MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
 
@@ -44,41 +43,46 @@ public:
                                         nsISupports* aContext,
                                         nsIInputStream* aInStr,
                                         uint64_t aSourceOffset,
                                         uint32_t aCount) MOZ_OVERRIDE;
   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        nsresult aStatus,
                                        bool aLastPart) MOZ_OVERRIDE;
-  virtual nsresult OnNewSourceData() MOZ_OVERRIDE;
 
   virtual void OnSurfaceDiscarded() MOZ_OVERRIDE;
 
   virtual void SetInnerWindowID(uint64_t aInnerWindowId) MOZ_OVERRIDE;
   virtual uint64_t InnerWindowID() const MOZ_OVERRIDE;
 
   virtual bool HasError() MOZ_OVERRIDE;
   virtual void SetHasError() MOZ_OVERRIDE;
 
   virtual ImageURL* GetURI() MOZ_OVERRIDE;
 
 protected:
   explicit ImageWrapper(Image* aInnerImage)
     : mInnerImage(aInnerImage)
   {
-    NS_ABORT_IF_FALSE(aInnerImage, "Cannot wrap a null image");
+    MOZ_ASSERT(aInnerImage, "Need an image to wrap");
   }
 
   virtual ~ImageWrapper() { }
 
   /**
    * Returns a weak reference to the inner image wrapped by this ImageWrapper.
    */
-  Image* InnerImage() { return mInnerImage.get(); }
+  Image* InnerImage() const { return mInnerImage.get(); }
+
+  void SetInnerImage(Image* aInnerImage)
+  {
+    MOZ_ASSERT(aInnerImage, "Need an image to wrap");
+    mInnerImage = aInnerImage;
+  }
 
 private:
   nsRefPtr<Image> mInnerImage;
 };
 
 } // namespace image
 } // namespace mozilla
 
new file mode 100644
--- /dev/null
+++ b/image/src/MultipartImage.cpp
@@ -0,0 +1,299 @@
+/* -*- 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 "MultipartImage.h"
+
+#include "imgINotificationObserver.h"
+
+namespace mozilla {
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+class NextPartObserver : public IProgressObserver
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(NextPartObserver)
+  NS_INLINE_DECL_REFCOUNTING(NextPartObserver)
+
+  explicit NextPartObserver(MultipartImage* aOwner)
+    : mOwner(aOwner)
+  {
+    MOZ_ASSERT(mOwner);
+  }
+
+  void BeginObserving(Image* aImage)
+  {
+    MOZ_ASSERT(aImage);
+    mImage = aImage;
+
+    nsRefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+    tracker->AddObserver(this);
+  }
+
+  void FinishObservingWithoutNotifying()
+  {
+    FinishObserving(/* aNotify = */ false);
+  }
+
+  virtual void Notify(int32_t aType,
+                      const nsIntRect* aRect = nullptr) MOZ_OVERRIDE
+  {
+    if (!mImage) {
+      // We've already finished observing the last image we were given.
+      return;
+    }
+
+    if (aType == imgINotificationObserver::FRAME_COMPLETE) {
+      FinishObserving(/* aNotify = */ true);
+    }
+  }
+
+  virtual void OnLoadComplete(bool aLastPart) MOZ_OVERRIDE
+  {
+    if (!mImage) {
+      // We've already finished observing the last image we were given.
+      return;
+    }
+
+    // If there's already an error, we may never get a FRAME_COMPLETE
+    // notification, so go ahead and notify our owner right away.
+    nsRefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+    if (tracker->GetProgress() & FLAG_HAS_ERROR) {
+      FinishObserving(/* aNotify = */ true);
+    }
+  }
+
+  // Other notifications are ignored.
+  virtual void BlockOnload() MOZ_OVERRIDE { }
+  virtual void UnblockOnload() MOZ_OVERRIDE { }
+  virtual void SetHasImage() MOZ_OVERRIDE { }
+  virtual void OnStartDecode() MOZ_OVERRIDE { }
+  virtual bool NotificationsDeferred() const MOZ_OVERRIDE { return false; }
+  virtual void SetNotificationsDeferred(bool) MOZ_OVERRIDE { }
+
+private:
+  virtual ~NextPartObserver() { }
+
+  void FinishObserving(bool aNotify)
+  {
+    MOZ_ASSERT(mImage);
+
+    nsRefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+    tracker->RemoveObserver(this);
+    mImage = nullptr;
+
+    if (aNotify) {
+      mOwner->FinishTransition();
+    }
+  }
+
+  MultipartImage* mOwner;
+  nsRefPtr<Image> mImage;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation
+///////////////////////////////////////////////////////////////////////////////
+
+MultipartImage::MultipartImage(Image* aImage, ProgressTracker* aTracker)
+  : ImageWrapper(aImage)
+  , mDeferNotifications(false)
+{
+  MOZ_ASSERT(aTracker);
+  mProgressTrackerInit = new ProgressTrackerInit(this, aTracker);
+  mNextPartObserver = new NextPartObserver(this);
+
+  // Start observing the first part.
+  nsRefPtr<ProgressTracker> firstPartTracker =
+    InnerImage()->GetProgressTracker();
+  firstPartTracker->AddObserver(this);
+  InnerImage()->RequestDecode();
+  InnerImage()->IncrementAnimationConsumers();
+}
+
+MultipartImage::~MultipartImage() { }
+
+NS_IMPL_QUERY_INTERFACE_INHERITED0(MultipartImage, ImageWrapper) 
+NS_IMPL_ADDREF(MultipartImage)
+NS_IMPL_RELEASE(MultipartImage)
+
+void
+MultipartImage::BeginTransitionToPart(Image* aNextPart)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aNextPart);
+
+  if (mNextPart) {
+    NS_WARNING("Decoder not keeping up with multipart image");
+    mNextPartObserver->FinishObservingWithoutNotifying();
+  }
+
+  mNextPart = aNextPart;
+
+  // Start observing the next part; we'll complete the transition when
+  // NextPartObserver calls FinishTransition.
+  mNextPartObserver->BeginObserving(mNextPart);
+  mNextPart->RequestDecode();
+  mNextPart->IncrementAnimationConsumers();
+}
+
+void MultipartImage::FinishTransition()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mNextPart, "Should have a next part here");
+
+  // Stop observing the current part.
+  {
+    nsRefPtr<ProgressTracker> currentPartTracker =
+      InnerImage()->GetProgressTracker();
+    currentPartTracker->RemoveObserver(this);
+  }
+
+  // Make the next part become the current part.
+  mTracker->ResetForNewRequest();
+  SetInnerImage(mNextPart);
+  mNextPart = nullptr;
+  nsRefPtr<ProgressTracker> newCurrentPartTracker =
+    InnerImage()->GetProgressTracker();
+  newCurrentPartTracker->AddObserver(this);
+
+  // Finally, send all the notifications for the new current part and send a
+  // FRAME_UPDATE notification so that observers know to redraw.
+  mTracker->SyncNotifyProgress(newCurrentPartTracker->GetProgress(),
+                               nsIntRect::GetMaxSizedIntRect());
+}
+
+already_AddRefed<imgIContainer>
+MultipartImage::Unwrap()
+{
+  // Although we wrap another image, we don't allow callers to unwrap as. As far
+  // as external code is concerned, MultipartImage is atomic.
+  nsCOMPtr<imgIContainer> image = this;
+  return image.forget();
+}
+
+already_AddRefed<ProgressTracker>
+MultipartImage::GetProgressTracker()
+{
+  MOZ_ASSERT(mTracker);
+  nsRefPtr<ProgressTracker> tracker = mTracker;
+  return tracker.forget();
+}
+
+void
+MultipartImage::SetProgressTracker(ProgressTracker* aTracker)
+{
+  MOZ_ASSERT(aTracker);
+  MOZ_ASSERT(!mTracker);
+  mTracker = aTracker;
+}
+
+nsresult
+MultipartImage::OnImageDataAvailable(nsIRequest* aRequest,
+                                     nsISupports* aContext,
+                                     nsIInputStream* aInStr,
+                                     uint64_t aSourceOffset,
+                                     uint32_t aCount)
+{
+  // Note that this method is special in that we forward it to the next part if
+  // one exists, and *not* the current part.
+
+  // We may trigger notifications that will free mNextPart, so keep it alive.
+  nsRefPtr<Image> nextPart = mNextPart;
+  if (nextPart) {
+    return nextPart->OnImageDataAvailable(aRequest, aContext, aInStr,
+                                          aSourceOffset, aCount);
+  }
+
+  return InnerImage()->OnImageDataAvailable(aRequest, aContext, aInStr,
+                                            aSourceOffset, aCount);
+}
+
+nsresult
+MultipartImage::OnImageDataComplete(nsIRequest* aRequest,
+                                    nsISupports* aContext,
+                                    nsresult aStatus,
+                                    bool aLastPart)
+{
+  // Note that this method is special in that we forward it to the next part if
+  // one exists, and *not* the current part.
+
+  // We may trigger notifications that will free mNextPart, so keep it alive.
+  nsRefPtr<Image> nextPart = mNextPart;
+  if (nextPart) {
+    return nextPart->OnImageDataComplete(aRequest, aContext, aStatus,
+                                         aLastPart);
+  }
+
+  return InnerImage()->OnImageDataComplete(aRequest, aContext, aStatus,
+                                           aLastPart);
+}
+
+void
+MultipartImage::Notify(int32_t aType, const nsIntRect* aRect /* = nullptr*/)
+{
+  if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
+    mTracker->SyncNotifyProgress(FLAG_SIZE_AVAILABLE);
+  } else if (aType == imgINotificationObserver::FRAME_UPDATE) {
+    mTracker->SyncNotifyProgress(NoProgress, *aRect);
+  } else if (aType == imgINotificationObserver::FRAME_COMPLETE) {
+    mTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE);
+  } else if (aType == imgINotificationObserver::LOAD_COMPLETE) {
+    mTracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+  } else if (aType == imgINotificationObserver::DECODE_COMPLETE) {
+    mTracker->SyncNotifyProgress(FLAG_DECODE_COMPLETE);
+  } else if (aType == imgINotificationObserver::DISCARD) {
+    mTracker->OnDiscard();
+  } else if (aType == imgINotificationObserver::UNLOCKED_DRAW) {
+    mTracker->OnUnlockedDraw();
+  } else if (aType == imgINotificationObserver::IS_ANIMATED) {
+    mTracker->SyncNotifyProgress(FLAG_IS_ANIMATED);
+  } else if (aType == imgINotificationObserver::HAS_TRANSPARENCY) {
+    mTracker->SyncNotifyProgress(FLAG_HAS_TRANSPARENCY);
+  } else {
+    NS_NOTREACHED("Notification list should be exhaustive");
+  }
+}
+
+void
+MultipartImage::OnLoadComplete(bool aLastPart)
+{
+  Progress progress = FLAG_LOAD_COMPLETE;
+  if (aLastPart) {
+    progress |= FLAG_LAST_PART_COMPLETE;
+  }
+  mTracker->SyncNotifyProgress(progress);
+}
+
+void
+MultipartImage::SetHasImage()
+{
+  mTracker->OnImageAvailable();
+}
+
+void
+MultipartImage::OnStartDecode()
+{
+  mTracker->SyncNotifyProgress(FLAG_DECODE_STARTED);
+}
+
+bool
+MultipartImage::NotificationsDeferred() const
+{
+  return mDeferNotifications;
+}
+
+void
+MultipartImage::SetNotificationsDeferred(bool aDeferNotifications)
+{
+  mDeferNotifications = aDeferNotifications;
+}
+
+} // namespace image
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/image/src/MultipartImage.h
@@ -0,0 +1,90 @@
+/* -*- 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_IMAGELIB_MULTIPARTIMAGE_H_
+#define MOZILLA_IMAGELIB_MULTIPARTIMAGE_H_
+
+#include "ImageWrapper.h"
+#include "IProgressObserver.h"
+#include "ProgressTracker.h"
+
+namespace mozilla {
+namespace image {
+
+class NextPartObserver;
+
+/**
+ * An Image wrapper that implements support for multipart/x-mixed-replace
+ * images.
+ */
+class MultipartImage
+  : public ImageWrapper
+  , public IProgressObserver
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_TYPENAME(MultipartImage)
+  NS_DECL_ISUPPORTS
+
+  MultipartImage(Image* aImage, ProgressTracker* aTracker);
+
+  void BeginTransitionToPart(Image* aNextPart);
+
+  // Overridden ImageWrapper methods:
+  virtual already_AddRefed<imgIContainer> Unwrap() MOZ_OVERRIDE;
+  virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
+  virtual void SetProgressTracker(ProgressTracker* aTracker) MOZ_OVERRIDE;
+  virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+                                        nsISupports* aContext,
+                                        nsIInputStream* aInStr,
+                                        uint64_t aSourceOffset,
+                                        uint32_t aCount) MOZ_OVERRIDE;
+  virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
+                                       nsISupports* aContext,
+                                       nsresult aStatus,
+                                       bool aLastPart) MOZ_OVERRIDE;
+
+  // We don't support locking or track animation consumers for individual parts,
+  // so we override these methods to do nothing.
+  NS_IMETHOD LockImage() MOZ_OVERRIDE { return NS_OK; }
+  NS_IMETHOD UnlockImage() MOZ_OVERRIDE { return NS_OK; }
+  virtual void IncrementAnimationConsumers() MOZ_OVERRIDE { }
+  virtual void DecrementAnimationConsumers() MOZ_OVERRIDE { }
+#ifdef DEBUG
+  virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE { return 1; }
+#endif
+
+  // Overridden IProgressObserver methods:
+  virtual void Notify(int32_t aType,
+                      const nsIntRect* aRect = nullptr) MOZ_OVERRIDE;
+  virtual void OnLoadComplete(bool aLastPart) MOZ_OVERRIDE;
+  virtual void SetHasImage() MOZ_OVERRIDE;
+  virtual void OnStartDecode() MOZ_OVERRIDE;
+  virtual bool NotificationsDeferred() const MOZ_OVERRIDE;
+  virtual void SetNotificationsDeferred(bool aDeferNotifications) MOZ_OVERRIDE;
+
+  // We don't allow multipart images to block onload, so we override these
+  // methods to do nothing.
+  virtual void BlockOnload() MOZ_OVERRIDE { }
+  virtual void UnblockOnload() MOZ_OVERRIDE { }
+
+protected:
+  virtual ~MultipartImage();
+
+private:
+  friend class NextPartObserver;
+
+  void FinishTransition();
+
+  nsRefPtr<ProgressTracker> mTracker;
+  nsAutoPtr<ProgressTrackerInit> mProgressTrackerInit;
+  nsRefPtr<NextPartObserver> mNextPartObserver;
+  nsRefPtr<Image> mNextPart;
+  bool mDeferNotifications : 1;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // MOZILLA_IMAGELIB_MULTIPARTIMAGE_H_
--- a/image/src/OrientedImage.cpp
+++ b/image/src/OrientedImage.cpp
@@ -21,39 +21,16 @@ namespace mozilla {
 using namespace gfx;
 using layers::LayerManager;
 using layers::ImageContainer;
 
 namespace image {
 
 NS_IMPL_ISUPPORTS_INHERITED0(OrientedImage, ImageWrapper)
 
-nsIntRect
-OrientedImage::FrameRect(uint32_t aWhichFrame)
-{
-  nsresult rv;
-
-  // Retrieve the frame rect of the inner image.
-  nsIntRect innerRect = InnerImage()->FrameRect(aWhichFrame);
-  if (mOrientation.IsIdentity()) {
-    return innerRect;
-  }
-
-  // Get the underlying image's dimensions.
-  nsIntSize size;
-  rv = InnerImage()->GetWidth(&size.width);
-  NS_ENSURE_SUCCESS(rv, innerRect);
-  rv = InnerImage()->GetHeight(&size.height);
-  NS_ENSURE_SUCCESS(rv, innerRect);
-
-  // Transform the frame rect.
-  gfxRect finalRect = OrientationMatrix(size).TransformBounds(innerRect);
-  return nsIntRect(finalRect.x, finalRect.y, finalRect.width, finalRect.height);
-}
-
 NS_IMETHODIMP
 OrientedImage::GetWidth(int32_t* aWidth)
 {
   if (mOrientation.SwapsWidthAndHeight()) {
     return InnerImage()->GetHeight(aWidth);
   } else {
     return InnerImage()->GetWidth(aWidth);
   }
--- a/image/src/OrientedImage.h
+++ b/image/src/OrientedImage.h
@@ -23,18 +23,16 @@ namespace image {
  */
 class OrientedImage : public ImageWrapper
 {
   typedef gfx::SourceSurface SourceSurface;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  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_(TemporaryRef<SourceSurface>)
     GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
                                layers::ImageContainer** _retval) MOZ_OVERRIDE;
--- a/image/src/ProgressTracker.cpp
+++ b/image/src/ProgressTracker.cpp
@@ -3,17 +3,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/. */
 
 #include "ImageLogging.h"
 #include "ProgressTracker.h"
 
 #include "imgIContainer.h"
-#include "imgRequestProxy.h"
+#include "imgINotificationObserver.h"
+#include "imgIRequest.h"
 #include "Image.h"
 #include "nsNetUtil.h"
 #include "nsIObserverService.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Services.h"
 
 using mozilla::WeakPtr;
@@ -23,20 +24,20 @@ namespace image {
 
 ProgressTrackerInit::ProgressTrackerInit(Image* aImage,
                                          ProgressTracker* aTracker)
 {
   MOZ_ASSERT(aImage);
 
   if (aTracker) {
     mTracker = aTracker;
-    mTracker->SetImage(aImage);
   } else {
-    mTracker = new ProgressTracker(aImage);
+    mTracker = new ProgressTracker();
   }
+  mTracker->SetImage(aImage);
   aImage->SetProgressTracker(mTracker);
   MOZ_ASSERT(mTracker);
 }
 
 ProgressTrackerInit::~ProgressTrackerInit()
 {
   mTracker->ResetImage();
 }
@@ -57,38 +58,29 @@ CheckProgressConsistency(Progress aProgr
   }
   if (aProgress & FLAG_FRAME_COMPLETE) {
     MOZ_ASSERT(aProgress & FLAG_DECODE_STARTED);
   }
   if (aProgress & FLAG_LOAD_COMPLETE) {
     // No preconditions.
   }
   if (aProgress & FLAG_ONLOAD_BLOCKED) {
-    if (aProgress & FLAG_IS_MULTIPART) {
-      MOZ_ASSERT(aProgress & FLAG_ONLOAD_UNBLOCKED);
-    } else {
-      MOZ_ASSERT(aProgress & FLAG_DECODE_STARTED);
-    }
+    MOZ_ASSERT(aProgress & FLAG_DECODE_STARTED);
   }
   if (aProgress & FLAG_ONLOAD_UNBLOCKED) {
     MOZ_ASSERT(aProgress & FLAG_ONLOAD_BLOCKED);
-    MOZ_ASSERT(aProgress & (FLAG_FRAME_COMPLETE |
-                            FLAG_IS_MULTIPART |
-                            FLAG_HAS_ERROR));
+    MOZ_ASSERT(aProgress & (FLAG_FRAME_COMPLETE | FLAG_HAS_ERROR));
   }
   if (aProgress & FLAG_IS_ANIMATED) {
     MOZ_ASSERT(aProgress & FLAG_DECODE_STARTED);
     MOZ_ASSERT(aProgress & FLAG_SIZE_AVAILABLE);
   }
   if (aProgress & FLAG_HAS_TRANSPARENCY) {
     MOZ_ASSERT(aProgress & FLAG_SIZE_AVAILABLE);
   }
-  if (aProgress & FLAG_IS_MULTIPART) {
-    // No preconditions.
-  }
   if (aProgress & FLAG_LAST_PART_COMPLETE) {
     MOZ_ASSERT(aProgress & FLAG_LOAD_COMPLETE);
   }
   if (aProgress & FLAG_HAS_ERROR) {
     // No preconditions.
   }
 }
 
@@ -102,32 +94,16 @@ ProgressTracker::SetImage(Image* aImage)
 
 void
 ProgressTracker::ResetImage()
 {
   NS_ABORT_IF_FALSE(mImage, "Resetting image when it's already null!");
   mImage = nullptr;
 }
 
-void
-ProgressTracker::SetIsMultipart()
-{
-  if (mProgress & FLAG_IS_MULTIPART) {
-    return;
-  }
-
-  MOZ_ASSERT(!(mProgress & FLAG_ONLOAD_BLOCKED),
-             "Blocked onload before we knew we were multipart?");
-
-  // Set the MULTIPART flag and ensure that we never block onload.
-  mProgress |= FLAG_IS_MULTIPART | FLAG_ONLOAD_BLOCKED | FLAG_ONLOAD_UNBLOCKED;
-
-  CheckProgressConsistency(mProgress);
-}
-
 bool
 ProgressTracker::IsLoading() const
 {
   // Checking for whether OnStopRequest has fired allows us to say we're
   // loading before OnStartRequest gets called, letting the request properly
   // get removed from the cache in certain cases.
   return !(mProgress & FLAG_LOAD_COMPLETE);
 }
@@ -166,368 +142,371 @@ ProgressTracker::GetImageStatus() const
   return status;
 }
 
 // A helper class to allow us to call SyncNotify asynchronously.
 class AsyncNotifyRunnable : public nsRunnable
 {
   public:
     AsyncNotifyRunnable(ProgressTracker* aTracker,
-                        imgRequestProxy* aRequestProxy)
+                        IProgressObserver* aObserver)
       : mTracker(aTracker)
     {
       MOZ_ASSERT(NS_IsMainThread(), "Should be created on the main thread");
       MOZ_ASSERT(aTracker, "aTracker should not be null");
-      MOZ_ASSERT(aRequestProxy, "aRequestProxy should not be null");
-      mProxies.AppendElement(aRequestProxy);
+      MOZ_ASSERT(aObserver, "aObserver should not be null");
+      mObservers.AppendElement(aObserver);
     }
 
     NS_IMETHOD Run()
     {
       MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
       MOZ_ASSERT(mTracker, "mTracker should not be null");
-      for (uint32_t i = 0; i < mProxies.Length(); ++i) {
-        mProxies[i]->SetNotificationsDeferred(false);
-        mTracker->SyncNotify(mProxies[i]);
+      for (uint32_t i = 0; i < mObservers.Length(); ++i) {
+        mObservers[i]->SetNotificationsDeferred(false);
+        mTracker->SyncNotify(mObservers[i]);
       }
 
       mTracker->mRunnable = nullptr;
       return NS_OK;
     }
 
-    void AddProxy(imgRequestProxy* aRequestProxy)
+    void AddObserver(IProgressObserver* aObserver)
     {
-      mProxies.AppendElement(aRequestProxy);
+      mObservers.AppendElement(aObserver);
     }
 
-    void RemoveProxy(imgRequestProxy* aRequestProxy)
+    void RemoveObserver(IProgressObserver* aObserver)
     {
-      mProxies.RemoveElement(aRequestProxy);
+      mObservers.RemoveElement(aObserver);
     }
 
   private:
     friend class ProgressTracker;
 
     nsRefPtr<ProgressTracker> mTracker;
-    nsTArray<nsRefPtr<imgRequestProxy>> mProxies;
+    nsTArray<nsRefPtr<IProgressObserver>> mObservers;
 };
 
 void
-ProgressTracker::Notify(imgRequestProxy* proxy)
+ProgressTracker::Notify(IProgressObserver* aObserver)
 {
-  MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
+  MOZ_ASSERT(NS_IsMainThread());
+
 #ifdef PR_LOGGING
   if (mImage && mImage->GetURI()) {
     nsRefPtr<ImageURL> uri(mImage->GetURI());
     nsAutoCString spec;
     uri->GetSpec(spec);
     LOG_FUNC_WITH_PARAM(GetImgLog(),
                         "ProgressTracker::Notify async", "uri", spec.get());
   } else {
     LOG_FUNC_WITH_PARAM(GetImgLog(),
                         "ProgressTracker::Notify async", "uri", "<unknown>");
   }
 #endif
 
-  proxy->SetNotificationsDeferred(true);
+  aObserver->SetNotificationsDeferred(true);
 
-  // If we have an existing runnable that we can use, we just append this proxy
-  // to its list of proxies to be notified. This ensures we don't unnecessarily
-  // delay onload.
+  // If we have an existing runnable that we can use, we just append this
+  // observer to its list of observers to be notified. This ensures we don't
+  // unnecessarily delay onload.
   AsyncNotifyRunnable* runnable =
     static_cast<AsyncNotifyRunnable*>(mRunnable.get());
 
   if (runnable) {
-    runnable->AddProxy(proxy);
+    runnable->AddObserver(aObserver);
   } else {
-    mRunnable = new AsyncNotifyRunnable(this, proxy);
+    mRunnable = new AsyncNotifyRunnable(this, aObserver);
     NS_DispatchToCurrentThread(mRunnable);
   }
 }
 
 // A helper class to allow us to call SyncNotify asynchronously for a given,
 // fixed, state.
 class AsyncNotifyCurrentStateRunnable : public nsRunnable
 {
   public:
     AsyncNotifyCurrentStateRunnable(ProgressTracker* aProgressTracker,
-                                    imgRequestProxy* aProxy)
+                                    IProgressObserver* aObserver)
       : mProgressTracker(aProgressTracker)
-      , mProxy(aProxy)
+      , mObserver(aObserver)
     {
       MOZ_ASSERT(NS_IsMainThread(), "Should be created on the main thread");
       MOZ_ASSERT(mProgressTracker, "mProgressTracker should not be null");
-      MOZ_ASSERT(mProxy, "mProxy should not be null");
+      MOZ_ASSERT(mObserver, "mObserver should not be null");
       mImage = mProgressTracker->GetImage();
     }
 
     NS_IMETHOD Run()
     {
       MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
-      mProxy->SetNotificationsDeferred(false);
+      mObserver->SetNotificationsDeferred(false);
 
-      mProgressTracker->SyncNotify(mProxy);
+      mProgressTracker->SyncNotify(mObserver);
       return NS_OK;
     }
 
   private:
     nsRefPtr<ProgressTracker> mProgressTracker;
-    nsRefPtr<imgRequestProxy> mProxy;
+    nsRefPtr<IProgressObserver> mObserver;
 
     // We have to hold on to a reference to the tracker's image, just in case
     // it goes away while we're in the event queue.
     nsRefPtr<Image> mImage;
 };
 
 void
-ProgressTracker::NotifyCurrentState(imgRequestProxy* proxy)
+ProgressTracker::NotifyCurrentState(IProgressObserver* aObserver)
 {
-  MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
+  MOZ_ASSERT(NS_IsMainThread());
+
 #ifdef PR_LOGGING
-  nsRefPtr<ImageURL> uri;
-  proxy->GetURI(getter_AddRefs(uri));
   nsAutoCString spec;
-  uri->GetSpec(spec);
+  if (mImage && mImage->GetURI()) {
+    mImage->GetURI()->GetSpec(spec);
+  }
   LOG_FUNC_WITH_PARAM(GetImgLog(),
                       "ProgressTracker::NotifyCurrentState", "uri", spec.get());
 #endif
 
-  proxy->SetNotificationsDeferred(true);
+  aObserver->SetNotificationsDeferred(true);
 
-  nsCOMPtr<nsIRunnable> ev = new AsyncNotifyCurrentStateRunnable(this, proxy);
+  nsCOMPtr<nsIRunnable> ev = new AsyncNotifyCurrentStateRunnable(this, aObserver);
   NS_DispatchToCurrentThread(ev);
 }
 
-#define NOTIFY_IMAGE_OBSERVERS(PROXIES, FUNC) \
+#define NOTIFY_IMAGE_OBSERVERS(OBSERVERS, FUNC) \
   do { \
-    ProxyArray::ForwardIterator iter(PROXIES); \
+    ObserverArray::ForwardIterator iter(OBSERVERS); \
     while (iter.HasMore()) { \
-      nsRefPtr<imgRequestProxy> proxy = iter.GetNext().get(); \
-      if (proxy && !proxy->NotificationsDeferred()) { \
-        proxy->FUNC; \
+      nsRefPtr<IProgressObserver> observer = iter.GetNext().get(); \
+      if (observer && !observer->NotificationsDeferred()) { \
+        observer->FUNC; \
       } \
     } \
   } while (false);
 
 /* static */ void
-ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies,
+ProgressTracker::SyncNotifyInternal(ObserverArray& aObservers,
                                     bool aHasImage,
                                     Progress aProgress,
                                     const nsIntRect& aDirtyRect)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  typedef imgINotificationObserver I;
+
   if (aProgress & FLAG_SIZE_AVAILABLE) {
-    NOTIFY_IMAGE_OBSERVERS(aProxies, OnSizeAvailable());
+    NOTIFY_IMAGE_OBSERVERS(aObservers, Notify(I::SIZE_AVAILABLE));
   }
 
   if (aProgress & FLAG_DECODE_STARTED) {
-    NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartDecode());
+    NOTIFY_IMAGE_OBSERVERS(aObservers, OnStartDecode());
   }
 
   if (aProgress & FLAG_ONLOAD_BLOCKED) {
-    NOTIFY_IMAGE_OBSERVERS(aProxies, BlockOnload());
+    NOTIFY_IMAGE_OBSERVERS(aObservers, BlockOnload());
   }
 
   if (aHasImage) {
     // OnFrameUpdate
     // If there's any content in this frame at all (always true for
     // vector images, true for raster images that have decoded at
     // least one frame) then send OnFrameUpdate.
     if (!aDirtyRect.IsEmpty()) {
-      NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameUpdate(&aDirtyRect));
+      NOTIFY_IMAGE_OBSERVERS(aObservers, Notify(I::FRAME_UPDATE, &aDirtyRect));
     }
 
     if (aProgress & FLAG_FRAME_COMPLETE) {
-      NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameComplete());
+      NOTIFY_IMAGE_OBSERVERS(aObservers, Notify(I::FRAME_COMPLETE));
     }
 
     if (aProgress & FLAG_HAS_TRANSPARENCY) {
-      NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageHasTransparency());
+      NOTIFY_IMAGE_OBSERVERS(aObservers, Notify(I::HAS_TRANSPARENCY));
     }
 
     if (aProgress & FLAG_IS_ANIMATED) {
-      NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageIsAnimated());
+      NOTIFY_IMAGE_OBSERVERS(aObservers, Notify(I::IS_ANIMATED));
     }
   }
 
   // Send UnblockOnload before OnStopDecode and OnStopRequest. This allows
   // observers that can fire events when they receive those notifications to do
   // so then, instead of being forced to wait for UnblockOnload.
   if (aProgress & FLAG_ONLOAD_UNBLOCKED) {
-    NOTIFY_IMAGE_OBSERVERS(aProxies, UnblockOnload());
+    NOTIFY_IMAGE_OBSERVERS(aObservers, UnblockOnload());
   }
 
   if (aProgress & FLAG_DECODE_COMPLETE) {
     MOZ_ASSERT(aHasImage, "Stopped decoding without ever having an image?");
-    NOTIFY_IMAGE_OBSERVERS(aProxies, OnDecodeComplete());
+    NOTIFY_IMAGE_OBSERVERS(aObservers, Notify(I::DECODE_COMPLETE));
   }
 
   if (aProgress & FLAG_LOAD_COMPLETE) {
-    NOTIFY_IMAGE_OBSERVERS(aProxies,
+    NOTIFY_IMAGE_OBSERVERS(aObservers,
                            OnLoadComplete(aProgress & FLAG_LAST_PART_COMPLETE));
   }
 }
 
 void
 ProgressTracker::SyncNotifyProgress(Progress aProgress,
                                     const nsIntRect& aInvalidRect
                                                   /* = nsIntRect() */)
 {
-  MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "Use mObservers on main thread only");
 
   // Don't unblock onload if we're not blocked.
   Progress progress = Difference(aProgress);
   if (!((mProgress | progress) & FLAG_ONLOAD_BLOCKED)) {
     progress &= ~FLAG_ONLOAD_UNBLOCKED;
   }
 
   // Apply the changes.
   mProgress |= progress;
 
   CheckProgressConsistency(mProgress);
 
   // Send notifications.
-  SyncNotifyInternal(mConsumers, !!mImage, progress, aInvalidRect);
+  SyncNotifyInternal(mObservers, !!mImage, progress, aInvalidRect);
 
   if (progress & FLAG_HAS_ERROR) {
     FireFailureNotification();
   }
 }
 
 void
-ProgressTracker::SyncNotify(imgRequestProxy* proxy)
+ProgressTracker::SyncNotify(IProgressObserver* aObserver)
 {
-  MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
+  MOZ_ASSERT(NS_IsMainThread());
+
 #ifdef PR_LOGGING
-  nsRefPtr<ImageURL> uri;
-  proxy->GetURI(getter_AddRefs(uri));
   nsAutoCString spec;
-  uri->GetSpec(spec);
+  if (mImage && mImage->GetURI()) {
+    mImage->GetURI()->GetSpec(spec);
+  }
   LOG_SCOPE_WITH_PARAM(GetImgLog(),
                        "ProgressTracker::SyncNotify", "uri", spec.get());
 #endif
 
-  nsIntRect r;
+  nsIntRect rect;
   if (mImage) {
-    // XXX - Should only send partial rects here, but that needs to
-    // wait until we fix up the observer interface
-    r = mImage->FrameRect(imgIContainer::FRAME_CURRENT);
+    if (NS_FAILED(mImage->GetWidth(&rect.width)) ||
+        NS_FAILED(mImage->GetHeight(&rect.height))) {
+      // Either the image has no intrinsic size, or it has an error.
+      rect = nsIntRect::GetMaxSizedIntRect();
+    }
   }
 
-  ProxyArray array;
-  array.AppendElement(proxy);
-  SyncNotifyInternal(array, !!mImage, mProgress, r);
+  ObserverArray array;
+  array.AppendElement(aObserver);
+  SyncNotifyInternal(array, !!mImage, mProgress, rect);
 }
 
 void
-ProgressTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
-                                        nsresult aStatus)
+ProgressTracker::EmulateRequestFinished(IProgressObserver* aObserver)
 {
   MOZ_ASSERT(NS_IsMainThread(),
-             "SyncNotifyState and mConsumers are not threadsafe");
-  nsCOMPtr<imgIRequest> kungFuDeathGrip(aProxy);
+             "SyncNotifyState and mObservers are not threadsafe");
+  nsRefPtr<IProgressObserver> kungFuDeathGrip(aObserver);
 
   if (mProgress & FLAG_ONLOAD_BLOCKED && !(mProgress & FLAG_ONLOAD_UNBLOCKED)) {
-    aProxy->UnblockOnload();
+    aObserver->UnblockOnload();
   }
 
   if (!(mProgress & FLAG_LOAD_COMPLETE)) {
-    aProxy->OnLoadComplete(true);
+    aObserver->OnLoadComplete(true);
   }
 }
 
 void
-ProgressTracker::AddConsumer(imgRequestProxy* aConsumer)
+ProgressTracker::AddObserver(IProgressObserver* aObserver)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  mConsumers.AppendElementUnlessExists(aConsumer);
+  mObservers.AppendElementUnlessExists(aObserver);
 }
 
-// XXX - The last argument should go away.
 bool
-ProgressTracker::RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus)
+ProgressTracker::RemoveObserver(IProgressObserver* aObserver)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  // Remove the proxy from the list.
-  bool removed = mConsumers.RemoveElement(aConsumer);
+
+  // Remove the observer from the list.
+  bool removed = mObservers.RemoveElement(aObserver);
 
-  // Consumers can get confused if they don't get all the proper teardown
+  // Observers can get confused if they don't get all the proper teardown
   // notifications. Part ways on good terms.
-  if (removed && !aConsumer->NotificationsDeferred()) {
-    EmulateRequestFinished(aConsumer, aStatus);
+  if (removed && !aObserver->NotificationsDeferred()) {
+    EmulateRequestFinished(aObserver);
   }
 
-  // Make sure we don't give callbacks to a consumer that isn't interested in
+  // Make sure we don't give callbacks to an observer that isn't interested in
   // them any more.
   AsyncNotifyRunnable* runnable =
     static_cast<AsyncNotifyRunnable*>(mRunnable.get());
 
-  if (aConsumer->NotificationsDeferred() && runnable) {
-    runnable->RemoveProxy(aConsumer);
-    aConsumer->SetNotificationsDeferred(false);
+  if (aObserver->NotificationsDeferred() && runnable) {
+    runnable->RemoveObserver(aObserver);
+    aObserver->SetNotificationsDeferred(false);
   }
 
   return removed;
 }
 
 bool
-ProgressTracker::FirstConsumerIs(imgRequestProxy* aConsumer)
+ProgressTracker::FirstObserverIs(IProgressObserver* aObserver)
 {
-  MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
-  ProxyArray::ForwardIterator iter(mConsumers);
+  MOZ_ASSERT(NS_IsMainThread(), "Use mObservers on main thread only");
+  ObserverArray::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
-    nsRefPtr<imgRequestProxy> proxy = iter.GetNext().get();
-    if (proxy) {
-      return proxy.get() == aConsumer;
+    nsRefPtr<IProgressObserver> observer = iter.GetNext().get();
+    if (observer) {
+      return observer.get() == aObserver;
     }
   }
   return false;
 }
 
 void
 ProgressTracker::OnUnlockedDraw()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NOTIFY_IMAGE_OBSERVERS(mConsumers, OnUnlockedDraw());
+  NOTIFY_IMAGE_OBSERVERS(mObservers,
+                         Notify(imgINotificationObserver::UNLOCKED_DRAW));
 }
 
 void
 ProgressTracker::ResetForNewRequest()
 {
   MOZ_ASSERT(NS_IsMainThread());
-
-  // We're starting a new load (and if this is called more than once, this is a
-  // multipart request) so keep only the bits that carry over between loads.
-  mProgress &= FLAG_IS_MULTIPART | FLAG_HAS_ERROR |
-               FLAG_ONLOAD_BLOCKED | FLAG_ONLOAD_UNBLOCKED;
-
+  mProgress = NoProgress;
   CheckProgressConsistency(mProgress);
 }
 
 void
 ProgressTracker::OnDiscard()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NOTIFY_IMAGE_OBSERVERS(mConsumers, OnDiscard());
+  NOTIFY_IMAGE_OBSERVERS(mObservers,
+                         Notify(imgINotificationObserver::DISCARD));
 }
 
 void
 ProgressTracker::OnImageAvailable()
 {
   if (!NS_IsMainThread()) {
     // Note: SetHasImage calls Image::Lock and Image::IncrementAnimationCounter
     // so subsequent calls or dispatches which Unlock or Decrement~ should
     // be issued after this to avoid race conditions.
     NS_DispatchToMainThread(
       NS_NewRunnableMethod(this, &ProgressTracker::OnImageAvailable));
     return;
   }
 
-  NOTIFY_IMAGE_OBSERVERS(mConsumers, SetHasImage());
+  NOTIFY_IMAGE_OBSERVERS(mObservers, SetHasImage());
 }
 
 void
 ProgressTracker::FireFailureNotification()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Some kind of problem has happened with image decoding.
--- a/image/src/ProgressTracker.h
+++ b/image/src/ProgressTracker.h
@@ -8,17 +8,17 @@
 #define ProgressTracker_h__
 
 #include "mozilla/RefPtr.h"
 #include "mozilla/WeakPtr.h"
 #include "nsCOMPtr.h"
 #include "nsTObserverArray.h"
 #include "nsThreadUtils.h"
 #include "nsRect.h"
-#include "imgRequestProxy.h"
+#include "IProgressObserver.h"
 
 class imgIContainer;
 class nsIRunnable;
 
 namespace mozilla {
 namespace image {
 
 class AsyncNotifyRunnable;
@@ -31,19 +31,18 @@ enum {
   FLAG_DECODE_STARTED     = 1u << 1,  // STATUS_DECODE_STARTED
   FLAG_DECODE_COMPLETE    = 1u << 2,  // STATUS_DECODE_COMPLETE
   FLAG_FRAME_COMPLETE     = 1u << 3,  // STATUS_FRAME_COMPLETE
   FLAG_LOAD_COMPLETE      = 1u << 4,  // STATUS_LOAD_COMPLETE
   FLAG_ONLOAD_BLOCKED     = 1u << 5,
   FLAG_ONLOAD_UNBLOCKED   = 1u << 6,
   FLAG_IS_ANIMATED        = 1u << 7,  // STATUS_IS_ANIMATED
   FLAG_HAS_TRANSPARENCY   = 1u << 8,  // STATUS_HAS_TRANSPARENCY
-  FLAG_IS_MULTIPART       = 1u << 9,
-  FLAG_LAST_PART_COMPLETE = 1u << 10,
-  FLAG_HAS_ERROR          = 1u << 11  // STATUS_ERROR
+  FLAG_LAST_PART_COMPLETE = 1u << 9,
+  FLAG_HAS_ERROR          = 1u << 10  // STATUS_ERROR
 };
 
 typedef uint32_t Progress;
 
 const uint32_t NoProgress = 0;
 
 inline Progress LoadCompleteProgress(bool aLastPart,
                                      bool aError,
@@ -57,83 +56,78 @@ inline Progress LoadCompleteProgress(boo
     progress |= FLAG_HAS_ERROR;
   }
   return progress;
 }
 
 /**
  * ProgressTracker is a class that records an Image's progress through the
  * loading and decoding process, and makes it possible to send notifications to
- * imgRequestProxys, both synchronously and asynchronously.
+ * IProgressObservers, both synchronously and asynchronously.
  *
- * When a new proxy needs to be notified of the current progress of an image,
- * call the Notify() method on this class with the relevant proxy as its
- * argument, and the notifications will be replayed to the proxy asynchronously.
+ * When a new observer needs to be notified of the current progress of an image,
+ * call the Notify() method on this class with the relevant observer as its
+ * argument, and the notifications will be replayed to the observer
+ * asynchronously.
  */
 class ProgressTracker : public mozilla::SupportsWeakPtr<ProgressTracker>
 {
   virtual ~ProgressTracker() { }
 
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(ProgressTracker)
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProgressTracker)
 
-  // aImage is the image that will be passed to the observers in SyncNotify()
-  // and EmulateRequestFinished(), and must be alive as long as this instance
-  // is, because we hold a weak reference to it.
-  explicit ProgressTracker(Image* aImage)
-    : mImage(aImage)
+  ProgressTracker()
+    : mImage(nullptr)
     , mProgress(NoProgress)
   { }
 
   bool HasImage() const { return mImage; }
   already_AddRefed<Image> GetImage() const
   {
     nsRefPtr<Image> image = mImage;
     return image.forget();
   }
 
-  // Informs this ProgressTracker that it's associated with a multipart image.
-  void SetIsMultipart();
-
   // Returns whether we are in the process of loading; that is, whether we have
   // not received OnStopRequest from Necko.
   bool IsLoading() const;
 
   // Get the current image status (as in imgIRequest).
   uint32_t GetImageStatus() const;
 
   // Get the current Progress.
   Progress GetProgress() const { return mProgress; }
 
   // Schedule an asynchronous "replaying" of all the notifications that would
   // have to happen to put us in the current state.
   // We will also take note of any notifications that happen between the time
-  // Notify() is called and when we call SyncNotify on |proxy|, and replay them
-  // as well.
-  // Should be called on the main thread only, since imgRequestProxy and GetURI
-  // are not threadsafe.
-  void Notify(imgRequestProxy* proxy);
+  // Notify() is called and when we call SyncNotify on |aObserver|, and replay
+  // them as well.
+  // Should be called on the main thread only, since observers and GetURI are
+  // not threadsafe.
+  void Notify(IProgressObserver* aObserver);
 
   // Schedule an asynchronous "replaying" of all the notifications that would
   // have to happen to put us in the state we are in right now.
   // Unlike Notify(), does *not* take into account future notifications.
   // This is only useful if you do not have an imgRequest, e.g., if you are a
   // static request returned from imgIRequest::GetStaticRequest().
-  // Should be called on the main thread only, since imgRequestProxy and GetURI
-  // are not threadsafe.
-  void NotifyCurrentState(imgRequestProxy* proxy);
+  // Should be called on the main thread only, since observers and GetURI are
+  // not threadsafe.
+  void NotifyCurrentState(IProgressObserver* aObserver);
 
   // "Replay" all of the notifications that would have to happen to put us in
   // the state we're currently in.
   // Only use this if you're already servicing an asynchronous call (e.g.
   // OnStartRequest).
-  // Should be called on the main thread only, since imgRequestProxy and GetURI
-  // are not threadsafe.
-  void SyncNotify(imgRequestProxy* proxy);
+  // Should be called on the main thread only, since observers and GetURI are
+  // not threadsafe.
+  void SyncNotify(IProgressObserver* aObserver);
 
   // Get this ProgressTracker ready for a new request. This resets all the
   // state that doesn't persist between requests.
   void ResetForNewRequest();
 
   // Stateless notifications. These are dispatched and immediately forgotten
   // about. All except OnImageAvailable are main thread only.
   void OnDiscard();
@@ -150,75 +144,69 @@ public:
   // Update our state to incorporate the changes in aProgress and synchronously
   // notify our observers.
   //
   // Because this may result in recursive notifications, no decoding locks may
   // be held.  Called on the main thread only.
   void SyncNotifyProgress(Progress aProgress,
                           const nsIntRect& aInvalidRect = nsIntRect());
 
-  // We manage a set of consumers that are using an image and thus concerned
+  // We manage a set of observers that are using an image and thus concerned
   // with its loading progress. Weak pointers.
-  void AddConsumer(imgRequestProxy* aConsumer);
-  bool RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus);
-  size_t ConsumerCount() const {
-    MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
-    return mConsumers.Length();
+  void AddObserver(IProgressObserver* aObserver);
+  bool RemoveObserver(IProgressObserver* aObserver);
+  size_t ObserverCount() const {
+    MOZ_ASSERT(NS_IsMainThread(), "Use mObservers on main thread only");
+    return mObservers.Length();
   }
 
   // This is intentionally non-general because its sole purpose is to support
   // some obscure network priority logic in imgRequest. That stuff could
   // probably be improved, but it's too scary to mess with at the moment.
-  bool FirstConsumerIs(imgRequestProxy* aConsumer);
-
-  void AdoptConsumers(ProgressTracker* aTracker) {
-    MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
-    MOZ_ASSERT(aTracker);
-    mConsumers = aTracker->mConsumers;
-  }
+  bool FirstObserverIs(IProgressObserver* aObserver);
 
 private:
-  typedef nsTObserverArray<mozilla::WeakPtr<imgRequestProxy>> ProxyArray;
+  typedef nsTObserverArray<mozilla::WeakPtr<IProgressObserver>> ObserverArray;
   friend class AsyncNotifyRunnable;
   friend class AsyncNotifyCurrentStateRunnable;
   friend class ProgressTrackerInit;
 
   ProgressTracker(const ProgressTracker& aOther) MOZ_DELETE;
 
   // This method should only be called once, and only on an ProgressTracker
   // that was initialized without an image. ProgressTrackerInit automates this.
   void SetImage(Image* aImage);
 
   // Resets our weak reference to our image, for when mImage is about to go out
   // of scope.  ProgressTrackerInit automates this.
   void ResetImage();
 
-  // Send some notifications that would be necessary to make |aProxy| believe
+  // Send some notifications that would be necessary to make |aObserver| believe
   // the request is finished downloading and decoding.  We only send
-  // FLAG_REQUEST_* and FLAG_ONLOAD_UNBLOCKED, and only if necessary.
-  void EmulateRequestFinished(imgRequestProxy* aProxy, nsresult aStatus);
+  // FLAG_LOAD_COMPLETE and FLAG_ONLOAD_UNBLOCKED, and only if necessary.
+  void EmulateRequestFinished(IProgressObserver* aObserver);
 
   // Main thread only because it deals with the observer service.
   void FireFailureNotification();
 
-  // Main thread only, since imgRequestProxy calls are expected on the main
-  // thread, and mConsumers is not threadsafe.
-  static void SyncNotifyInternal(ProxyArray& aProxies,
+  // Main thread only, since notifications are expected on the main thread, and
+  // mObservers is not threadsafe.
+  static void SyncNotifyInternal(ObserverArray& aObservers,
                                  bool aHasImage, Progress aProgress,
                                  const nsIntRect& aInvalidRect);
 
   nsCOMPtr<nsIRunnable> mRunnable;
 
   // This weak ref should be set null when the image goes out of scope.
   Image* mImage;
 
-  // List of proxies attached to the image. Each proxy represents a consumer
-  // using the image. Array and/or individual elements should only be accessed
-  // on the main thread.
-  ProxyArray mConsumers;
+  // List of observers attached to the image. Each observer represents a
+  // consumer using the image. Array and/or individual elements should only be
+  // accessed on the main thread.
+  ObserverArray mObservers;
 
   Progress mProgress;
 };
 
 class ProgressTrackerInit
 {
 public:
   ProgressTrackerInit(Image* aImage, ProgressTracker* aTracker);
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -184,17 +184,17 @@ public:
 
     // Everything worked, so commit to these objects and mark ourselves ready.
     mDstRef = Move(tentativeDstRef);
     mState = eReady;
 
     // Insert the new surface into the cache immediately. We need to do this so
     // that we won't start multiple scaling jobs for the same size.
     SurfaceCache::Insert(mDstRef.get(), ImageKey(mImage.get()),
-                         RasterSurfaceKey(mDstSize.ToIntSize(), mImageFlags),
+                         RasterSurfaceKey(mDstSize.ToIntSize(), mImageFlags, 0),
                          Lifetime::Transient);
 
     return true;
   }
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     if (mState == eReady) {
@@ -238,17 +238,17 @@ public:
       mDstRef.reset();
     } else if (mState == eFinishWithError) {
       MOZ_ASSERT(NS_IsMainThread());
       NS_WARNING("HQ scaling failed");
 
       // Remove the frame from the cache since we know we don't need it.
       SurfaceCache::RemoveSurface(ImageKey(mImage.get()),
                                   RasterSurfaceKey(mDstSize.ToIntSize(),
-                                                   mImageFlags));
+                                                   mImageFlags, 0));
 
       // Release everything we're holding, too.
       mSrcRef.reset();
       mDstRef.reset();
     } else {
       // mState must be eNew, which is invalid in Run().
       MOZ_ASSERT(false, "Need to call Init() before dispatching");
     }
@@ -290,25 +290,25 @@ RasterImage::RasterImage(ProgressTracker
   mDecodeCount(0),
   mRequestedSampleSize(0),
 #ifdef DEBUG
   mFramesNotified(0),
 #endif
   mDecodingMonitor("RasterImage Decoding Monitor"),
   mDecoder(nullptr),
   mDecodeStatus(DecodeStatus::INACTIVE),
+  mFrameCount(0),
   mNotifyProgress(NoProgress),
   mNotifying(false),
   mHasSize(false),
   mDecodeOnDraw(false),
-  mMultipart(false),
+  mTransient(false),
   mDiscardable(false),
   mHasSourceData(false),
   mDecoded(false),
-  mHasFirstFrame(false),
   mHasBeenDecoded(false),
   mPendingAnimation(false),
   mAnimationFinished(false),
   mWantFullDecode(false),
   mPendingError(false)
 {
   mProgressTrackerInit = new ProgressTrackerInit(this, aProgressTracker);
 
@@ -373,27 +373,27 @@ RasterImage::Init(const char* aMimeType,
 
   // Not sure an error can happen before init, but be safe
   if (mError)
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aMimeType);
 
   // We must be non-discardable and non-decode-on-draw for
-  // multipart channels
-  NS_ABORT_IF_FALSE(!(aFlags & INIT_FLAG_MULTIPART) ||
-                    (!(aFlags & INIT_FLAG_DISCARDABLE) &&
-                     !(aFlags & INIT_FLAG_DECODE_ON_DRAW)),
-                    "Can't be discardable or decode-on-draw for multipart");
+  // transient images.
+  MOZ_ASSERT(!(aFlags & INIT_FLAG_TRANSIENT) ||
+               (!(aFlags & INIT_FLAG_DISCARDABLE) &&
+                !(aFlags & INIT_FLAG_DECODE_ON_DRAW)),
+             "Transient images can't be discardable or decode-on-draw");
 
   // Store initialization data
   mSourceDataMimeType.Assign(aMimeType);
   mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);
   mDecodeOnDraw = !!(aFlags & INIT_FLAG_DECODE_ON_DRAW);
-  mMultipart = !!(aFlags & INIT_FLAG_MULTIPART);
+  mTransient = !!(aFlags & INIT_FLAG_TRANSIENT);
 
   // Statistics
   if (mDiscardable) {
     num_discardable_containers++;
     discardable_source_bytes += mSourceData.Length();
   }
 
   // Lock this image's surfaces in the SurfaceCache if we're not discardable.
@@ -540,82 +540,78 @@ RasterImage::GetType()
   return imgIContainer::TYPE_RASTER;
 }
 
 DrawableFrameRef
 RasterImage::LookupFrameInternal(uint32_t aFrameNum,
                                  const nsIntSize& aSize,
                                  uint32_t aFlags)
 {
-  if (mAnim) {
+  if (!mAnim) {
+    NS_ASSERTION(aFrameNum == 0,
+                 "Don't ask for a frame > 0 if we're not animated!");
+    aFrameNum = 0;
+  }
+
+  if (mAnim && aFrameNum > 0) {
     MOZ_ASSERT(mFrameBlender, "mAnim but no mFrameBlender?");
-    nsRefPtr<imgFrame> frame = mFrameBlender->GetFrame(aFrameNum);
-    return frame->DrawableRef();
+    MOZ_ASSERT(DecodeFlags(aFlags) == DECODE_FLAGS_DEFAULT,
+               "Can't composite frames with non-default decode flags");
+    return mFrameBlender->GetCompositedFrame(aFrameNum);
   }
 
-  NS_ASSERTION(aFrameNum == 0,
-               "Don't ask for a frame > 0 if we're not animated!");
-
   return SurfaceCache::Lookup(ImageKey(this),
                               RasterSurfaceKey(aSize.ToIntSize(),
-                                               DecodeFlags(aFlags)));
+                                               DecodeFlags(aFlags),
+                                               aFrameNum));
 }
 
 DrawableFrameRef
 RasterImage::LookupFrame(uint32_t aFrameNum,
                          const nsIntSize& aSize,
                          uint32_t aFlags,
                          bool aShouldSyncNotify /* = true */)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mMultipart &&
-      aFrameNum == GetCurrentFrameIndex() &&
-      mMultipartDecodedFrame) {
-    // In the multipart case we prefer to use mMultipartDecodedFrame, which is
-    // the most recent one we completely decoded, rather than display the real
-    // current frame and risk severe tearing.
-    return mMultipartDecodedFrame->DrawableRef();
-  }
-
   DrawableFrameRef ref = LookupFrameInternal(aFrameNum, aSize, aFlags);
 
-  if (!ref && IsOpaque()) {
+  if (!ref && IsOpaque() && aFrameNum == 0) {
     // We can use non-premultiplied alpha frames when premultipled alpha is
     // requested, or vice versa, if this image is opaque. Try again with the bit
     // toggled.
     ref = LookupFrameInternal(aFrameNum, aSize,
                               aFlags ^ FLAG_DECODE_NO_PREMULTIPLY_ALPHA);
   }
 
   if (!ref) {
     // The OS threw this frame away. We need to redecode if we can.
     MOZ_ASSERT(!mAnim, "Animated frames should be locked");
 
     // Update our state so the decoder knows what to do.
     mFrameDecodeFlags = aFlags & DECODE_FLAGS_MASK;
     mDecoded = false;
-    mHasFirstFrame = false;
+    mFrameCount = 0;
     WantDecodedFrames(aFlags, aShouldSyncNotify);
 
     // See if we managed to redecode enough to get the frame we want.
     ref = LookupFrameInternal(aFrameNum, aSize, aFlags);
 
     if (!ref) {
       // We didn't successfully redecode, so just fail.
       return DrawableFrameRef();
     }
   }
 
-  // We will return a paletted frame if it's not marked as compositing failed
-  // so we can catch crashes for reasons we haven't investigated.
   if (ref->GetCompositingFailed()) {
     return DrawableFrameRef();
   }
 
+  MOZ_ASSERT(!ref || !ref->GetIsPaletted(), "Should not have paletted frame");
+
   return ref;
 }
 
 uint32_t
 RasterImage::GetCurrentFrameIndex() const
 {
   if (mAnim) {
     return mAnim->GetCurrentAnimationFrameIndex();
@@ -654,67 +650,24 @@ RasterImage::IsOpaque()
   if (!(progress & FLAG_DECODE_COMPLETE)) {
     return false;
   }
 
   // Other, we're opaque if FLAG_HAS_TRANSPARENCY is not set.
   return !(progress & FLAG_HAS_TRANSPARENCY);
 }
 
-nsIntRect
-RasterImage::FrameRect(uint32_t aWhichFrame)
-{
-  if (aWhichFrame > FRAME_MAX_VALUE) {
-    NS_WARNING("aWhichFrame outside valid range!");
-    return nsIntRect();
-  }
-
-  if (!mHasFirstFrame) {
-    return nsIntRect();
-  }
-
-  if (GetNumFrames() == 1) {
-    return nsIntRect(0, 0, mSize.width, mSize.height);
-  }
-
-  // We must be animated, so get the requested frame from our FrameBlender.
-  MOZ_ASSERT(mFrameBlender, "We should be animated here");
-  nsRefPtr<imgFrame> frame =
-    mFrameBlender->RawGetFrame(GetRequestedFrameIndex(aWhichFrame));
-
-  // If we have the frame, use that rectangle.
-  if (frame) {
-    return frame->GetRect();
-  }
-
-  // If the frame doesn't exist, we return the empty rectangle. It's not clear
-  // whether this is appropriate in general, but at the moment the only
-  // consumer of this method is ProgressTracker (when it wants to figure out
-  // dirty rectangles to send out batched observer updates). This should
-  // probably be revisited when we fix bug 503973.
-  return nsIntRect();
-}
-
 void
 RasterImage::OnSurfaceDiscarded()
 {
   if (mProgressTracker) {
     mProgressTracker->OnDiscard();
   }
 }
 
-uint32_t
-RasterImage::GetNumFrames() const
-{
-  if (mFrameBlender) {
-    return mFrameBlender->GetNumFrames();
-  }
-  return mHasFirstFrame ? 1 : 0;
-}
-
 //******************************************************************************
 /* readonly attribute boolean animated; */
 NS_IMETHODIMP
 RasterImage::GetAnimated(bool *aAnimated)
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
@@ -1014,82 +967,69 @@ RasterImage::InternalAddFrame(uint32_t a
   }
   frame->SetAsNonPremult(aDecodeFlags & FLAG_DECODE_NO_PREMULTIPLY_ALPHA);
 
   RawAccessFrameRef ref = frame->RawAccessRef();
   if (!ref) {
     return RawAccessFrameRef();
   }
 
-  if (GetNumFrames() == 0) {
-    bool succeeded =
-      SurfaceCache::Insert(frame, ImageKey(this),
-                           RasterSurfaceKey(mSize.ToIntSize(), aDecodeFlags),
-                           Lifetime::Persistent);
-    if (!succeeded) {
-      return RawAccessFrameRef();
-    }
-    mHasFirstFrame = true;
-    return ref;
+  bool succeeded =
+    SurfaceCache::Insert(frame, ImageKey(this),
+                         RasterSurfaceKey(mSize.ToIntSize(),
+                                          aDecodeFlags,
+                                          aFrameNum),
+                         Lifetime::Persistent);
+  if (!succeeded) {
+    return RawAccessFrameRef();
   }
 
-  if (GetNumFrames() == 1) {
+  if (aFrameNum == 1) {
     // We're becoming animated, so initialize animation stuff.
     MOZ_ASSERT(!mFrameBlender, "Already have a FrameBlender?");
     MOZ_ASSERT(!mAnim, "Already have animation state?");
-    mFrameBlender.emplace();
-    mFrameBlender->SetSize(mSize);
-    mAnim = MakeUnique<FrameAnimator>(*mFrameBlender, mAnimationMode);
+    mFrameBlender.emplace(ImageKey(this), mSize.ToIntSize());
+    mAnim = MakeUnique<FrameAnimator>(this, *mFrameBlender, mAnimationMode);
 
     // We don't support discarding animated images (See bug 414259).
     // Lock the image and throw away the key.
     //
     // Note that this is inefficient, since we could get rid of the source data
     // too. However, doing this is actually hard, because we're probably
     // mid-decode, and thus we're decoding out of the source buffer. Since we're
     // going to fix this anyway later, and since we didn't kill the source data
     // in the old world either, locking is acceptable for the moment.
     LockImage();
 
-    // Insert the first frame into the FrameBlender.
     MOZ_ASSERT(aPreviousFrame, "Must provide a previous frame when animated");
-    RawAccessFrameRef ref = aPreviousFrame->RawAccessRef();
-    if (!ref) {
-      return RawAccessFrameRef();  // Let's keep the FrameBlender consistent...
-    }
-    mFrameBlender->InsertFrame(0, Move(ref));
-
-    // Remove it from the SurfaceCache. (It's not really doing any harm there,
-    // but keeping it there could cause it to be counted twice in our memory
-    // statistics.)
-    SurfaceCache::RemoveSurface(ImageKey(this),
-                                RasterSurfaceKey(mSize.ToIntSize(),
-                                                 aDecodeFlags));
+    aPreviousFrame->SetRawAccessOnly();
 
     // If we dispose of the first frame by clearing it, then the first frame's
     // refresh area is all of itself.
     // RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR).
     int32_t frameDisposalMethod = aPreviousFrame->GetFrameDisposalMethod();
     if (frameDisposalMethod == FrameBlender::kDisposeClear ||
         frameDisposalMethod == FrameBlender::kDisposeRestorePrevious) {
       mAnim->SetFirstFrameRefreshArea(aPreviousFrame->GetRect());
     }
 
     if (mPendingAnimation && ShouldAnimate()) {
       StartAnimation();
     }
   }
 
-  // Some GIFs are huge but only have a small area that they animate. We only
-  // need to refresh that small area when frame 0 comes around again.
-  mAnim->UnionFirstFrameRefreshArea(frame->GetRect());
-
-  MOZ_ASSERT(mFrameBlender, "Should have a FrameBlender by now");
-  mFrameBlender->InsertFrame(aFrameNum, frame->RawAccessRef());
-
+  if (aFrameNum > 0) {
+    ref->SetRawAccessOnly();
+
+    // Some GIFs are huge but only have a small area that they animate. We only
+    // need to refresh that small area when frame 0 comes around again.
+    mAnim->UnionFirstFrameRefreshArea(frame->GetRect());
+  }
+
+  mFrameCount++;
   return ref;
 }
 
 nsresult
 RasterImage::SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mDecodingMonitor.AssertCurrentThreadIn();
@@ -1098,17 +1038,17 @@ RasterImage::SetSize(int32_t aWidth, int
     return NS_ERROR_FAILURE;
 
   // Ensure that we have positive values
   // XXX - Why isn't the size unsigned? Should this be changed?
   if ((aWidth < 0) || (aHeight < 0))
     return NS_ERROR_INVALID_ARG;
 
   // if we already have a size, check the new size against the old one
-  if (!mMultipart && mHasSize &&
+  if (mHasSize &&
       ((aWidth != mSize.width) ||
        (aHeight != mSize.height) ||
        (aOrientation != mOrientation))) {
     NS_WARNING("Image changed size on redecode! This should not happen!");
 
     // Make the decoder aware of the error so that it doesn't try to call
     // FinishInternal during ShutdownDecoder.
     if (mDecoder)
@@ -1149,35 +1089,34 @@ RasterImage::EnsureFrame(uint32_t aFrame
                             aPaletteDepth, aPreviousFrame);
   }
 
   // We're replacing a frame. It must be the first frame; there's no reason to
   // ever replace any other frame, since the first frame is the only one we
   // speculatively allocate without knowing what the decoder really needs.
   // XXX(seth): I'm not convinced there's any reason to support this at all. We
   // should figure out how to avoid triggering this and rip it out.
-  MOZ_ASSERT(mHasFirstFrame, "Should have the first frame");
   MOZ_ASSERT(aFrameNum == 0, "Replacing a frame other than the first?");
   MOZ_ASSERT(GetNumFrames() == 1, "Should have only one frame");
   MOZ_ASSERT(aPreviousFrame, "Need the previous frame to replace");
   MOZ_ASSERT(!mFrameBlender && !mAnim, "Shouldn't be animated");
   if (aFrameNum != 0 || !aPreviousFrame || GetNumFrames() != 1) {
     return RawAccessFrameRef();
   }
 
   MOZ_ASSERT(!aPreviousFrame->GetRect().IsEqualEdges(aFrameRect) ||
              aPreviousFrame->GetFormat() != aFormat ||
              aPreviousFrame->GetPaletteDepth() != aPaletteDepth,
              "Replacing first frame with the same kind of frame?");
 
   // Remove the old frame from the SurfaceCache.
   IntSize prevFrameSize = aPreviousFrame->GetImageSize();
   SurfaceCache::RemoveSurface(ImageKey(this),
-                              RasterSurfaceKey(prevFrameSize, aDecodeFlags));
-  mHasFirstFrame = false;
+                              RasterSurfaceKey(prevFrameSize, aDecodeFlags, 0));
+  mFrameCount = 0;
 
   // Add the new frame as usual.
   return InternalAddFrame(aFrameNum, aFrameRect, aDecodeFlags, aFormat,
                           aPaletteDepth, nullptr);
 }
 
 void
 RasterImage::DecodingComplete(imgFrame* aFinalFrame)
@@ -1189,42 +1128,22 @@ RasterImage::DecodingComplete(imgFrame* 
   }
 
   // Flag that we're done decoding.
   // XXX - these should probably be combined when we fix animated image
   // discarding with bug 500402.
   mDecoded = true;
   mHasBeenDecoded = true;
 
-  bool singleFrame = GetNumFrames() == 1;
-
   // If there's only 1 frame, mark it as optimizable. Optimizing animated images
-  // is not supported.
-  //
-  // We don't optimize the frame for multipart images because we reuse
-  // the frame.
-  if (singleFrame && !mMultipart && aFinalFrame) {
+  // is not supported. Optimizing transient images isn't worth it.
+  if (GetNumFrames() == 1 && !mTransient && aFinalFrame) {
     aFinalFrame->SetOptimizable();
   }
 
-  // Double-buffer our frame in the multipart case, since we'll start decoding
-  // into the first frame again immediately and this produces severe tearing.
-  if (mMultipart) {
-    if (singleFrame && aFinalFrame) {
-      // aFinalFrame must be the first frame since we only have one.
-      mMultipartDecodedFrame = aFinalFrame->DrawableRef();
-    } else {
-      // Don't double buffer for animated multipart images. It entails more
-      // complexity and it's not really needed since we already are smart about
-      // not displaying the still-decoding frame of an animated image. We may
-      // have already stored an extra frame, though, so we'll release it here.
-      mMultipartDecodedFrame.reset();
-    }
-  }
-
   if (mAnim) {
     mAnim->SetDoneDecoding(true);
   }
 }
 
 NS_IMETHODIMP
 RasterImage::SetAnimationMode(uint16_t aAnimationMode)
 {
@@ -1387,42 +1306,16 @@ RasterImage::AddSourceData(const char *a
                                      "sourceDataComplete()!");
 
   // Image is already decoded, we shouldn't be getting data, but it could
   // be extra garbage data at the end of a file.
   if (mDecoded) {
     return NS_OK;
   }
 
-  // Starting a new part's frames, let's clean up before we add any
-  // This needs to happen just before we start getting EnsureFrame() call(s),
-  // so that there's no gap for anything to miss us.
-  if (mMultipart && (!mDecoder || mDecoder->BytesDecoded() == 0)) {
-    // Our previous state may have been animated, so let's clean up.
-    if (mAnimating) {
-      StopAnimation();
-    }
-    mAnimationFinished = false;
-    mPendingAnimation = false;
-    if (mAnim) {
-      mAnim = nullptr;
-    }
-
-    // If we had a FrameBlender, clean it up. We'll hold on to the first frame
-    // so we have something to draw until the next frame is decoded.
-    if (mFrameBlender) {
-      nsRefPtr<imgFrame> firstFrame = mFrameBlender->RawGetFrame(0);
-      mMultipartDecodedFrame = firstFrame->DrawableRef();
-      mFrameBlender.reset();
-    }
-
-    // Remove everything stored in the surface cache for this image.
-    SurfaceCache::RemoveImage(ImageKey(this));
-  }
-
   // If we're not storing source data and we've previously gotten the size,
   // write the data directly to the decoder. (If we haven't gotten the size,
   // we'll queue up the data and write it out when we do.)
   if (!StoringSourceData() && mHasSize) {
     rv = WriteToDecoder(aBuffer, aCount, DecodeStrategy::SYNC);
     CONTAINER_ENSURE_SUCCESS(rv);
 
     rv = FinishedSomeDecoding();
@@ -1560,69 +1453,16 @@ RasterImage::OnImageDataAvailable(nsIReq
 
   NS_ABORT_IF_FALSE(bytesRead == aCount || HasError() || NS_FAILED(rv),
     "WriteToRasterImage should consume everything if ReadSegments succeeds or "
     "the image must be in error!");
 
   return rv;
 }
 
-nsresult
-RasterImage::OnNewSourceData()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsresult rv;
-
-  if (mError)
-    return NS_ERROR_FAILURE;
-
-  // The source data should be complete before calling this
-  NS_ABORT_IF_FALSE(mHasSourceData,
-                    "Calling NewSourceData before SourceDataComplete!");
-  if (!mHasSourceData)
-    return NS_ERROR_ILLEGAL_VALUE;
-
-  // Only supported for multipart channels. It wouldn't be too hard to change this,
-  // but it would involve making sure that things worked for decode-on-draw and
-  // discarding. Presently there's no need for this, so we don't.
-  NS_ABORT_IF_FALSE(mMultipart, "NewSourceData only supported for multipart");
-  if (!mMultipart)
-    return NS_ERROR_ILLEGAL_VALUE;
-
-  // We're multipart, so we shouldn't be storing source data
-  NS_ABORT_IF_FALSE(!StoringSourceData(),
-                    "Shouldn't be storing source data for multipart");
-
-  // We're not storing the source data and we got SourceDataComplete. We should
-  // have shut down the previous decoder
-  NS_ABORT_IF_FALSE(!mDecoder, "Shouldn't have a decoder in NewSourceData");
-
-  // The decoder was shut down and we didn't flag an error, so we should be decoded
-  NS_ABORT_IF_FALSE(mDecoded, "Should be decoded in NewSourceData");
-
-  // Reset some flags
-  mDecoded = false;
-  mHasSourceData = false;
-  mHasSize = false;
-  mHasFirstFrame = false;
-  mWantFullDecode = true;
-  mDecodeStatus = DecodeStatus::INACTIVE;
-
-  if (mAnim) {
-    mAnim->SetDoneDecoding(false);
-  }
-
-  // We always need the size first.
-  rv = InitDecoder(/* aDoSizeDecode = */ true);
-  CONTAINER_ENSURE_SUCCESS(rv);
-
-  return NS_OK;
-}
-
 /* static */ already_AddRefed<nsIEventTarget>
 RasterImage::GetEventTarget()
 {
   return DecodePool::Singleton()->GetEventTarget();
 }
 
 nsresult
 RasterImage::SetSourceSizeHint(uint32_t sizeHint)
@@ -1697,22 +1537,19 @@ RasterImage::Discard()
 
   // For post-operation logging
   int old_frame_count = GetNumFrames();
 
   // Delete all the decoded frames
   mFrameBlender.reset();
   SurfaceCache::RemoveImage(ImageKey(this));
 
-  // Clear the last decoded multipart frame.
-  mMultipartDecodedFrame.reset();
-
   // Flag that we no longer have decoded frames for this image
   mDecoded = false;
-  mHasFirstFrame = false;
+  mFrameCount = 0;
 
   // Notify that we discarded
   if (mProgressTracker) {
     mProgressTracker->OnDiscard();
   }
 
   mDecodeStatus = DecodeStatus::INACTIVE;
 
@@ -1738,17 +1575,17 @@ RasterImage::CanDiscard() {
          !mDecoder &&            // Can't discard with an open decoder
          !mAnim;                 // Can never discard animated images
 }
 
 // Helper method to determine if we're storing the source data in a buffer
 // or just writing it directly to the decoder
 bool
 RasterImage::StoringSourceData() const {
-  return !mMultipart;
+  return !mTransient;
 }
 
 
 // Sets up a decoder for this image. It is an error to call this function
 // when decoding is already in process (ie - when mDecoder is non-null).
 nsresult
 RasterImage::InitDecoder(bool aDoSizeDecode)
 {
@@ -2182,19 +2019,19 @@ RasterImage::CanScale(GraphicsFilter aFi
   // we're drawing to something else (e.g. a canvas) we usually have no way of
   // updating what we've drawn, so HQ scaling is useless.
   if (!gfxPrefs::ImageHQDownscalingEnabled() || !mDecoded ||
       !(aFlags & imgIContainer::FLAG_HIGH_QUALITY_SCALING) ||
       aFilter != GraphicsFilter::FILTER_GOOD) {
     return false;
   }
 
-  // We don't use the scaler for animated or multipart images to avoid doing a
+  // We don't use the scaler for animated or transient images to avoid doing a
   // bunch of work on an image that just gets thrown away.
-  if (mAnim || mMultipart) {
+  if (mAnim || mTransient) {
     return false;
   }
 
   // If target size is 1:1 with original, don't scale.
   if (aSize == mSize) {
     return false;
   }
 
@@ -2275,17 +2112,18 @@ RasterImage::DrawWithPreDownscaleIfNeede
                                           uint32_t aFlags)
 {
   DrawableFrameRef frameRef;
 
   if (CanScale(aFilter, aSize, aFlags)) {
     frameRef =
       SurfaceCache::Lookup(ImageKey(this),
                            RasterSurfaceKey(aSize.ToIntSize(),
-                                            DecodeFlags(aFlags)));
+                                            DecodeFlags(aFlags),
+                                            0));
     if (!frameRef) {
       // We either didn't have a matching scaled frame or the OS threw it away.
       // Request a new one so we'll be ready next time. For now, we'll fall back
       // to aFrameRef below.
       RequestScale(aFrameRef.get(), aFlags, aSize);
     }
     if (frameRef && !frameRef->ImageComplete()) {
       frameRef.reset();  // We're still scaling, so we can't use this yet.
@@ -2420,17 +2258,17 @@ RasterImage::UnlockImage()
                     "Calling UnlockImage with mLockCount == 0!");
   if (mLockCount == 0)
     return NS_ERROR_ABORT;
 
   // Decrement our lock count
   mLockCount--;
 
   // Unlock this image's surfaces in the SurfaceCache.
-  if (mLockCount == 0) {
+  if (mLockCount == 0 ) {
     SurfaceCache::UnlockImage(ImageKey(this));
   }
 
   // If we've decoded this image once before, we're currently decoding again,
   // and our lock count is now zero (so nothing is forcing us to keep the
   // decoded data around), try to cancel the decode and throw away whatever
   // we've decoded.
   if (mHasBeenDecoded && mDecoder && mLockCount == 0 && !mAnim) {
@@ -2804,17 +2642,18 @@ RasterImage::OptimalImageSizeForDest(con
   }
 
   nsIntSize destSize(ceil(aDest.width), ceil(aDest.height));
 
   if (CanScale(aFilter, destSize, aFlags)) {
     DrawableFrameRef frameRef =
       SurfaceCache::Lookup(ImageKey(this),
                            RasterSurfaceKey(destSize.ToIntSize(),
-                                            DecodeFlags(aFlags)));
+                                            DecodeFlags(aFlags),
+                                            0));
 
     if (frameRef && frameRef->ImageComplete()) {
         return destSize;  // We have an existing HQ scale for this size.
     }
     if (!frameRef) {
       // We could HQ scale to this size, but we haven't. Request a scale now.
       frameRef = LookupFrame(GetRequestedFrameIndex(aWhichFrame),
                              mSize, aFlags);
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -154,36 +154,37 @@ public:
 #endif
 
   virtual nsresult StartAnimation() MOZ_OVERRIDE;
   virtual nsresult StopAnimation() MOZ_OVERRIDE;
 
   // Methods inherited from Image
   nsresult Init(const char* aMimeType,
                 uint32_t aFlags) MOZ_OVERRIDE;
-  virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
+
   virtual void OnSurfaceDiscarded() MOZ_OVERRIDE;
 
   // Raster-specific methods
   static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure,
                                       const char* aFromRawSegment,
                                       uint32_t aToOffset, uint32_t aCount,
                                       uint32_t* aWriteCount);
 
   /* The total number of frames in this image. */
-  uint32_t GetNumFrames() const;
+  uint32_t GetNumFrames() const { return mFrameCount; }
 
   virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
                                MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
 
   /* Triggers discarding. */
   void Discard();
 
   /* Callbacks for decoders */
+
   /** Sets the size and inherent orientation of the container. This should only
    * be called by the decoder. This function may be called multiple times, but
    * will throw an error if subsequent calls do not match the first.
    */
   nsresult SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation);
 
   /**
    * Ensures that a given frame number exists with the given parameters, and
@@ -223,17 +224,16 @@ public:
                                         nsISupports* aContext,
                                         nsIInputStream* aInStr,
                                         uint64_t aSourceOffset,
                                         uint32_t aCount) MOZ_OVERRIDE;
   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        nsresult aStatus,
                                        bool aLastPart) MOZ_OVERRIDE;
-  virtual nsresult OnNewSourceData() MOZ_OVERRIDE;
 
   static already_AddRefed<nsIEventTarget> GetEventTarget();
 
   /**
    * A hint of the number of bytes of source data that the image contains. If
    * called early on, this can help reduce copying and reallocations by
    * appropriately preallocating the source data buffer.
    *
@@ -346,19 +346,16 @@ private: // data
   //
   // Valid flag bits are imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA
   // and imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION.
   uint32_t                   mFrameDecodeFlags;
 
   //! All the frames of the image.
   Maybe<FrameBlender>       mFrameBlender;
 
-  //! The last frame we decoded for multipart images.
-  DrawableFrameRef          mMultipartDecodedFrame;
-
   nsCOMPtr<nsIProperties>   mProperties;
 
   // IMPORTANT: if you use mAnim in a method, call EnsureImageIsDecoded() first to ensure
   // that the frames actually exist (they may have been discarded to save memory, or
   // we maybe decoding on draw).
   UniquePtr<FrameAnimator> mAnim;
 
   // Image locking.
@@ -395,31 +392,33 @@ private: // data
 
   FallibleTArray<char>       mSourceData;
 
   // Decoder and friends
   nsRefPtr<Decoder>          mDecoder;
   DecodeStatus               mDecodeStatus;
   // END LOCKED MEMBER VARIABLES
 
+  // The number of frames this image has.
+  uint32_t                   mFrameCount;
+
   // Notification state. Used to avoid recursive notifications.
   Progress                   mNotifyProgress;
   nsIntRect                  mNotifyInvalidRect;
   bool                       mNotifying:1;
 
   // Boolean flags (clustered together to conserve space):
   bool                       mHasSize:1;       // Has SetSize() been called?
   bool                       mDecodeOnDraw:1;  // Decoding on draw?
-  bool                       mMultipart:1;     // Multipart?
+  bool                       mTransient:1;     // Is the image short-lived?
   bool                       mDiscardable:1;   // Is container discardable?
   bool                       mHasSourceData:1; // Do we have source data?
 
   // Do we have the frames in decoded form?
   bool                       mDecoded:1;
-  bool                       mHasFirstFrame:1;
   bool                       mHasBeenDecoded:1;
 
   // Whether we're waiting to start animation. If we get a StartAnimation() call
   // but we don't yet have more than one frame, mPendingAnimation is set so that
   // we know to start animation later if/when we have more frames.
   bool                       mPendingAnimation:1;
 
   // Whether the animation can stop, due to running out
--- a/image/src/SurfaceCache.h
+++ b/image/src/SurfaceCache.h
@@ -74,41 +74,39 @@ private:
     , mAnimationTime(aAnimationTime)
     , mFlags(aFlags)
   { }
 
   static uint32_t HashSIC(const SVGImageContext& aSIC) {
     return aSIC.Hash();
   }
 
-  friend SurfaceKey RasterSurfaceKey(const IntSize&, const uint32_t);
+  friend SurfaceKey RasterSurfaceKey(const IntSize&, uint32_t, uint32_t);
   friend SurfaceKey VectorSurfaceKey(const IntSize&,
                                      const Maybe<SVGImageContext>&,
-                                     const float);
+                                     float);
 
   IntSize                mSize;
   Maybe<SVGImageContext> mSVGContext;
   float                  mAnimationTime;
   uint32_t               mFlags;
 };
 
 inline SurfaceKey
 RasterSurfaceKey(const gfx::IntSize& aSize,
-                 const uint32_t aFlags)
+                 uint32_t aFlags,
+                 uint32_t aFrameNum)
 {
-  // We don't care about aAnimationTime for RasterImage because it's not
-  // currently possible to store anything but the first frame in the
-  // SurfaceCache.
-  return SurfaceKey(aSize, Nothing(), 0.0f, aFlags);
+  return SurfaceKey(aSize, Nothing(), float(aFrameNum), aFlags);
 }
 
 inline SurfaceKey
 VectorSurfaceKey(const gfx::IntSize& aSize,
                  const Maybe<SVGImageContext>& aSVGContext,
-                 const float aAnimationTime)
+                 float aAnimationTime)
 {
   // We don't care about aFlags for VectorImage because none of the flags we
   // have right now influence VectorImage's rendering. If we add a new flag that
   // *does* affect how a VectorImage renders, we'll have to change this.
   return SurfaceKey(aSize, aSVGContext, aAnimationTime, 0);
 }
 
 MOZ_BEGIN_ENUM_CLASS(Lifetime, uint8_t)
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -354,22 +354,16 @@ VectorImage::Init(const char* aMimeType,
   MOZ_ASSERT(!mIsFullyLoaded && !mHaveAnimations && !mError,
              "Flags unexpectedly set before initialization");
   MOZ_ASSERT(!strcmp(aMimeType, IMAGE_SVG_XML), "Unexpected mimetype");
 
   mIsInitialized = true;
   return NS_OK;
 }
 
-nsIntRect
-VectorImage::FrameRect(uint32_t aWhichFrame)
-{
-  return nsIntRect::GetMaxSizedIntRect();
-}
-
 size_t
 VectorImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
 {
   nsIDocument* doc = mSVGDocumentWrapper->GetDocument();
   if (!doc) {
     return 0; // No document, so no memory used for the document.
   }
 
@@ -424,22 +418,16 @@ VectorImage::OnImageDataAvailable(nsIReq
                                   nsIInputStream* aInStr,
                                   uint64_t aSourceOffset,
                                   uint32_t aCount)
 {
   return OnDataAvailable(aRequest, aContext, aInStr, aSourceOffset, aCount);
 }
 
 nsresult
-VectorImage::OnNewSourceData()
-{
-  return NS_OK;
-}
-
-nsresult
 VectorImage::StartAnimation()
 {
   if (mError)
     return NS_ERROR_FAILURE;
 
   MOZ_ASSERT(ShouldAnimate(), "Should not animate!");
 
   mSVGDocumentWrapper->StartAnimation();
--- a/image/src/VectorImage.h
+++ b/image/src/VectorImage.h
@@ -35,32 +35,30 @@ public:
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_IMGICONTAINER
 
   // (no public constructor - use ImageFactory)
 
   // Methods inherited from Image
   nsresult Init(const char* aMimeType,
                 uint32_t aFlags) MOZ_OVERRIDE;
-  virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
                                MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
 
   virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
                                         nsISupports* aContext,
                                         nsIInputStream* aInStr,
                                         uint64_t aSourceOffset,
                                         uint32_t aCount) MOZ_OVERRIDE;
   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        nsresult aResult,
                                        bool aLastPart) MOZ_OVERRIDE;
-  virtual nsresult OnNewSourceData() MOZ_OVERRIDE;
 
   /**
    * Callback for SVGRootRenderingObserver.
    *
    * This just sets a dirty flag that we check in VectorImage::RequestRefresh,
    * which is called under the ticks of the refresh driver of any observing
    * documents that we may have. Only then (after all animations in this image
    * have been updated) do we send out "frame changed" notifications,
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -420,16 +420,25 @@ imgFrame::DrawableRef()
 }
 
 RawAccessFrameRef
 imgFrame::RawAccessRef()
 {
   return RawAccessFrameRef(this);
 }
 
+void
+imgFrame::SetRawAccessOnly()
+{
+  MOZ_ASSERT(mLockCount > 0, "Must hold a RawAccessFrameRef");
+  // Lock our data and throw away the key.
+  LockImageData();
+}
+
+
 imgFrame::SurfaceWithFormat
 imgFrame::SurfaceForDrawing(bool               aDoPadding,
                             bool               aDoPartialDecode,
                             bool               aDoTile,
                             gfxContext*        aContext,
                             const nsIntMargin& aPadding,
                             gfxRect&           aImageRect,
                             ImageRegion&       aRegion,
--- a/image/src/imgFrame.h
+++ b/image/src/imgFrame.h
@@ -72,16 +72,28 @@ public:
                             const nsIntSize& aSize,
                             const SurfaceFormat aFormat,
                             GraphicsFilter aFilter,
                             uint32_t aImageFlags);
 
   DrawableFrameRef DrawableRef();
   RawAccessFrameRef RawAccessRef();
 
+  /**
+   * Make this imgFrame permanently available for raw access.
+   *
+   * This is irrevocable, and should be avoided whenever possible, since it
+   * prevents this imgFrame from being optimized and makes it impossible for its
+   * volatile buffer to be freed.
+   *
+   * It is an error to call this without already holding a RawAccessFrameRef to
+   * this imgFrame.
+   */
+  void SetRawAccessOnly();
+
   bool Draw(gfxContext* aContext, const ImageRegion& aRegion,
             GraphicsFilter aFilter, uint32_t aImageFlags);
 
   nsresult ImageUpdated(const nsIntRect &aUpdateRect);
 
   IntSize GetImageSize() { return mImageSize; }
   nsIntRect GetRect() const;
   IntSize GetSize() const { return mSize; }
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -7,16 +7,17 @@
 #include "imgRequest.h"
 #include "ImageLogging.h"
 
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
 #include "ProgressTracker.h"
 #include "ImageFactory.h"
 #include "Image.h"
+#include "MultipartImage.h"
 #include "RasterImage.h"
 
 #include "nsIChannel.h"
 #include "nsICachingChannel.h"
 #include "nsIThreadRetargetableRequest.h"
 #include "nsIInputStream.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIHttpChannel.h"
@@ -57,27 +58,27 @@ NS_IMPL_ISUPPORTS(imgRequest,
                   nsIStreamListener, nsIRequestObserver,
                   nsIThreadRetargetableStreamListener,
                   nsIChannelEventSink,
                   nsIInterfaceRequestor,
                   nsIAsyncVerifyRedirectCallback)
 
 imgRequest::imgRequest(imgLoader* aLoader)
  : mLoader(aLoader)
- , mProgressTracker(new ProgressTracker(nullptr))
+ , mProgressTracker(new ProgressTracker())
  , mValidator(nullptr)
  , mInnerWindowId(0)
  , mCORSMode(imgIRequest::CORS_NONE)
  , mReferrerPolicy(mozilla::net::RP_Default)
  , mImageErrorCode(NS_OK)
  , mDecodeRequested(false)
  , mIsMultiPartChannel(false)
  , mGotData(false)
  , mIsInCache(false)
- , mResniffMimeType(false)
+ , mNewPartPending(false)
 { }
 
 imgRequest::~imgRequest()
 {
   if (mLoader) {
     mLoader->RemoveFromUncachedImages(this);
   }
   if (mURI) {
@@ -137,17 +138,17 @@ nsresult imgRequest::Init(nsIURI *aURI,
 
 void imgRequest::ClearLoader() {
   mLoader = nullptr;
 }
 
 already_AddRefed<ProgressTracker>
 imgRequest::GetProgressTracker()
 {
-  if (mImage && mGotData) {
+  if (mImage) {
     NS_ABORT_IF_FALSE(!mProgressTracker,
                       "Should have given mProgressTracker to mImage");
     return mImage->GetProgressTracker();
   } else {
     NS_ABORT_IF_FALSE(mProgressTracker,
                       "Should have mProgressTracker until we create mImage");
     nsRefPtr<ProgressTracker> progressTracker = mProgressTracker;
     MOZ_ASSERT(progressTracker);
@@ -175,44 +176,44 @@ void imgRequest::ResetCacheEntry()
 void imgRequest::AddProxy(imgRequestProxy *proxy)
 {
   NS_PRECONDITION(proxy, "null imgRequestProxy passed in");
   LOG_SCOPE_WITH_PARAM(GetImgLog(), "imgRequest::AddProxy", "proxy", proxy);
 
   // If we're empty before adding, we have to tell the loader we now have
   // proxies.
   nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
-  if (progressTracker->ConsumerCount() == 0) {
+  if (progressTracker->ObserverCount() == 0) {
     NS_ABORT_IF_FALSE(mURI, "Trying to SetHasProxies without key uri.");
     if (mLoader) {
       mLoader->SetHasProxies(this);
     }
   }
 
-  progressTracker->AddConsumer(proxy);
+  progressTracker->AddObserver(proxy);
 }
 
 nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
 {
   LOG_SCOPE_WITH_PARAM(GetImgLog(), "imgRequest::RemoveProxy", "proxy", proxy);
 
   // This will remove our animation consumers, so after removing
   // this proxy, we don't end up without proxies with observers, but still
   // have animation consumers.
   proxy->ClearAnimationConsumers();
 
   // Let the status tracker do its thing before we potentially call Cancel()
   // below, because Cancel() may result in OnStopRequest being called back
   // before Cancel() returns, leaving the image in a different state then the
   // one it was in at this point.
   nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
-  if (!progressTracker->RemoveConsumer(proxy, aStatus))
+  if (!progressTracker->RemoveObserver(proxy))
     return NS_OK;
 
-  if (progressTracker->ConsumerCount() == 0) {
+  if (progressTracker->ObserverCount() == 0) {
     // If we have no observers, there's nothing holding us alive. If we haven't
     // been cancelled and thus removed from the cache, tell the image loader so
     // we can be evicted from the cache.
     if (mCacheEntry) {
       NS_ABORT_IF_FALSE(mURI, "Removing last observer without key uri.");
 
       if (mLoader) {
         mLoader->SetHasNoProxies(this, mCacheEntry);
@@ -412,17 +413,17 @@ void imgRequest::RemoveFromCache()
   }
 
   mCacheEntry = nullptr;
 }
 
 bool imgRequest::HasConsumers()
 {
   nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
-  return progressTracker && progressTracker->ConsumerCount() > 0;
+  return progressTracker && progressTracker->ObserverCount() > 0;
 }
 
 int32_t imgRequest::Priority() const
 {
   int32_t priority = nsISupportsPriority::PRIORITY_NORMAL;
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
   if (p)
     p->GetPriority(&priority);
@@ -434,17 +435,17 @@ void imgRequest::AdjustPriority(imgReque
   // only the first proxy is allowed to modify the priority of this image load.
   //
   // XXX(darin): this is probably not the most optimal algorithm as we may want
   // to increase the priority of requests that have a lot of proxies.  the key
   // concern though is that image loads remain lower priority than other pieces
   // of content such as link clicks, CSS, and JS.
   //
   nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
-  if (!progressTracker->FirstConsumerIs(proxy))
+  if (!progressTracker->FirstObserverIs(proxy))
     return;
 
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel);
   if (p)
     p->AdjustPriority(delta);
 }
 
 void imgRequest::SetIsInCache(bool incache)
@@ -628,62 +629,46 @@ imgRequest::StartDecoding()
 
 /** nsIRequestObserver methods **/
 
 /* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
 NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
 {
   LOG_SCOPE(GetImgLog(), "imgRequest::OnStartRequest");
 
-  // Figure out if we're multipart
+  mNewPartPending = true;
+
+  // Figure out if we're multipart.
   nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));
   nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
   if (mpchan) {
     mIsMultiPartChannel = true;
-    progressTracker->SetIsMultipart();
   } else {
     NS_ABORT_IF_FALSE(!mIsMultiPartChannel, "Something went wrong");
   }
 
   // If we're not multipart, we shouldn't have an image yet
   NS_ABORT_IF_FALSE(mIsMultiPartChannel || !mImage,
                     "Already have an image for non-multipart request");
 
-  // If we're multipart and about to load another image, signal so we can
-  // detect the mime type in OnDataAvailable.
-  if (mIsMultiPartChannel && mImage) {
-    mResniffMimeType = true;
-
-    // Tell the image to reinitialize itself. We have to do this in
-    // OnStartRequest so that its state machine is always in a consistent
-    // state.
-    // Note that if our MIME type changes, mImage will be replaced with a
-    // new object.
-    mImage->OnNewSourceData();
-  }
-
   /*
    * If mRequest is null here, then we need to set it so that we'll be able to
    * cancel it if our Cancel() method is called.  Note that this can only
    * happen for multipart channels.  We could simply not null out mRequest for
    * non-last parts, if GetIsLastPart() were reliable, but it's not.  See
    * https://bugzilla.mozilla.org/show_bug.cgi?id=339610
    */
   if (!mRequest) {
     NS_ASSERTION(mpchan,
                  "We should have an mRequest here unless we're multipart");
     nsCOMPtr<nsIChannel> chan;
     mpchan->GetBaseChannel(getter_AddRefs(chan));
     mRequest = chan;
   }
 
-  // Note: refreshing progressTracker in case OnNewSourceData changed it.
-  progressTracker = GetProgressTracker();
-  progressTracker->ResetForNewRequest();
-
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
   if (channel)
     channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
 
   /* Get our principal */
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
   if (chan) {
     nsCOMPtr<nsIScriptSecurityManager> secMan = nsContentUtils::GetSecurityManager();
@@ -696,17 +681,17 @@ NS_IMETHODIMP imgRequest::OnStartRequest
     }
   }
 
   SetCacheValidation(mCacheEntry, aRequest);
 
   mApplicationCache = GetApplicationCache(aRequest);
 
   // Shouldn't we be dead already if this gets hit?  Probably multipart/x-mixed-replace...
-  if (progressTracker->ConsumerCount() == 0) {
+  if (progressTracker->ObserverCount() == 0) {
     this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
   }
 
   // Try to retarget OnDataAvailable to a decode thread.
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
   nsCOMPtr<nsIThreadRetargetableRequest> retargetable =
     do_QueryInterface(aRequest);
   if (httpChannel && retargetable &&
@@ -833,26 +818,22 @@ imgRequest::OnDataAvailable(nsIRequest *
                             nsIInputStream *inStr, uint64_t sourceOffset,
                             uint32_t count)
 {
   LOG_SCOPE_WITH_PARAM(GetImgLog(), "imgRequest::OnDataAvailable", "count", count);
 
   NS_ASSERTION(aRequest, "imgRequest::OnDataAvailable -- no request!");
 
   nsresult rv;
-
-  if (!mGotData || mResniffMimeType) {
-    LOG_SCOPE(GetImgLog(), "imgRequest::OnDataAvailable |First time through... finding mimetype|");
+  mGotData = true;
 
-    mGotData = true;
+  if (mNewPartPending) {
+    LOG_SCOPE(GetImgLog(), "imgRequest::OnDataAvailable |New part; finding MIME type|");
 
-    // Store and reset this for the invariant that it's always false after
-    // calls to OnDataAvailable (see bug 907575)
-    bool resniffMimeType = mResniffMimeType;
-    mResniffMimeType = false;
+    mNewPartPending = false;
 
     mimetype_closure closure;
     nsAutoCString newType;
     closure.newType = &newType;
 
     /* look at the first few bytes and see if we can tell what the data is from that
      * since servers tend to lie. :(
      */
@@ -876,75 +857,76 @@ imgRequest::OnDataAvailable(nsIRequest *
         this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
 
         return NS_BINDING_ABORTED;
       }
 
       LOG_MSG(GetImgLog(), "imgRequest::OnDataAvailable", "Got content type from the channel");
     }
 
-    // If we're a regular image and this is the first call to OnDataAvailable,
-    // this will always be true. If we've resniffed our MIME type (i.e. we're a
-    // multipart/x-mixed-replace image), we have to be able to switch our image
-    // type and decoder.
-    // We always reinitialize for SVGs, because they have no way of
-    // reinitializing themselves.
-    if (mContentType != newType || newType.EqualsLiteral(IMAGE_SVG_XML)) {
-      mContentType = newType;
+    mContentType = newType;
+    SetProperties(chan);
+    bool firstPart = !mImage;
+
+    LOG_MSG_WITH_PARAM(GetImgLog(), "imgRequest::OnDataAvailable", "content type", mContentType.get());
 
-      // If we've resniffed our MIME type and it changed, we need to create a
-      // new status tracker to give to the image, because we don't have one of
-      // our own any more.
-      if (resniffMimeType) {
-        MOZ_ASSERT(mIsMultiPartChannel, "Resniffing a non-multipart image");
+    // XXX If server lied about mimetype and it's SVG, we may need to copy
+    // the data and dispatch back to the main thread, AND tell the channel to
+    // dispatch there in the future.
 
-        // Initialize a new status tracker.
-        nsRefPtr<ProgressTracker> freshTracker = new ProgressTracker(nullptr);
-        freshTracker->SetIsMultipart();
+    // Create the new image and give it ownership of our ProgressTracker.
+    if (mIsMultiPartChannel) {
+      // Create the ProgressTracker and image for this part.
+      nsRefPtr<ProgressTracker> progressTracker = new ProgressTracker();
+      nsRefPtr<Image> image =
+        ImageFactory::CreateImage(aRequest, progressTracker, mContentType,
+                                  mURI, /* aIsMultipart = */ true,
+                                  static_cast<uint32_t>(mInnerWindowId));
 
-        // Replace the old status tracker with it.
-        nsRefPtr<ProgressTracker> oldProgressTracker = GetProgressTracker();
-        freshTracker->AdoptConsumers(oldProgressTracker);
-        mProgressTracker = freshTracker.forget();
+      if (!mImage) {
+        // First part for a multipart channel. Create the MultipartImage wrapper.
+        MOZ_ASSERT(mProgressTracker, "Shouldn't have given away tracker yet");
+        mImage = new MultipartImage(image, mProgressTracker);
+        mProgressTracker = nullptr;
+      } else {
+        // Transition to the new part.
+        static_cast<MultipartImage*>(mImage.get())->BeginTransitionToPart(image);
       }
-
-      SetProperties(chan);
-
-      LOG_MSG_WITH_PARAM(GetImgLog(), "imgRequest::OnDataAvailable", "content type", mContentType.get());
+    } else {
+      MOZ_ASSERT(!mImage, "New part for non-multipart channel?");
+      MOZ_ASSERT(mProgressTracker, "Shouldn't have given away tracker yet");
 
-      // XXX If server lied about mimetype and it's SVG, we may need to copy
-      // the data and dispatch back to the main thread, AND tell the channel to
-      // dispatch there in the future.
+      // Create an image using our progress tracker.
+      mImage =
+        ImageFactory::CreateImage(aRequest, mProgressTracker, mContentType,
+                                  mURI, /* aIsMultipart = */ false,
+                                  static_cast<uint32_t>(mInnerWindowId));
+      mProgressTracker = nullptr;
+    }
 
-      // Now we can create a new image to hold the data. If we don't have a decoder
-      // for this mimetype we'll find out about it here.
-      mImage = ImageFactory::CreateImage(aRequest, mProgressTracker, mContentType,
-                                         mURI, mIsMultiPartChannel,
-                                         static_cast<uint32_t>(mInnerWindowId));
-
-      // Release our copy of the status tracker since the image owns it now.
-      mProgressTracker = nullptr;
-
+    if (firstPart) {
       // Notify listeners that we have an image.
       nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
       progressTracker->OnImageAvailable();
+      MOZ_ASSERT(progressTracker->HasImage());
+    }
 
-      if (mImage->HasError() && !mIsMultiPartChannel) { // Probably bad mimetype
-        // We allow multipart images to fail to initialize without cancelling the
-        // load because subsequent images might be fine; thus only single part
-        // images end up here.
-        this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
-        return NS_BINDING_ABORTED;
-      }
+    if (mImage->HasError() && !mIsMultiPartChannel) { // Probably bad mimetype
+      // We allow multipart images to fail to initialize without cancelling the
+      // load because subsequent images might be fine; thus only single part
+      // images end up here.
+      this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
+      return NS_BINDING_ABORTED;
+    }
 
-      NS_ABORT_IF_FALSE(progressTracker->HasImage(), "Status tracker should have an image!");
-      NS_ABORT_IF_FALSE(mImage, "imgRequest should have an image!");
+    MOZ_ASSERT(!mProgressTracker, "Should've given tracker to image");
+    MOZ_ASSERT(mImage, "Should have image");
 
-      if (mDecodeRequested)
-        mImage->StartDecoding();
+    if (mDecodeRequested) {
+      mImage->StartDecoding();
     }
   }
 
   // Notify the image that it has new data.
   rv = mImage->OnImageDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
 
   if (NS_FAILED(rv)) {
     PR_LOG(GetImgLog(), PR_LOG_WARNING,
--- a/image/src/imgRequest.h
+++ b/image/src/imgRequest.h
@@ -267,12 +267,12 @@ private:
   // Sometimes consumers want to do things before the image is ready. Let them,
   // and apply the action when the image becomes available.
   bool mDecodeRequested : 1;
 
   bool mIsMultiPartChannel : 1;
   bool mGotData : 1;
   bool mIsInCache : 1;
   bool mBlockingOnload : 1;
-  bool mResniffMimeType : 1;
+  bool mNewPartPending : 1;
 };
 
 #endif
--- a/image/src/imgRequestProxy.cpp
+++ b/image/src/imgRequestProxy.cpp
@@ -729,108 +729,62 @@ void imgRequestProxy::OnStartDecode()
     // OnStartDecodes which indicates the beginning of a new decode.  The cache
     // entry's size therefore needs to be reset to 0 here.  If we do not do
     // this, the code in ProgressTrackerObserver::OnStopFrame will continue to
     // increase the data size cumulatively.
     GetOwner()->ResetCacheEntry();
   }
 }
 
-void imgRequestProxy::OnSizeAvailable()
-{
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnStartContainer");
-
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::SIZE_AVAILABLE, nullptr);
-  }
-}
-
-void imgRequestProxy::OnFrameUpdate(const nsIntRect * rect)
+static const char*
+NotificationTypeToString(int32_t aType)
 {
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnFrameUpdate");
-
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::FRAME_UPDATE, rect);
-  }
-}
-
-void imgRequestProxy::OnFrameComplete()
-{
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnFrameComplete");
-
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::FRAME_COMPLETE, nullptr);
-  }
-}
-
-void imgRequestProxy::OnDecodeComplete()
-{
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnDecodeComplete");
-
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::DECODE_COMPLETE, nullptr);
+  switch(aType)
+  {
+    case imgINotificationObserver::SIZE_AVAILABLE: return "SIZE_AVAILABLE";
+    case imgINotificationObserver::FRAME_UPDATE: return "FRAME_UPDATE";
+    case imgINotificationObserver::FRAME_COMPLETE: return "FRAME_COMPLETE";
+    case imgINotificationObserver::LOAD_COMPLETE: return "LOAD_COMPLETE";
+    case imgINotificationObserver::DECODE_COMPLETE: return "DECODE_COMPLETE";
+    case imgINotificationObserver::DISCARD: return "DISCARD";
+    case imgINotificationObserver::UNLOCKED_DRAW: return "UNLOCKED_DRAW";
+    case imgINotificationObserver::IS_ANIMATED: return "IS_ANIMATED";
+    case imgINotificationObserver::HAS_TRANSPARENCY: return "HAS_TRANSPARENCY";
+    default:
+      NS_NOTREACHED("Notification list should be exhaustive");
+      return "(unknown notification)";
   }
 }
 
-void imgRequestProxy::OnDiscard()
+void
+imgRequestProxy::Notify(int32_t aType, const nsIntRect* aRect)
 {
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnDiscard");
+  MOZ_ASSERT(aType != imgINotificationObserver::LOAD_COMPLETE,
+             "Should call OnLoadComplete");
 
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::DISCARD, nullptr);
+  LOG_FUNC_WITH_PARAM(GetImgLog(), "imgRequestProxy::Notify", "type",
+                      NotificationTypeToString(aType));
+
+  if (!mListener || mCanceled) {
+    return;
   }
-}
-
-void imgRequestProxy::OnUnlockedDraw()
-{
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnUnlockedDraw");
 
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::UNLOCKED_DRAW, nullptr);
-  }
+  // Make sure the listener stays alive while we notify.
+  nsCOMPtr<imgINotificationObserver> listener(mListener);
+
+  mListener->Notify(this, aType, aRect);
 }
 
-void imgRequestProxy::OnImageHasTransparency()
-{
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnImageHasTransparency");
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::HAS_TRANSPARENCY, nullptr);
-  }
-}
-
-void imgRequestProxy::OnImageIsAnimated()
-{
-  LOG_FUNC(GetImgLog(), "imgRequestProxy::OnImageIsAnimated");
-  if (mListener && !mCanceled) {
-    // Hold a ref to the listener while we call it, just in case.
-    nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
-    mListener->Notify(this, imgINotificationObserver::IS_ANIMATED, nullptr);
-  }
-}
-
-void imgRequestProxy::OnLoadComplete(bool aLastPart)
+void
+imgRequestProxy::OnLoadComplete(bool aLastPart)
 {
 #ifdef PR_LOGGING
   nsAutoCString name;
   GetName(name);
-  LOG_FUNC_WITH_PARAM(GetImgLog(), "imgRequestProxy::OnStopRequest", "name", name.get());
+  LOG_FUNC_WITH_PARAM(GetImgLog(), "imgRequestProxy::OnLoadComplete", "name", name.get());
 #endif
   // There's all sorts of stuff here that could kill us (the OnStopRequest call
   // on the listener, the removal from the loadgroup, the release of the
   // listener, etc).  Don't let them do it.
   nsCOMPtr<imgIRequest> kungFuDeathGrip(this);
 
   if (mListener && !mCanceled) {
     // Hold a ref to the listener while we call it, just in case.
@@ -858,31 +812,33 @@ void imgRequestProxy::OnLoadComplete(boo
     // everything.  Note that this can cancel us and other fun things
     // like that.  Don't add anything in this method after this point.
     imgINotificationObserver* obs = mListener;
     mListenerIsStrongRef = false;
     NS_RELEASE(obs);
   }
 }
 
-void imgRequestProxy::BlockOnload()
+void
+imgRequestProxy::BlockOnload()
 {
 #ifdef PR_LOGGING
   nsAutoCString name;
   GetName(name);
   LOG_FUNC_WITH_PARAM(GetImgLog(), "imgRequestProxy::BlockOnload", "name", name.get());
 #endif
 
   nsCOMPtr<imgIOnloadBlocker> blocker = do_QueryInterface(mListener);
   if (blocker) {
     blocker->BlockOnload(this);
   }
 }
 
-void imgRequestProxy::UnblockOnload()
+void
+imgRequestProxy::UnblockOnload()
 {
 #ifdef PR_LOGGING
   nsAutoCString name;
   GetName(name);
   LOG_FUNC_WITH_PARAM(GetImgLog(), "imgRequestProxy::UnblockOnload", "name", name.get());
 #endif
 
   nsCOMPtr<imgIOnloadBlocker> blocker = do_QueryInterface(mListener);
--- a/image/src/imgRequestProxy.h
+++ b/image/src/imgRequestProxy.h
@@ -2,29 +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 imgRequestProxy_h__
 #define imgRequestProxy_h__
 
-#include "mozilla/WeakPtr.h"
 #include "imgIRequest.h"
 #include "nsISecurityInfoProvider.h"
 
 #include "nsILoadGroup.h"
 #include "nsISupportsPriority.h"
 #include "nsITimedChannel.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "mozilla/TimeStamp.h"
 
 #include "imgRequest.h"
+#include "IProgressObserver.h"
 
 #define NS_IMGREQUESTPROXY_CID \
 { /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */         \
      0x20557898,                                     \
      0x1dd2,                                         \
      0x11b2,                                         \
     {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
 }
@@ -39,20 +39,20 @@ namespace mozilla {
 namespace image {
 class Image;
 class ImageURL;
 class ProgressTracker;
 } // namespace image
 } // namespace mozilla
 
 class imgRequestProxy : public imgIRequest,
+                        public mozilla::image::IProgressObserver,
                         public nsISupportsPriority,
                         public nsISecurityInfoProvider,
-                        public nsITimedChannel,
-                        public mozilla::SupportsWeakPtr<imgRequestProxy>
+                        public nsITimedChannel
 {
 protected:
   virtual ~imgRequestProxy();
 
 public:
   typedef mozilla::image::Image Image;
   typedef mozilla::image::ImageURL ImageURL;
   typedef mozilla::image::ProgressTracker ProgressTracker;
@@ -90,30 +90,40 @@ public:
   // notification is scheduled.
   void NotifyListener();
 
   // Synchronously notify this proxy's listener of the current state of the
   // image. Only use this function if you are currently servicing an
   // asynchronously-called function.
   void SyncNotifyListener();
 
+  // imgINotificationObserver methods:
+  virtual void Notify(int32_t aType,
+                      const nsIntRect* aRect = nullptr) MOZ_OVERRIDE;
+  virtual void OnLoadComplete(bool aLastPart) MOZ_OVERRIDE;
+
+  // imgIOnloadBlocker methods:
+  virtual void BlockOnload() MOZ_OVERRIDE;
+  virtual void UnblockOnload() MOZ_OVERRIDE;
+
+  // Other, internal-only methods:
+  virtual void SetHasImage() MOZ_OVERRIDE;
+  virtual void OnStartDecode() MOZ_OVERRIDE;
+
   // Whether we want notifications from ProgressTracker to be deferred until
   // an event it has scheduled has been fired.
-  bool NotificationsDeferred() const
+  virtual bool NotificationsDeferred() const MOZ_OVERRIDE
   {
     return mDeferNotifications;
   }
-  void SetNotificationsDeferred(bool aDeferNotifications)
+  virtual void SetNotificationsDeferred(bool aDeferNotifications) MOZ_OVERRIDE
   {
     mDeferNotifications = aDeferNotifications;
   }
 
-  // XXXbholley - This eventually gets folded into the new notification API.
-  void SetHasImage();
-
   // Removes all animation consumers that were created with
   // IncrementAnimationConsumers. This is necessary since we need
   // to do it before the proxy itself is destroyed. See
   // imgRequest::RemoveProxy
   void ClearAnimationConsumers();
 
   virtual nsresult Clone(imgINotificationObserver* aObserver, imgRequestProxy** aClone);
   nsresult GetStaticRequest(imgRequestProxy** aReturn);
@@ -140,37 +150,16 @@ protected:
         return NS_OK;
       }
 
     private:
       nsRefPtr<imgRequestProxy> mOwner;
       nsresult mStatus;
   };
 
-  // The following notification functions are protected to ensure that (friend
-  // class) ProgressTracker is the only class allowed to send us
-  // notifications.
-
-  void OnStartDecode();
-  void OnSizeAvailable();
-  void OnFrameUpdate(const nsIntRect* aRect);
-  void OnFrameComplete();
-  void OnDecodeComplete();
-  void OnDiscard();
-  void OnUnlockedDraw();
-  void OnImageHasTransparency();
-  void OnImageIsAnimated();
-
-  /* non-virtual sort-of-nsIRequestObserver methods */
-  void OnLoadComplete(bool aLastPart);
-
-  /* non-virtual imgIOnloadBlocker methods */
-  void BlockOnload();
-  void UnblockOnload();
-
   /* Finish up canceling ourselves */
   void DoCancel(nsresult status);
 
   /* Do the proper refcount management to null out mListener */
   void NullOutListener();
 
   void DoRemoveFromLoadGroup() {
     RemoveFromLoadGroup(true);
--- a/image/src/moz.build
+++ b/image/src/moz.build
@@ -5,18 +5,19 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'ImageOps.h',
     'ImageRegion.h',
     'imgLoader.h',
     'imgRequest.h',
     'imgRequestProxy.h',
+    'IProgressObserver.h',
     'Orientation.h',
-    'SurfaceCache.h'
+    'SurfaceCache.h',
 ]
 
 UNIFIED_SOURCES += [
     'ClippedImage.cpp',
     'DecodePool.cpp',
     'Decoder.cpp',
     'DynamicImage.cpp',
     'FrameAnimator.cpp',
@@ -24,16 +25,17 @@ UNIFIED_SOURCES += [
     'FrozenImage.cpp',
     'Image.cpp',
     'ImageFactory.cpp',
     'ImageMetadata.cpp',
     'ImageOps.cpp',
     'ImageWrapper.cpp',
     'imgFrame.cpp',
     'imgTools.cpp',
+    'MultipartImage.cpp',
     'OrientedImage.cpp',
     'ScriptedNotificationObserver.cpp',
     'ShutdownTracker.cpp',
     'SurfaceCache.cpp',
     'SVGDocumentWrapper.cpp',
     'VectorImage.cpp',
 ]
 
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -341,34 +341,31 @@ dnl Special win32 checks
 dnl ========================================================
 
 MOZ_ARG_ENABLE_BOOL(metro,
 [  --enable-metro           Enable Windows Metro build targets],
     MOZ_METRO=1,
     MOZ_METRO=)
 if test -n "$MOZ_METRO"; then
     AC_DEFINE(MOZ_METRO)
-    # Target the Windows 8 Kit
-    WINSDK_TARGETVER=602
-    WINVER=502
-else
-    # Target the Windows 7 SDK by default
-    WINSDK_TARGETVER=601
-    WINVER=502
 fi
 
+# Target the Windows 8.1 SDK by default
+WINSDK_TARGETVER=603
+WINVER=502
+
 MOZ_ARG_WITH_STRING(windows-version,
 [  --with-windows-version=WINSDK_TARGETVER
-                          Windows SDK version to target. Lowest version
-                          currently allowed is 601, highest is 602],
+                          Windows SDK version to target. Win8.1 (603) is
+                          currently the minimum supported version.],
   WINSDK_TARGETVER=$withval)
 
-# Currently only two sdk versions allowed, 601 and 602
+# Currently only version 603 is allowed
 case "$WINSDK_TARGETVER" in
-601|602)
+603)
     MOZ_WINSDK_TARGETVER=0${WINSDK_TARGETVER}0000
     ;;
 
 *)
     AC_MSG_ERROR([Invalid value for --with-windows-version ($WINSDK_TARGETVER)]);
     ;;
 esac
 
@@ -490,17 +487,17 @@ case "$target" in
                 "$_WINDRES_MINOR_VERSION" -lt "$WINDRES_MINOR_VERSION" -o \
                 "$_WINDRES_MAJOR_VERSION" -eq "$WINDRES_MAJOR_VERSION" -a \
                 "$_WINDRES_MINOR_VERSION" -eq "$WINDRES_MINOR_VERSION" -a \
                 "$_WINDRES_RELEASE_VERSION" -lt "$WINDRES_RELEASE_VERSION"
         then
             AC_MSG_ERROR([windres version $WINDRES_VERSION or higher is required to build.])
         fi
 
-        MOZ_WINSDK_MAXVER=0x06010000
+        MOZ_WINSDK_MAXVER=0x06030000
     fi # !GNU_CC
 
     AC_DEFINE_UNQUOTED(WINVER,0x$WINVER)
     AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x$WINVER)
     # Require OS features provided by IE 6.0 SP2 (XP SP2)
     AC_DEFINE_UNQUOTED(_WIN32_IE,0x0603)
 
     # If the maximum version supported by this SDK is lower than the target
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -545,17 +545,16 @@ class GCRuntime
 
     /*
      * Return the list of chunks that can be released outside the GC lock.
      * Must be called either during the GC or with the GC lock taken.
      */
     ChunkPool expireEmptyChunkPool(bool shrinkBuffers, const AutoLockGC &lock);
     void freeEmptyChunks(JSRuntime *rt, const AutoLockGC &lock);
     void prepareToFreeChunk(ChunkInfo &info);
-    void releaseChunk(Chunk *chunk);
 
     friend class BackgroundAllocTask;
     f