Merge m-c to b2g-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 27 Nov 2013 12:50:24 +0100
changeset 157764 6d9e485ede928e818504b5354bc5d838239c8a72
parent 157763 c1351b200a4974bae4dcb6d1e7e503834b289322 (current diff)
parent 157732 6ecf0c4dfcbe6b04640713afa29eba044b6c0475 (diff)
child 157765 0b48e1b383f143e3c932fb0ea301a7616909e06e
push id25722
push useremorley@mozilla.com
push dateWed, 27 Nov 2013 16:45:44 +0000
treeherdermozilla-central@5eb1c89fc2bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to b2g-inbound
accessible/src/jsat/tick.wav
b2g/config/gaia.json
dom/ipc/ContentParent.cpp
gfx/layers/ThebesLayerBuffer.cpp
gfx/layers/ThebesLayerBuffer.h
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
gfx/layers/opengl/ColorLayerOGL.cpp
gfx/layers/opengl/ColorLayerOGL.h
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/layers/opengl/ContainerLayerOGL.h
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/layers/opengl/LayerManagerOGLProgram.cpp
gfx/layers/opengl/LayerManagerOGLProgram.h
gfx/layers/opengl/LayerManagerOGLShaders.h
gfx/layers/opengl/LayerManagerOGLShaders.txt
gfx/layers/opengl/ThebesLayerOGL.cpp
gfx/layers/opengl/ThebesLayerOGL.h
security/patches/bug-935831.patch
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 942207 - apparently need clobber to avoid bustage
+Another Windows WebIDL clobber needed due to bug 928195
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -491,32 +491,35 @@ var Output = {
       this.selectionStart = braille.selectionStart = aSelection.selectionStart + this.startOffset;
       this.selectionEnd = braille.selectionEnd = aSelection.selectionEnd + this.startOffset;
 
       return braille;
     }
   },
 
   speechHelper: {
-    EARCONS: ['chrome://global/content/accessibility/tick.wav'],
+    EARCONS: ['virtual_cursor_move.ogg',
+              'virtual_cursor_key.ogg',
+              'clicked.ogg'],
 
     earconBuffers: {},
 
     inited: false,
 
     webspeechEnabled: false,
 
     init: function init() {
       let window = Utils.win;
       this.webspeechEnabled = !!window.speechSynthesis;
 
       for (let earcon of this.EARCONS) {
-        let earconName = /.*\/(.*)\..*$/.exec(earcon)[1];
+        let earconName = /(^.*)\..*$/.exec(earcon)[1];
         this.earconBuffers[earconName] = new WeakMap();
-        this.earconBuffers[earconName].set(window, new window.Audio(earcon));
+        this.earconBuffers[earconName].set(
+          window, new window.Audio('chrome://global/content/accessibility/' + earcon));
       }
 
       this.inited = true;
     },
 
     output: function output(aActions) {
       if (!this.inited) {
         this.init();
--- a/accessible/src/jsat/EventManager.jsm
+++ b/accessible/src/jsat/EventManager.jsm
@@ -52,18 +52,16 @@ this.EventManager.prototype = {
 
         AccessibilityEventObserver.addListener(this);
 
         this.webProgress.addProgressListener(this,
           (Ci.nsIWebProgress.NOTIFY_STATE_ALL |
            Ci.nsIWebProgress.NOTIFY_LOCATION));
         this.addEventListener('scroll', this, true);
         this.addEventListener('resize', this, true);
-        // XXX: Ideally this would be an a11y event. Bug #742280.
-        this.addEventListener('DOMActivate', this, true);
       }
       this.present(Presentation.tabStateChanged(null, 'newtab'));
 
     } catch (x) {
       Logger.logException(x, 'Failed to start EventManager');
     }
   },
 
@@ -74,43 +72,26 @@ this.EventManager.prototype = {
       return;
     }
     Logger.debug('EventManager.stop');
     AccessibilityEventObserver.removeListener(this);
     try {
       this.webProgress.removeProgressListener(this);
       this.removeEventListener('scroll', this, true);
       this.removeEventListener('resize', this, true);
-      // XXX: Ideally this would be an a11y event. Bug #742280.
-      this.removeEventListener('DOMActivate', this, true);
     } catch (x) {
       // contentScope is dead.
     } finally {
       this._started = false;
     }
   },
 
   handleEvent: function handleEvent(aEvent) {
     try {
       switch (aEvent.type) {
-      case 'DOMActivate':
-      {
-        let activatedAcc =
-          Utils.AccRetrieval.getAccessibleFor(aEvent.originalTarget);
-        let [state, extState] = Utils.getStates(activatedAcc);
-
-        // Checkable objects will have a state changed event that we will use
-        // instead of this hackish DOMActivate. We will also know the true
-        // action that was taken.
-        if (state & Ci.nsIAccessibleStates.STATE_CHECKABLE)
-          return;
-
-        this.present(Presentation.actionInvoked(activatedAcc, 'click'));
-        break;
-      }
       case 'scroll':
       case 'resize':
       {
         // the target could be an element, document or window
         let window = null;
         if (aEvent.target instanceof Ci.nsIDOMWindow)
           window = aEvent.target;
         else if (aEvent.target instanceof Ci.nsIDOMDocument)
--- a/accessible/src/jsat/Presentation.jsm
+++ b/accessible/src/jsat/Presentation.jsm
@@ -15,16 +15,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'PivotContext',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'UtteranceGenerator',
   'resource://gre/modules/accessibility/OutputGenerator.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'BrailleGenerator',
   'resource://gre/modules/accessibility/OutputGenerator.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
+  'resource://gre/modules/accessibility/Constants.jsm');
 
 this.EXPORTED_SYMBOLS = ['Presentation'];
 
 /**
  * The interface for all presenter classes. A presenter could be, for example,
  * a speech output module, or a visual cursor indicator.
  */
 function Presenter() {}
@@ -299,16 +301,21 @@ AndroidPresenter.prototype = {
     return {
       type: this.type,
       details: androidEvents
     };
   },
 
   actionInvoked: function AndroidPresenter_actionInvoked(aObject, aActionName) {
     let state = Utils.getStates(aObject)[0];
+
+    // Checkable objects will have a state changed event we will use instead.
+    if (state & Ci.nsIAccessibleStates.STATE_CHECKABLE)
+      return null;
+
     return {
       type: this.type,
       details: [{
         eventType: this.ANDROID_VIEW_CLICKED,
         text: UtteranceGenerator.genForAction(aObject, aActionName),
         checked: !!(state & Ci.nsIAccessibleStates.STATE_CHECKED)
       }]
     };
@@ -446,36 +453,40 @@ SpeechPresenter.prototype = {
   pivotChanged: function SpeechPresenter_pivotChanged(aContext, aReason) {
     if (!aContext.accessible)
       return null;
 
     return {
       type: this.type,
       details: {
         actions: [
-          {method: 'playEarcon', data: 'tick', options: {}},
+          {method: 'playEarcon',
+           data: aContext.accessible.role === Roles.KEY ?
+             'virtual_cursor_key' : 'virtual_cursor_move',
+           options: {}},
           {method: 'speak',
             data: UtteranceGenerator.genForContext(aContext).output.join(' '),
             options: {enqueue: true}}
         ]
       }
     };
   },
 
   actionInvoked: function SpeechPresenter_actionInvoked(aObject, aActionName) {
-    return {
-      type: this.type,
-      details: {
-        actions: [
-          {method: 'speak',
-           data: UtteranceGenerator.genForAction(aObject, aActionName).join(' '),
-           options: {enqueue: false}}
-        ]
-      }
-    };
+    let actions = [];
+    if (aActionName === 'click') {
+      actions.push({method: 'playEarcon',
+                    data: 'clicked',
+                    options: {}});
+    } else {
+      actions.push({method: 'speak',
+                    data: UtteranceGenerator.genForAction(aObject, aActionName).join(' '),
+                    options: {enqueue: false}});
+    }
+    return { type: this.type, details: { actions: actions } };
   },
 
   liveRegion: function SpeechPresenter_liveRegion(aContext, aIsPolite, aIsHide,
     aModifiedText) {
     return {
       type: this.type,
       details: {
         actions: [{
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -198,16 +198,22 @@ function activateCurrent(aMessage) {
         evt.initMouseEvent(aEventType, true, true, content,
                            x, y, 0, 0, 0, false, false, false, false, 0, null);
         node.dispatchEvent(evt);
       }
 
       dispatchMouseEvent('mousedown');
       dispatchMouseEvent('mouseup');
     }
+
+    if (aAccessible.role !== Roles.KEY) {
+      // Keys will typically have a sound of their own.
+      sendAsyncMessage('AccessFu:Present',
+                       Presentation.actionInvoked(aAccessible, 'click'));
+    }
   }
 
   function moveCaretTo(aAccessible, aOffset) {
     let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
     let oldOffset = accText.caretOffset;
     let text = accText.getText(0, accText.characterCount);
 
     if (aOffset >= 0 && aOffset <= accText.characterCount) {
--- a/accessible/src/jsat/jar.mn
+++ b/accessible/src/jsat/jar.mn
@@ -1,8 +1,10 @@
 # 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/.
 
 toolkit.jar:
     content/global/accessibility/AccessFu.css (AccessFu.css)
     content/global/accessibility/content-script.js (content-script.js)
-    content/global/accessibility/tick.wav (tick.wav)
+    content/global/accessibility/virtual_cursor_move.ogg (sounds/virtual_cursor_move.ogg)
+    content/global/accessibility/virtual_cursor_key.ogg (sounds/virtual_cursor_key.ogg)
+    content/global/accessibility/clicked.ogg (sounds/clicked.ogg)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..68388018e5e3054e07a9e59fe4dcb5100843f6fc
GIT binary patch
literal 6618
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
aRvi{Ragql>V?WD73_WkD4aB>p75*EAP#^~Y
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b29b55b449519d7f489f4a383a13cf77c663a71d
GIT binary patch
literal 4224
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..da97934605c8661999d0ea78e5e4f2bb330b880d
GIT binary patch
literal 5636
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
DKV)pg
deleted file mode 100644
index b40a1bbd0e85afe96f869ef38ac21d5a80344e2d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -731,18 +731,17 @@ pref("jsloader.reuseGlobal", true);
 pref("font.size.inflation.minTwips", 120);
 // And disable it for lingering master-process UI.
 pref("font.size.inflation.disabledInMasterProcess", true);
 
 // Enable freeing dirty pages when minimizing memory; this reduces memory
 // consumption when applications are sent to the background.
 pref("memory.free_dirty_pages", true);
 
-pref("layout.imagevisibility.enabled", false);
-pref("layout.imagevisibility.enabled_for_browser_elements_only", true);
+pref("layout.imagevisibility.enabled", true);
 pref("layout.imagevisibility.numscrollportwidths", 1);
 pref("layout.imagevisibility.numscrollportheights", 1);
 
 // Enable native identity (persona/browserid)
 pref("dom.identity.enabled", true);
 
 // Wait up to this much milliseconds when orientation changed
 pref("layers.orientation.sync.timeout", 1000);
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "61db56e065e5a0189b31d3bac2b838d7a65353b4", 
+    "revision": "9ba62e3061abd5521ffbbee5386a0654f972f73b", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/base/content/browser-charsetmenu.inc
+++ b/browser/base/content/browser-charsetmenu.inc
@@ -1,41 +1,62 @@
 # 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/.
 
 #filter substitution
 
 #expand <menu id="__ID_PREFIX__charsetMenu"
     label="&charsetMenu.label;"
+#ifndef OMIT_ACCESSKEYS
     accesskey="&charsetMenu.accesskey;"
+#endif
     oncommand="MultiplexHandler(event)"
+#ifdef OMIT_ACCESSKEYS
     onpopupshowing="CharsetMenu.build(event);"
+#else
+    onpopupshowing="CharsetMenu.build(event, true);"
+#endif
     onpopupshown="UpdateMenus(event);">
   <menupopup>
     <menu label="&charsetMenuAutodet.label;"
-          accesskey="&charsetMenuAutodet.accesskey;">
+#ifndef OMIT_ACCESSKEYS
+          accesskey="&charsetMenuAutodet.accesskey;"
+#endif
+        >
       <menupopup>
         <menuitem type="radio"
                   name="detectorGroup"
-                  id="chardet.off"
+#expand           id="__ID_PREFIX__chardet.off"
                   label="&charsetMenuAutodet.off.label;"
-                  accesskey="&charsetMenuAutodet.off.accesskey;"/>
+#ifndef OMIT_ACCESSKEYS
+                  accesskey="&charsetMenuAutodet.off.accesskey;"
+#endif
+                  />
         <menuitem type="radio"
                   name="detectorGroup"
-                  id="chardet.ja_parallel_state_machine"
+#expand           id="__ID_PREFIX__chardet.ja_parallel_state_machine"
                   label="&charsetMenuAutodet.ja.label;"
-                  accesskey="&charsetMenuAutodet.ja.accesskey;"/>
+#ifndef OMIT_ACCESSKEYS
+                  accesskey="&charsetMenuAutodet.ja.accesskey;"
+#endif
+                  />
         <menuitem type="radio"
                   name="detectorGroup"
-                  id="chardet.ruprob"
+#expand           id="__ID_PREFIX__chardet.ruprob"
                   label="&charsetMenuAutodet.ru.label;"
-                  accesskey="&charsetMenuAutodet.ru.accesskey;"/>
+#ifndef OMIT_ACCESSKEYS
+                  accesskey="&charsetMenuAutodet.ru.accesskey;"
+#endif
+                  />
         <menuitem type="radio"
                   name="detectorGroup"
-                  id="chardet.ukprob"
+#expand           id="__ID_PREFIX__chardet.ukprob"
                   label="&charsetMenuAutodet.uk.label;"
-                  accesskey="&charsetMenuAutodet.uk.accesskey;"/>
+#ifndef OMIT_ACCESSKEYS
+                  accesskey="&charsetMenuAutodet.uk.accesskey;"
+#endif
+                  />
       </menupopup>
     </menu>
     <menuseparator/>
   </menupopup>
 </menu>
--- a/browser/components/customizableui/content/toolbar.xml
+++ b/browser/components/customizableui/content/toolbar.xml
@@ -373,16 +373,17 @@
 
 <!-- This is a peculiar binding. It is here to deal with overlayed/inserted add-on content,
       and immediately direct such content elsewhere. -->
   <binding id="addonbar-delegating">
     <implementation>
       <constructor><![CDATA[
           // Reading these immediately so nobody messes with them anymore:
           this._delegatingToolbar = this.getAttribute("toolbar-delegate");
+          this._wasCollapsed = this.getAttribute("collapsed");
           // Leaving those in here to unbreak some code:
           if (document.readyState == "complete") {
             this._init();
           } else {
             // Need to wait until XUL overlays are loaded. See bug 554279.
             let self = this;
             document.addEventListener("readystatechange", function onReadyStateChange() {
               if (document.readyState != "complete")
@@ -404,18 +405,27 @@
                 // Hold on to the palette but remove it from the document.
                 toolbox.palette = node;
                 toolbox.removeChild(node);
               }
             }
           }
 
           // pass the current set of children for comparison with placements:
-          let children = [node.id for (node of this.childNodes)
-                          if (node.getAttribute("skipintoolbarset") != "true" && node.id)];
+          let children = [];
+          for (node of this.childNodes) {
+            if (node.getAttribute("skipintoolbarset") != "true" && node.id) {
+              // Force everything to be removable so that buildArea can chuck stuff
+              // out if the user has customized things / we've been here before:
+              if (!this._whiteListed.has(node.id)) {
+                node.setAttribute("removable", "true");
+              }
+              children.push(node);
+            }
+          }
           CustomizableUI.registerToolbarNode(this, children);
           this.evictNodes();
           // We can't easily use |this| or strong bindings for the observer fn here
           // because that creates leaky circular references when the node goes away,
           // and XBL destructors are unreliable.
           let mutationObserver = new MutationObserver(function(mutations) {
             if (!mutations.length) {
               return;
@@ -450,30 +460,38 @@
         <parameter name="aNode"/>
         <body>
         <![CDATA[
           if (this._whiteListed.has(aNode.id) || CustomizableUI.isSpecialWidget(aNode.id)) {
             return;
           }
           const kItemMaxWidth = 100;
           let oldParent = aNode.parentNode;
-
-          try {
-            aNode.setAttribute("removable", "true");
+          aNode.setAttribute("removable", "true");
 
-            let nodeWidth = aNode.getBoundingClientRect().width;
-            if (nodeWidth == 0 || nodeWidth > kItemMaxWidth) {
-              throw new Error(aNode.id + " is too big (" + nodeWidth +
-                              "px wide), moving to the palette");
+          let movedOut = false;
+          if (!this._wasCollapsed) {
+            try {
+              let nodeWidth = aNode.getBoundingClientRect().width;
+              if (nodeWidth == 0 || nodeWidth > kItemMaxWidth) {
+                throw new Error(aNode.id + " is too big (" + nodeWidth +
+                                "px wide), moving to the palette");
+              }
+              CustomizableUI.addWidgetToArea(aNode.id, this._delegatingToolbar);
+              movedOut = true;
+            } catch (ex) {
+              // This will throw if the node is too big, or can't be moved there for
+              // some reason. Report this:
+              Cu.reportError(ex);
             }
-            CustomizableUI.addWidgetToArea(aNode.id, this._delegatingToolbar);
-          } catch (ex) {
-            Cu.reportError(ex);
-            // This will throw if the node is too big, or can't be moved there for
-            // some reason. Try to remove it anyway:
+          }
+
+          /* We won't have moved the widget if either the add-on bar was collapsed,
+           * or if it was too wide to be inserted into the navbar. */
+          if (!movedOut) {
             try {
               CustomizableUI.removeWidgetFromArea(aNode.id);
             } catch (ex) {
               Cu.reportError(ex);
               aNode.remove();
             }
           }
 
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -321,20 +321,16 @@ PlacesViewBase.prototype = {
 
         let popup = document.createElement("menupopup");
         popup._placesNode = PlacesUtils.asContainer(aPlacesNode);
 
         if (!this._nativeView) {
           popup.setAttribute("placespopup", "true");
         }
 
-#ifdef XP_MACOSX
-        // No context menu on mac.
-        popup.setAttribute("context", "placesContext");
-#endif
         element.appendChild(popup);
         element.className = "menu-iconic bookmark-item";
 
         this._domNodes.set(aPlacesNode, popup);
       }
       else
         throw "Unexpected node";
 
@@ -983,19 +979,17 @@ PlacesToolbar.prototype = {
             }.bind(this)
           );
         }
 
         let popup = document.createElement("menupopup");
         popup.setAttribute("placespopup", "true");
         button.appendChild(popup);
         popup._placesNode = PlacesUtils.asContainer(aChild);
-#ifndef XP_MACOSX
         popup.setAttribute("context", "placesContext");
-#endif
 
         this._domNodes.set(aChild, popup);
       }
       else if (PlacesUtils.nodeIsURI(aChild)) {
         button.setAttribute("scheme",
                             PlacesUIUtils.guessUrlSchemeForUI(aChild.uri));
       }
     }
--- a/browser/devtools/sourceeditor/editor.js
+++ b/browser/devtools/sourceeditor/editor.js
@@ -233,19 +233,29 @@ Editor.prototype = {
       cm = win.CodeMirror(win.document.body, this.config);
       cm.getWrapperElement().addEventListener("contextmenu", (ev) => {
         ev.preventDefault();
         this.showContextMenu(el.ownerDocument, ev.screenX, ev.screenY);
       }, false);
 
       cm.on("focus", () => this.emit("focus"));
       cm.on("change", () => this.emit("change"));
-      cm.on("gutterClick", (cm, line) => this.emit("gutterClick", line));
       cm.on("cursorActivity", (cm) => this.emit("cursorActivity"));
 
+      cm.on("gutterClick", (cm, line, gutter, ev) => {
+        let head = { line: line, ch: 0 };
+        let tail = { line: line, ch: this.getText(line).length };
+
+        // Shift-click on a gutter selects the whole line.
+        if (ev.shiftKey)
+          return void cm.setSelection(head, tail);
+
+        this.emit("gutterClick", line);
+      });
+
       win.CodeMirror.defineExtension("l10n", (name) => {
         return L10N.GetStringFromName(name);
       });
 
       cm.getInputField().controllers.insertControllerAt(0, controller(this));
 
       this.container = env;
       editors.set(this, cm);
--- a/browser/devtools/sourceeditor/test/browser_editor_cursor.js
+++ b/browser/devtools/sourceeditor/test/browser_editor_cursor.js
@@ -26,11 +26,18 @@ function test() {
     is(ed.getSelection(), "Hello", "setSelection");
 
     ed.extendSelection({ start: 0, length: 5 });
     is(ed.getSelection(), ".\nHow", "extendSelection");
 
     ed.dropSelection();
     is(ed.getSelection(), "", "dropSelection");
 
+    // Check that shift-click on a gutter selects the whole line (bug 919707)
+    let iframe = win.document.querySelector("iframe");
+    let gutter = iframe.contentWindow.document.querySelector(".CodeMirror-gutters");
+
+    EventUtils.sendMouseEvent({ type: "mousedown", shiftKey: true }, gutter, iframe.contentWindow);
+    is(ed.getSelection(), "Hello.", "shift-click");
+
     teardown(ed, win);
   });
 }
\ No newline at end of file
--- a/browser/metro/base/content/contenthandlers/SelectionHandler.js
+++ b/browser/metro/base/content/contenthandlers/SelectionHandler.js
@@ -542,17 +542,17 @@ var SelectionHandler = {
         }, 50);
         break;
 
       case "Browser:SelectionHandlerPing":
         this._onPing(json.id);
         break;
 
       case "Browser:ResetLastPos":
-        this._onClickCoords(json.xPos, json.yPos);
+        this.onClickCoords(json.xPos, json.yPos);
         break;
     }
   },
 
   /*************************************************
    * Utilities
    */
 
--- a/browser/modules/CharsetMenu.jsm
+++ b/browser/modules/CharsetMenu.jsm
@@ -77,17 +77,17 @@ const kEncodings = new Set([
 
 // Always at the start of the menu, in this order, followed by a separator.
 const kPinned = [
   "UTF-8",
   "windows-1252"
 ];
 
 this.CharsetMenu = Object.freeze({
-  build: function BuildCharsetMenu(event) {
+  build: function BuildCharsetMenu(event, showAccessKeys) {
     let parent = event.target;
     if (parent.lastChild.localName != "menuseparator") {
       // Detector menu or charset menu already built
       return;
     }
     let doc = parent.ownerDocument;
 
     function createItem(encoding) {
@@ -95,21 +95,23 @@ this.CharsetMenu = Object.freeze({
       menuItem.setAttribute("type", "radio");
       menuItem.setAttribute("name", "charsetGroup");
       try {
         menuItem.setAttribute("label", gBundle.GetStringFromName(encoding));
       } catch (e) {
         // Localization error but put *something* in the menu to recover.
         menuItem.setAttribute("label", encoding);
       }
-      try {
-        menuItem.setAttribute("accesskey",
-                              gBundle.GetStringFromName(encoding + ".key"));
-      } catch (e) {
-        // Some items intentionally don't have an accesskey
+      if (showAccessKeys) {
+        try {
+          menuItem.setAttribute("accesskey",
+                                gBundle.GetStringFromName(encoding + ".key"));
+        } catch (e) {
+          // Some items intentionally don't have an accesskey
+        }
       }
       menuItem.setAttribute("id", "charset." + encoding);
       return menuItem;
     }
 
     // Clone the set in order to be able to remove the pinned encodings from
     // the cloned set.
     let encodings = new Set(kEncodings);
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -193,16 +193,18 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 //#define DEBUG_DOCSHELL_FOCUS
 #define DEBUG_PAGE_CACHE
 #endif
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
+#else
+#include <unistd.h> // for getpid()
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // True means sUseErrorPages has been added to preferences var cache.
 static bool gAddedPreferencesVarCache = false;
 
new file mode 100644
--- /dev/null
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -0,0 +1,1285 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "AsmJSCache.h"
+
+#include <stdio.h>
+
+#include "js/RootingAPI.h"
+#include "jsfriendapi.h"
+#include "mozilla/CondVar.h"
+#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
+#include "mozilla/dom/asmjscache/PAsmJSCacheEntryParent.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/PermissionMessageUtils.h"
+#include "mozilla/dom/quota/Client.h"
+#include "mozilla/dom/quota/OriginOrPatternString.h"
+#include "mozilla/dom/quota/QuotaManager.h"
+#include "mozilla/dom/quota/QuotaObject.h"
+#include "mozilla/dom/quota/UsageInfo.h"
+#include "mozilla/unused.h"
+#include "nsContentUtils.h"
+#include "nsIAtom.h"
+#include "nsIFile.h"
+#include "nsIPrincipal.h"
+#include "nsIRunnable.h"
+#include "nsIThread.h"
+#include "nsIXULAppInfo.h"
+#include "nsJSPrincipals.h"
+#include "nsThreadUtils.h"
+#include "nsXULAppAPI.h"
+#include "prio.h"
+#include "private/pprio.h"
+
+#define ASMJSCACHE_FILE_NAME "module"
+
+using mozilla::dom::quota::AssertIsOnIOThread;
+using mozilla::dom::quota::OriginOrPatternString;
+using mozilla::dom::quota::PersistenceType;
+using mozilla::dom::quota::QuotaManager;
+using mozilla::dom::quota::QuotaObject;
+using mozilla::dom::quota::UsageInfo;
+using mozilla::unused;
+
+namespace mozilla {
+namespace dom {
+namespace asmjscache {
+
+namespace {
+
+bool
+IsMainProcess()
+{
+  return XRE_GetProcessType() == GeckoProcessType_Default;
+}
+
+// FileDescriptorHolder owns a file descriptor and its memory mapping.
+// FileDescriptorHolder is derived by all three runnable classes (that is,
+// (Single|Parent|Child)ProcessRunnable. To avoid awkward workarouds,
+// FileDescriptorHolder is derived virtually by File and MainProcessRunnable for
+// the benefit of SingleProcessRunnable, which derives both. Since File and
+// MainProcessRunnable both need to be runnables, FileDescriptorHolder also
+// derives nsRunnable.
+class FileDescriptorHolder : public nsRunnable
+{
+public:
+  FileDescriptorHolder()
+  : mQuotaObject(nullptr),
+    mFileSize(INT64_MIN),
+    mFileDesc(nullptr),
+    mFileMap(nullptr),
+    mMappedMemory(nullptr)
+  { }
+
+  ~FileDescriptorHolder()
+  {
+    // These resources should have already been released by Finish().
+    MOZ_ASSERT(!mQuotaObject);
+    MOZ_ASSERT(!mMappedMemory);
+    MOZ_ASSERT(!mFileMap);
+    MOZ_ASSERT(!mFileDesc);
+  }
+
+  size_t
+  FileSize() const
+  {
+    MOZ_ASSERT(mFileSize >= 0, "Accessing FileSize of unopened file");
+    return mFileSize;
+  }
+
+  PRFileDesc*
+  FileDesc() const
+  {
+    MOZ_ASSERT(mFileDesc, "Accessing FileDesc of unopened file");
+    return mFileDesc;
+  }
+
+  bool
+  MapMemory(OpenMode aOpenMode)
+  {
+    MOZ_ASSERT(!mFileMap, "Cannot call MapMemory twice");
+
+    PRFileMapProtect mapFlags = aOpenMode == eOpenForRead ? PR_PROT_READONLY
+                                                          : PR_PROT_READWRITE;
+
+    mFileMap = PR_CreateFileMap(mFileDesc, mFileSize, mapFlags);
+    NS_ENSURE_TRUE(mFileMap, false);
+
+    mMappedMemory = PR_MemMap(mFileMap, 0, mFileSize);
+    NS_ENSURE_TRUE(mMappedMemory, false);
+
+    return true;
+  }
+
+  void*
+  MappedMemory() const
+  {
+    MOZ_ASSERT(mMappedMemory, "Accessing MappedMemory of un-mapped file");
+    return mMappedMemory;
+  }
+
+protected:
+  // This method must be called before AllowNextSynchronizedOp (which releases
+  // the lock protecting these resources). It is idempotent, so it is ok to call
+  // multiple times (or before the file has been fully opened).
+  void
+  Finish()
+  {
+    if (mMappedMemory) {
+      PR_MemUnmap(mMappedMemory, mFileSize);
+      mMappedMemory = nullptr;
+    }
+    if (mFileMap) {
+      PR_CloseFileMap(mFileMap);
+      mFileMap = nullptr;
+    }
+    if (mFileDesc) {
+      PR_Close(mFileDesc);
+      mFileDesc = nullptr;
+    }
+
+    // Holding the QuotaObject alive until all the cache files are closed enables
+    // assertions in QuotaManager that the cache entry isn't cleared while we
+    // are working on it.
+    mQuotaObject = nullptr;
+  }
+
+  nsRefPtr<QuotaObject> mQuotaObject;
+  int64_t mFileSize;
+  PRFileDesc* mFileDesc;
+  PRFileMap* mFileMap;
+  void* mMappedMemory;
+};
+
+// File is a base class shared by (Single|Client)ProcessEntryRunnable that
+// presents a single interface to the AsmJSCache ops which need to wait until
+// the file is open, regardless of whether we are executing in the main process
+// or not.
+class File : public virtual FileDescriptorHolder
+{
+public:
+  class AutoClose
+  {
+    File* mFile;
+
+  public:
+    explicit AutoClose(File* aFile = nullptr)
+    : mFile(aFile)
+    { }
+
+    void
+    Init(File* aFile)
+    {
+      MOZ_ASSERT(!mFile);
+      mFile = aFile;
+    }
+
+    File*
+    operator->() const
+    {
+      MOZ_ASSERT(mFile);
+      return mFile;
+    }
+
+    void
+    Forget(File** aFile)
+    {
+      *aFile = mFile;
+      mFile = nullptr;
+    }
+
+    ~AutoClose()
+    {
+      if (mFile) {
+        mFile->Close();
+      }
+    }
+  };
+
+  bool
+  BlockUntilOpen(AutoClose *aCloser)
+  {
+    MOZ_ASSERT(!mWaiting, "Can only call BlockUntilOpen once");
+    MOZ_ASSERT(!mOpened, "Can only call BlockUntilOpen once");
+
+    mWaiting = true;
+
+    nsresult rv = NS_DispatchToMainThread(this);
+    NS_ENSURE_SUCCESS(rv, false);
+
+    {
+      MutexAutoLock lock(mMutex);
+      while (mWaiting) {
+        mCondVar.Wait();
+      }
+    }
+
+    if (!mOpened) {
+      return false;
+    }
+
+    // Now that we're open, we're guarnateed a Close() call. However, we are
+    // not guarnateed someone is holding an outstanding reference until the File
+    // is closed, so we do that ourselves and Release() in OnClose().
+    aCloser->Init(this);
+    AddRef();
+    return true;
+  }
+
+  // This method must be called if BlockUntilOpen returns 'true'. AutoClose
+  // mostly takes care of this. A derived class that implements Close() must
+  // guarnatee that OnClose() is called (eventually).
+  virtual void
+  Close() = 0;
+
+protected:
+  File()
+  : mMutex("File::mMutex"),
+    mCondVar(mMutex, "File::mCondVar"),
+    mWaiting(false),
+    mOpened(false)
+  { }
+
+  ~File()
+  {
+    MOZ_ASSERT(!mWaiting, "Shouldn't be destroyed while thread is waiting");
+    MOZ_ASSERT(!mOpened, "OnClose() should have been called");
+  }
+
+  void
+  OnOpen()
+  {
+    Notify(true);
+  }
+
+  void
+  OnFailure()
+  {
+    FileDescriptorHolder::Finish();
+
+    Notify(false);
+  }
+
+  void
+  OnClose()
+  {
+    FileDescriptorHolder::Finish();
+
+    MOZ_ASSERT(mOpened);
+    mOpened = false;
+
+    // Match the AddRef in BlockUntilOpen(). The main thread event loop still
+    // holds an outstanding ref which will keep 'this' alive until returning to
+    // the event loop.
+    Release();
+  }
+
+private:
+  void
+  Notify(bool aSuccess)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    MutexAutoLock lock(mMutex);
+    MOZ_ASSERT(mWaiting);
+
+    mWaiting = false;
+    mOpened = aSuccess;
+    mCondVar.Notify();
+  }
+
+  Mutex mMutex;
+  CondVar mCondVar;
+  bool mWaiting;
+  bool mOpened;
+};
+
+// MainProcessRunnable is a base class shared by (Single|Parent)ProcessRunnable
+// that factors out the runnable state machine required to open a cache entry
+// that runs in the main process.
+class MainProcessRunnable : public virtual FileDescriptorHolder
+{
+public:
+  NS_DECL_NSIRUNNABLE
+
+  // MainProcessRunnable runnable assumes that the derived class ensures
+  // (through ref-counting or preconditions) that aPrincipal is kept alive for
+  // the lifetime of the MainProcessRunnable.
+  MainProcessRunnable(nsIPrincipal* aPrincipal,
+                      OpenMode aOpenMode,
+                      size_t aSizeToWrite)
+  : mPrincipal(aPrincipal),
+    mOpenMode(aOpenMode),
+    mSizeToWrite(aSizeToWrite),
+    mNeedAllowNextSynchronizedOp(false),
+    mState(eInitial)
+  {
+    MOZ_ASSERT(IsMainProcess());
+  }
+
+  virtual ~MainProcessRunnable()
+  {
+    MOZ_ASSERT(mState == eFinished);
+    MOZ_ASSERT(!mNeedAllowNextSynchronizedOp);
+  }
+
+protected:
+  // This method is be called by the derived class (either on the JS
+  // compilation thread or the main thread) when JS engine is finished
+  // reading/writing the cache entry.
+  void
+  Close()
+  {
+    MOZ_ASSERT(mState == eOpened);
+    mState = eClosing;
+    NS_DispatchToMainThread(this);
+  }
+
+  // This method is called both internally and by derived classes upon any
+  // failure that prevents the eventual opening of the cache entry.
+  void
+  Fail()
+  {
+    MOZ_ASSERT(mState == eInitial || mState == eWaitingToOpen ||
+               mState == eReadyToOpen || mState == eNotifying);
+
+    mState = eFailing;
+    NS_DispatchToMainThread(this);
+  }
+
+  // Called by MainProcessRunnable on the main thread after the entry is open:
+  virtual void
+  OnOpen() = 0;
+
+  // This method may be overridden, but it must be called from the overrider.
+  // Called by MainProcessRunnable on the main thread after a call to Fail():
+  virtual void
+  OnFailure()
+  {
+    FinishOnMainThread();
+  }
+
+  // This method may be overridden, but it must be called from the overrider.
+  // Called by MainProcessRunnable on the main thread after a call to Close():
+  virtual void
+  OnClose()
+  {
+    FinishOnMainThread();
+  }
+
+private:
+  nsresult
+  InitOnMainThread();
+
+  nsresult
+  OpenFileOnIOThread();
+
+  void
+  FinishOnMainThread();
+
+  nsIPrincipal* const mPrincipal;
+  const OpenMode mOpenMode;
+  const size_t mSizeToWrite;
+
+  // State initialized during eInitial:
+  bool mNeedAllowNextSynchronizedOp;
+  nsCString mGroup;
+  nsCString mOrigin;
+  nsCString mStorageId;
+
+  enum State {
+    eInitial, // Just created, waiting to be dispatched to main thread
+    eWaitingToOpen, // Waiting to be called back from WaitForOpenAllowed
+    eReadyToOpen, // Waiting to be dispatched to the IO thread
+    eNotifying, // Waiting to be dispatched to main thread to notify of success
+    eOpened, // Finished calling OnOpen from main thread, waiting to be closed
+    eClosing, // Waiting to be dispatched to main thread again
+    eFailing, // Just failed, waiting to be dispatched to the main thread
+    eFinished, // Terminal state
+  };
+  State mState;
+};
+
+nsresult
+MainProcessRunnable::InitOnMainThread()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mState == eInitial);
+
+  QuotaManager* qm = QuotaManager::GetOrCreate();
+  NS_ENSURE_STATE(qm);
+
+  nsresult rv = QuotaManager::GetInfoFromPrincipal(mPrincipal, &mGroup,
+                                                   &mOrigin, nullptr, nullptr);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  QuotaManager::GetStorageId(quota::PERSISTENCE_TYPE_TEMPORARY,
+                             mOrigin, quota::Client::ASMJS,
+                             NS_LITERAL_STRING(ASMJSCACHE_FILE_NAME),
+                             mStorageId);
+
+  return NS_OK;
+}
+
+nsresult
+MainProcessRunnable::OpenFileOnIOThread()
+{
+  AssertIsOnIOThread();
+  MOZ_ASSERT(mState == eReadyToOpen);
+
+  QuotaManager* qm = QuotaManager::Get();
+  MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
+
+  nsCOMPtr<nsIFile> path;
+  nsresult rv = qm->EnsureOriginIsInitialized(quota::PERSISTENCE_TYPE_TEMPORARY,
+                                              mGroup, mOrigin, true,
+                                              getter_AddRefs(path));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = path->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool exists;
+  rv = path->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!exists) {
+    rv = path->Create(nsIFile::DIRECTORY_TYPE, 0755);
+    NS_ENSURE_SUCCESS(rv, rv);
+  } else {
+    DebugOnly<bool> isDirectory;
+    MOZ_ASSERT(NS_SUCCEEDED(path->IsDirectory(&isDirectory)));
+    MOZ_ASSERT(isDirectory, "Should have caught this earlier!");
+  }
+
+  rv = path->Append(NS_LITERAL_STRING(ASMJSCACHE_FILE_NAME));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mQuotaObject = qm->GetQuotaObject(quota::PERSISTENCE_TYPE_TEMPORARY,
+                                    mGroup, mOrigin, path);
+  NS_ENSURE_STATE(mQuotaObject);
+
+  PRIntn openFlags;
+  if (mOpenMode == eOpenForRead) {
+    rv = path->GetFileSize(&mFileSize);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    openFlags = PR_RDONLY | nsIFile::OS_READAHEAD;
+  } else {
+    if (!mQuotaObject->MaybeAllocateMoreSpace(0, mSizeToWrite)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    mFileSize = mSizeToWrite;
+
+    MOZ_ASSERT(mOpenMode == eOpenForWrite);
+    openFlags = PR_RDWR | PR_TRUNCATE | PR_CREATE_FILE;
+  }
+
+  rv = path->OpenNSPRFileDesc(openFlags, 0644, &mFileDesc);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+void
+MainProcessRunnable::FinishOnMainThread()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Per FileDescriptorHolder::Finish()'s comment, call before
+  // AllowNextSynchronizedOp.
+  FileDescriptorHolder::Finish();
+
+  if (mNeedAllowNextSynchronizedOp) {
+    mNeedAllowNextSynchronizedOp = false;
+    QuotaManager* qm = QuotaManager::Get();
+    if (qm) {
+      qm->AllowNextSynchronizedOp(OriginOrPatternString::FromOrigin(mOrigin),
+                                  Nullable<PersistenceType>(), mStorageId);
+    }
+  }
+}
+
+NS_IMETHODIMP
+MainProcessRunnable::Run()
+{
+  nsresult rv;
+
+  // All success/failure paths must eventually call Finish() to avoid leaving
+  // the parser hanging.
+  switch (mState) {
+    case eInitial: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      rv = InitOnMainThread();
+      if (NS_FAILED(rv)) {
+        Fail();
+        return NS_OK;
+      }
+
+      mState = eWaitingToOpen;
+      rv = QuotaManager::Get()->WaitForOpenAllowed(
+                                     OriginOrPatternString::FromOrigin(mOrigin),
+                                     Nullable<PersistenceType>(), mStorageId,
+                                     this);
+      if (NS_FAILED(rv)) {
+        Fail();
+        return NS_OK;
+      }
+
+      mNeedAllowNextSynchronizedOp = true;
+      return NS_OK;
+    }
+
+    case eWaitingToOpen: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      mState = eReadyToOpen;
+
+      QuotaManager* qm = QuotaManager::Get();
+      if (!qm) {
+        Fail();
+        return NS_OK;
+      }
+
+      rv = qm->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL);
+      if (NS_FAILED(rv)) {
+        Fail();
+        return NS_OK;
+      }
+
+      return NS_OK;
+    }
+
+    case eReadyToOpen: {
+      AssertIsOnIOThread();
+
+      rv = OpenFileOnIOThread();
+      if (NS_FAILED(rv)) {
+        Fail();
+        return NS_OK;
+      }
+
+      mState = eNotifying;
+      NS_DispatchToMainThread(this);
+      return NS_OK;
+    }
+
+    case eNotifying: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      mState = eOpened;
+      OnOpen();
+      return NS_OK;
+    }
+
+    case eFailing: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      mState = eFinished;
+      OnFailure();
+      return NS_OK;
+    }
+
+    case eClosing: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      mState = eFinished;
+      OnClose();
+      return NS_OK;
+    }
+
+    case eOpened:
+    case eFinished: {
+      MOZ_ASSUME_UNREACHABLE("Shouldn't Run() in this state");
+    }
+  }
+
+  MOZ_ASSUME_UNREACHABLE("Corrupt state");
+  return NS_OK;
+}
+
+// A runnable that executes for a cache access originating in the main process.
+class SingleProcessRunnable MOZ_FINAL : public File,
+                                        private MainProcessRunnable
+{
+public:
+  // In the single-process case, the calling JS compilation thread holds the
+  // nsIPrincipal alive indirectly (via the global object -> compartment ->
+  // principal) so we don't have to ref-count it here. This is fortunate since
+  // we are off the main thread and nsIPrincipals can only be ref-counted on
+  // the main thread.
+  SingleProcessRunnable(nsIPrincipal* aPrincipal,
+                        OpenMode aOpenMode,
+                        size_t aSizeToWrite)
+  : MainProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite)
+  {
+    MOZ_ASSERT(IsMainProcess());
+    MOZ_ASSERT(!NS_IsMainThread());
+    MOZ_COUNT_CTOR(SingleProcessRunnable);
+  }
+
+  ~SingleProcessRunnable()
+  {
+    MOZ_COUNT_DTOR(SingleProcessRunnable);
+  }
+
+private:
+  void
+  Close() MOZ_OVERRIDE MOZ_FINAL
+  {
+    MainProcessRunnable::Close();
+  }
+
+  void
+  OnOpen() MOZ_OVERRIDE
+  {
+    File::OnOpen();
+  }
+
+  void
+  OnFailure() MOZ_OVERRIDE
+  {
+    MainProcessRunnable::OnFailure();
+    File::OnFailure();
+  }
+
+  void
+  OnClose() MOZ_OVERRIDE MOZ_FINAL
+  {
+    MainProcessRunnable::OnClose();
+    File::OnClose();
+  }
+
+  // Avoid MSVC 'dominance' warning by having clear Run() override.
+  NS_IMETHODIMP
+  Run() MOZ_OVERRIDE
+  {
+    return MainProcessRunnable::Run();
+  }
+};
+
+// A runnable that executes in a parent process for a cache access originating
+// in the content process. This runnable gets registered as an IPDL subprotocol
+// actor so that it can communicate with the corresponding ChildProcessRunnable.
+class ParentProcessRunnable MOZ_FINAL : public PAsmJSCacheEntryParent,
+                                        public MainProcessRunnable
+{
+public:
+  // The given principal comes from an IPC::Principal which will be dec-refed
+  // at the end of the message, so we must ref-count it here. Fortunately, we
+  // are on the main thread (where PContent messages are delivered).
+  ParentProcessRunnable(nsIPrincipal* aPrincipal,
+                        OpenMode aOpenMode,
+                        size_t aSizeToWrite)
+  : MainProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite),
+    mPrincipalHolder(aPrincipal),
+    mActorDestroyed(false),
+    mOpened(false),
+    mFinished(false)
+  {
+    MOZ_ASSERT(IsMainProcess());
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_COUNT_CTOR(ParentProcessRunnable);
+  }
+
+private:
+  ~ParentProcessRunnable()
+  {
+    MOZ_ASSERT(!mPrincipalHolder, "Should have already been released");
+    MOZ_ASSERT(mActorDestroyed);
+    MOZ_ASSERT(mFinished);
+    MOZ_COUNT_DTOR(ParentProcessRunnable);
+  }
+
+  bool
+  Recv__delete__() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(mOpened);
+
+    MOZ_ASSERT(!mFinished);
+    mFinished = true;
+
+    MainProcessRunnable::Close();
+    return true;
+  }
+
+  void
+  ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(!mActorDestroyed);
+    mActorDestroyed = true;
+
+    // Assume ActorDestroy can happen at any time, so probe the current state to
+    // determine what needs to happen.
+
+    if (mFinished) {
+      return;
+    }
+
+    mFinished = true;
+
+    if (mOpened) {
+      MainProcessRunnable::Close();
+    } else {
+      MainProcessRunnable::Fail();
+    }
+  }
+
+  void
+  OnOpen() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    MOZ_ASSERT(!mOpened);
+    mOpened = true;
+
+    FileDescriptor::PlatformHandleType handle =
+      FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFileDesc));
+    if (!SendOnOpen(mFileSize, handle)) {
+      unused << Send__delete__(this);
+    }
+  }
+
+  void
+  OnClose() MOZ_OVERRIDE MOZ_FINAL
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(mOpened);
+
+    mFinished = true;
+
+    MainProcessRunnable::OnClose();
+
+    MOZ_ASSERT(mActorDestroyed);
+
+    mPrincipalHolder = nullptr;
+  }
+
+  void
+  OnFailure() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(!mOpened);
+
+    mFinished = true;
+
+    MainProcessRunnable::OnFailure();
+
+    if (!mActorDestroyed) {
+      unused << Send__delete__(this);
+    }
+
+    mPrincipalHolder = nullptr;
+  }
+
+  nsCOMPtr<nsIPrincipal> mPrincipalHolder;
+  bool mActorDestroyed;
+  bool mOpened;
+  bool mFinished;
+};
+
+} // unnamed namespace
+
+PAsmJSCacheEntryParent*
+AllocEntryParent(OpenMode aOpenMode,
+                 uint32_t aSizeToWrite,
+                 nsIPrincipal* aPrincipal)
+{
+  ParentProcessRunnable* runnable =
+    new ParentProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
+
+  // AddRef to keep the runnable alive until DeallocEntryParent.
+  runnable->AddRef();
+
+  nsresult rv = NS_DispatchToMainThread(runnable);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  return runnable;
+}
+
+void
+DeallocEntryParent(PAsmJSCacheEntryParent* aActor)
+{
+  // Match the AddRef in AllocEntryParent.
+  static_cast<ParentProcessRunnable*>(aActor)->Release();
+}
+
+namespace {
+
+class ChildProcessRunnable MOZ_FINAL : public File,
+                                       public PAsmJSCacheEntryChild
+{
+public:
+  NS_DECL_NSIRUNNABLE
+
+  // In the single-process case, the calling JS compilation thread holds the
+  // nsIPrincipal alive indirectly (via the global object -> compartment ->
+  // principal) so we don't have to ref-count it here. This is fortunate since
+  // we are off the main thread and nsIPrincipals can only be ref-counted on
+  // the main thread.
+  ChildProcessRunnable(nsIPrincipal* aPrincipal,
+                       OpenMode aOpenMode,
+                       size_t aSizeToWrite)
+  : mPrincipal(aPrincipal),
+    mOpenMode(aOpenMode),
+    mSizeToWrite(aSizeToWrite),
+    mActorDestroyed(false),
+    mState(eInitial)
+  {
+    MOZ_ASSERT(!IsMainProcess());
+    MOZ_ASSERT(!NS_IsMainThread());
+    MOZ_COUNT_CTOR(ChildProcessRunnable);
+  }
+
+  ~ChildProcessRunnable()
+  {
+    MOZ_ASSERT(mState == eFinished);
+    MOZ_ASSERT(mActorDestroyed);
+    MOZ_COUNT_DTOR(ChildProcessRunnable);
+  }
+
+private:
+  bool
+  RecvOnOpen(const int64_t& aFileSize, const FileDescriptor& aFileDesc)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(mState == eOpening);
+
+    mFileSize = aFileSize;
+
+    mFileDesc = PR_ImportFile(PROsfd(aFileDesc.PlatformHandle()));
+    if (!mFileDesc) {
+      return false;
+    }
+
+    mState = eOpened;
+    File::OnOpen();
+    return true;
+  }
+
+  bool
+  Recv__delete__() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(mState == eOpening);
+
+    mState = eFinished;
+    File::OnFailure();
+    return true;
+  }
+
+  void
+  ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    mActorDestroyed = true;
+  }
+
+  void
+  Close() MOZ_OVERRIDE MOZ_FINAL
+  {
+    MOZ_ASSERT(mState == eOpened);
+
+    mState = eClosing;
+    NS_DispatchToMainThread(this);
+  }
+
+private:
+  nsIPrincipal* const mPrincipal;
+  const OpenMode mOpenMode;
+  size_t mSizeToWrite;
+  bool mActorDestroyed;
+
+  enum State {
+    eInitial, // Just created, waiting to dispatched to the main thread
+    eOpening, // Waiting for the parent process to respond
+    eOpened, // Parent process opened the entry and sent it back
+    eClosing, // Waiting to be dispatched to the main thread to Send__delete__
+    eFinished // Terminal state
+  };
+  State mState;
+};
+
+NS_IMETHODIMP
+ChildProcessRunnable::Run()
+{
+  switch (mState) {
+    case eInitial: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      // AddRef to keep this runnable alive until IPDL deallocates the
+      // subprotocol (DeallocEntryChild).
+      AddRef();
+
+      if (!ContentChild::GetSingleton()->SendPAsmJSCacheEntryConstructor(
+        this, mOpenMode, mSizeToWrite, IPC::Principal(mPrincipal)))
+      {
+        // On failure, undo the AddRef (since DeallocEntryChild will not be
+        // called) and unblock the parsing thread with a failure. The main
+        // thread event loop still holds an outstanding ref which will keep
+        // 'this' alive until returning to the event loop.
+        Release();
+
+        mState = eFinished;
+        File::OnFailure();
+        return NS_OK;
+      }
+
+      mState = eOpening;
+      return NS_OK;
+    }
+
+    case eClosing: {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      // Per FileDescriptorHolder::Finish()'s comment, call before
+      // AllowNextSynchronizedOp (which happens in the parent upon receipt of
+      // the Send__delete__ message).
+      File::OnClose();
+
+      if (!mActorDestroyed) {
+        unused << Send__delete__(this);
+      }
+
+      mState = eFinished;
+      return NS_OK;
+    }
+
+    case eOpening:
+    case eOpened:
+    case eFinished: {
+      MOZ_ASSUME_UNREACHABLE("Shouldn't Run() in this state");
+    }
+  }
+
+  MOZ_ASSUME_UNREACHABLE("Corrupt state");
+  return NS_OK;
+}
+
+} // unnamed namespace
+
+void
+DeallocEntryChild(PAsmJSCacheEntryChild* aActor)
+{
+  // Match the AddRef before SendPAsmJSCacheEntryConstructor.
+  static_cast<ChildProcessRunnable*>(aActor)->Release();
+}
+
+namespace {
+
+bool
+OpenFile(JS::Handle<JSObject*> aGlobal,
+         OpenMode aOpenMode,
+         size_t aSizeToWrite,
+         File::AutoClose* aFile)
+{
+  MOZ_ASSERT_IF(aOpenMode == eOpenForRead, aSizeToWrite == 0);
+
+  // There are three reasons we don't attempt caching from the main thread:
+  //  1. In the parent process: QuotaManager::WaitForOpenAllowed prevents
+  //     synchronous waiting on the main thread requiring a runnable to be
+  //     dispatched to the main thread.
+  //  2. In the child process: the IPDL PContent messages we need to
+  //     synchronously wait on are dispatched to the main thread.
+  //  3. While a cache lookup *should* be much faster than compilation, IO
+  //     operations can be unpredictably slow and we'd like to avoid the
+  //     occasional janks on the main thread.
+  // We could use a nested event loop to address 1 and 2, but we're potentially
+  // in the middle of running JS (eval()) and nested event loops can be
+  // semantically observable.
+  if (NS_IsMainThread()) {
+    return false;
+  }
+
+  // This assumes a non-worker global.
+  nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
+
+  // If we are in a child process, we need to synchronously call into the
+  // parent process to open the file and interact with the QuotaManager. The
+  // child can then map the file into its address space to perform I/O.
+  nsRefPtr<File> file;
+  if (IsMainProcess()) {
+    file = new SingleProcessRunnable(principal, aOpenMode, aSizeToWrite);
+  } else {
+    file = new ChildProcessRunnable(principal, aOpenMode, aSizeToWrite);
+  }
+
+  if (!file->BlockUntilOpen(aFile)) {
+    return false;
+  }
+
+  return file->MapMemory(aOpenMode);
+}
+
+} // anonymous namespace
+
+typedef uint32_t AsmJSCookieType;
+static const uint32_t sAsmJSCookie = 0x600d600d;
+
+// Anything smaller should compile fast enough that caching will just add
+// overhead.
+static const size_t sMinCachedModuleLength = 10000;
+
+bool
+OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
+                 const jschar* aBegin,
+                 const jschar* aLimit,
+                 size_t* aSize,
+                 const uint8_t** aMemory,
+                 intptr_t* aFile)
+{
+  if (size_t(aLimit - aBegin) < sMinCachedModuleLength) {
+    return false;
+  }
+
+  File::AutoClose file;
+  if (!OpenFile(aGlobal, eOpenForRead, 0, &file)) {
+    return false;
+  }
+
+  // Although we trust that the stored cache files have not been arbitrarily
+  // corrupted, it is possible that a previous execution aborted in the middle
+  // of writing a cache file (crash, OOM-killer, etc). To protect against
+  // partially-written cache files, we use the following scheme:
+  //  - Allocate an extra word at the beginning of every cache file which
+  //    starts out 0 (OpenFile opens with PR_TRUNCATE).
+  //  - After the asm.js serialization is complete, PR_SyncMemMap to write
+  //    everything to disk and then store a non-zero value (sAsmJSCookie)
+  //    in the first word.
+  //  - When attempting to read a cache file, check whether the first word is
+  //    sAsmJSCookie.
+  if (file->FileSize() < sizeof(AsmJSCookieType) ||
+      *(AsmJSCookieType*)file->MappedMemory() != sAsmJSCookie) {
+    return false;
+  }
+
+  *aSize = file->FileSize() - sizeof(AsmJSCookieType);
+  *aMemory = (uint8_t*) file->MappedMemory() + sizeof(AsmJSCookieType);
+
+  // The caller guarnatees a call to CloseEntryForRead (on success or
+  // failure) at which point the file will be closed.
+  file.Forget(reinterpret_cast<File**>(aFile));
+  return true;
+}
+
+void
+CloseEntryForRead(JS::Handle<JSObject*> global,
+                  size_t aSize,
+                  const uint8_t* aMemory,
+                  intptr_t aFile)
+{
+  File::AutoClose file(reinterpret_cast<File*>(aFile));
+
+  MOZ_ASSERT(aSize + sizeof(AsmJSCookieType) == file->FileSize());
+  MOZ_ASSERT(aMemory - sizeof(AsmJSCookieType) == file->MappedMemory());
+}
+
+bool
+OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
+                  const jschar* aBegin,
+                  const jschar* aEnd,
+                  size_t aSize,
+                  uint8_t** aMemory,
+                  intptr_t* aFile)
+{
+  if (size_t(aEnd - aBegin) < sMinCachedModuleLength) {
+    return false;
+  }
+
+  // Add extra space for the AsmJSCookieType (see OpenEntryForRead).
+  aSize += sizeof(AsmJSCookieType);
+
+  File::AutoClose file;
+  if (!OpenFile(aGlobal, eOpenForWrite, aSize, &file)) {
+    return false;
+  }
+
+  // Strip off the AsmJSCookieType from the buffer returned to the caller,
+  // which expects a buffer of aSize, not a buffer of sizeWithCookie starting
+  // with a cookie.
+  *aMemory = (uint8_t*) file->MappedMemory() + sizeof(AsmJSCookieType);
+
+  // The caller guarnatees a call to CloseEntryForWrite (on success or
+  // failure) at which point the file will be closed
+  file.Forget(reinterpret_cast<File**>(aFile));
+  return true;
+}
+
+void
+CloseEntryForWrite(JS::Handle<JSObject*> global,
+                   size_t aSize,
+                   uint8_t* aMemory,
+                   intptr_t aFile)
+{
+  File::AutoClose file(reinterpret_cast<File*>(aFile));
+
+  MOZ_ASSERT(aSize + sizeof(AsmJSCookieType) == file->FileSize());
+  MOZ_ASSERT(aMemory - sizeof(AsmJSCookieType) == file->MappedMemory());
+
+  // Flush to disk before writing the cookie (see OpenEntryForRead).
+  if (PR_SyncMemMap(file->FileDesc(),
+                    file->MappedMemory(),
+                    file->FileSize()) == PR_SUCCESS) {
+    *(AsmJSCookieType*)file->MappedMemory() = sAsmJSCookie;
+  }
+}
+
+bool
+GetBuildId(js::Vector<char>* aBuildID)
+{
+  nsCOMPtr<nsIXULAppInfo> info = do_GetService("@mozilla.org/xre/app-info;1");
+  if (!info) {
+    return false;
+  }
+
+  nsCString buildID;
+  nsresult rv = info->GetPlatformBuildID(buildID);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  if (!aBuildID->resize(buildID.Length())) {
+    return false;
+  }
+
+  for (size_t i = 0; i < buildID.Length(); i++) {
+    (*aBuildID)[i] = buildID[i];
+  }
+
+  return true;
+}
+
+class Client : public quota::Client
+{
+public:
+  NS_IMETHOD_(nsrefcnt)
+  AddRef() MOZ_OVERRIDE;
+
+  NS_IMETHOD_(nsrefcnt)
+  Release() MOZ_OVERRIDE;
+
+  virtual Type
+  GetType() MOZ_OVERRIDE
+  {
+    return ASMJS;
+  }
+
+  virtual nsresult
+  InitOrigin(PersistenceType aPersistenceType,
+             const nsACString& aGroup,
+             const nsACString& aOrigin,
+             UsageInfo* aUsageInfo) MOZ_OVERRIDE
+  {
+    return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aUsageInfo);
+  }
+
+  virtual nsresult
+  GetUsageForOrigin(PersistenceType aPersistenceType,
+                    const nsACString& aGroup,
+                    const nsACString& aOrigin,
+                    UsageInfo* aUsageInfo) MOZ_OVERRIDE
+  {
+    QuotaManager* qm = QuotaManager::Get();
+    MOZ_ASSERT(qm, "We were being called by the QuotaManager");
+
+    nsCOMPtr<nsIFile> directory;
+    nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin,
+                                            getter_AddRefs(directory));
+    NS_ENSURE_SUCCESS(rv, rv);
+    MOZ_ASSERT(directory, "We're here because the origin directory exists");
+
+    rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    bool exists;
+    MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists);
+
+    nsIFile* path = directory;
+    rv = path->Append(NS_LITERAL_STRING(ASMJSCACHE_FILE_NAME));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = path->Exists(&exists);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (exists) {
+      int64_t fileSize;
+      rv = path->GetFileSize(&fileSize);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      MOZ_ASSERT(fileSize >= 0, "Negative size?!");
+
+      // Since the client is not explicitly storing files, append to database
+      // usage which represents implicit storage allocation.
+      aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
+    }
+
+    return NS_OK;
+  }
+
+  virtual void
+  OnOriginClearCompleted(PersistenceType aPersistenceType,
+                         const OriginOrPatternString& aOriginOrPattern)
+                         MOZ_OVERRIDE
+  { }
+
+  virtual void
+  ReleaseIOThreadObjects() MOZ_OVERRIDE
+  { }
+
+  virtual bool
+  IsFileServiceUtilized() MOZ_OVERRIDE
+  {
+    return false;
+  }
+
+  virtual bool
+  IsTransactionServiceActivated() MOZ_OVERRIDE
+  {
+    return false;
+  }
+
+  virtual void
+  WaitForStoragesToComplete(nsTArray<nsIOfflineStorage*>& aStorages,
+                            nsIRunnable* aCallback) MOZ_OVERRIDE
+  {
+    MOZ_ASSUME_UNREACHABLE("There are no storages");
+  }
+
+  virtual void
+  AbortTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE
+  {
+    MOZ_ASSUME_UNREACHABLE("There are no storages");
+  }
+
+  virtual bool
+  HasTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE
+  {
+    return false;
+  }
+
+  virtual void
+  ShutdownTransactionService() MOZ_OVERRIDE
+  { }
+
+private:
+  nsAutoRefCnt mRefCnt;
+  NS_DECL_OWNINGTHREAD
+};
+
+NS_IMPL_ADDREF(asmjscache::Client)
+NS_IMPL_RELEASE(asmjscache::Client)
+
+quota::Client*
+CreateClient()
+{
+  return new Client();
+}
+
+} // namespace asmjscache
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/asmjscache/AsmJSCache.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_asmjscache_asmjscache_h
+#define mozilla_dom_asmjscache_asmjscache_h
+
+#include "ipc/IPCMessageUtils.h"
+#include "js/TypeDecls.h"
+#include "js/Vector.h"
+
+class nsIPrincipal;
+
+namespace mozilla {
+namespace dom {
+
+namespace quota {
+class Client;
+}
+
+namespace asmjscache {
+
+class PAsmJSCacheEntryChild;
+class PAsmJSCacheEntryParent;
+
+enum OpenMode
+{
+  eOpenForRead,
+  eOpenForWrite,
+  NUM_OPEN_MODES
+};
+
+// Implementation of AsmJSCacheOps, installed by nsJSEnvironment:
+
+bool
+OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
+                 const jschar* aBegin,
+                 const jschar* aLimit,
+                 size_t* aSize,
+                 const uint8_t** aMemory,
+                 intptr_t *aHandle);
+void
+CloseEntryForRead(JS::Handle<JSObject*> aGlobal,
+                  size_t aSize,
+                  const uint8_t* aMemory,
+                  intptr_t aHandle);
+bool
+OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
+                  const jschar* aBegin,
+                  const jschar* aEnd,
+                  size_t aSize,
+                  uint8_t** aMemory,
+                  intptr_t* aHandle);
+void
+CloseEntryForWrite(JS::Handle<JSObject*> aGlobal,
+                   size_t aSize,
+                   uint8_t* aMemory,
+                   intptr_t aHandle);
+bool
+GetBuildId(js::Vector<char>* aBuildId);
+
+// Called from QuotaManager.cpp:
+
+quota::Client*
+CreateClient();
+
+// Called from ipc/ContentParent.cpp:
+
+PAsmJSCacheEntryParent*
+AllocEntryParent(OpenMode aOpenMode, uint32_t aSizeToWrite,
+                 nsIPrincipal* aPrincipal);
+
+void
+DeallocEntryParent(PAsmJSCacheEntryParent* aActor);
+
+// Called from ipc/ContentChild.cpp:
+
+void
+DeallocEntryChild(PAsmJSCacheEntryChild* aActor);
+
+} // namespace asmjscache
+} // namespace dom
+} // namespace mozilla
+
+namespace IPC {
+
+template <>
+struct ParamTraits<mozilla::dom::asmjscache::OpenMode> :
+  public EnumSerializer<mozilla::dom::asmjscache::OpenMode,
+                        mozilla::dom::asmjscache::eOpenForRead,
+                        mozilla::dom::asmjscache::NUM_OPEN_MODES>
+{ };
+
+} // namespace IPC
+
+#endif  // mozilla_dom_asmjscache_asmjscache_h
new file mode 100644
--- /dev/null
+++ b/dom/asmjscache/PAsmJSCacheEntry.ipdl
@@ -0,0 +1,24 @@
+/* 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 protocol PContent;
+
+namespace mozilla {
+namespace dom {
+namespace asmjscache {
+
+protocol PAsmJSCacheEntry
+{
+  manager PContent;
+
+child:
+  OnOpen(int64_t fileSize, FileDescriptor fileDesc);
+
+both:
+  __delete__();
+};
+
+} // namespace asmjscache
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/asmjscache/moz.build
@@ -0,0 +1,25 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS.mozilla.dom.asmjscache += [
+    'AsmJSCache.h'
+]
+
+SOURCES += [
+    'AsmJSCache.cpp'
+]
+
+IPDL_SOURCES += [
+    'PAsmJSCacheEntry.ipdl'
+]
+
+FAIL_ON_WARNINGS = True
+
+MSVC_ENABLE_PGO = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'gklayout'
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -233,23 +233,21 @@ class nsIScriptTimeoutHandler;
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDOMLeakPRLog;
 #endif
 
-#ifdef XP_LINUX
-#include <unistd.h> // for getpid()
-#endif
-
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
+#else
+#include <unistd.h> // for getpid()
 #endif
 
 static const char kStorageEnabled[] = "dom.storage.enabled";
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using mozilla::TimeStamp;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -74,16 +74,17 @@
 #endif
 #include "prlog.h"
 #include "prthread.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/ContentEvents.h"
 
 #include "nsCycleCollectionNoteRootCallback.h"
 #include "GeckoProfiler.h"
 
 using namespace mozilla;
@@ -2873,16 +2874,26 @@ nsJSContext::EnsureStatics()
   };
   JS_SetStructuredCloneCallbacks(sRuntime, &cloneCallbacks);
 
   static js::DOMCallbacks DOMcallbacks = {
     InstanceClassHasProtoAtDepth
   };
   SetDOMCallbacks(sRuntime, &DOMcallbacks);
 
+  // Set up the asm.js cache callbacks
+  static JS::AsmJSCacheOps asmJSCacheOps = {
+    asmjscache::OpenEntryForRead,
+    asmjscache::CloseEntryForRead,
+    asmjscache::OpenEntryForWrite,
+    asmjscache::CloseEntryForWrite,
+    asmjscache::GetBuildId
+  };
+  JS::SetAsmJSCacheOps(sRuntime, &asmJSCacheOps);
+
   // Set these global xpconnect options...
   Preferences::RegisterCallbackAndCall(ReportAllJSExceptionsPrefChangedCallback,
                                        "dom.report_all_js_exceptions");
 
   Preferences::RegisterCallbackAndCall(SetMemoryHighWaterMarkPrefChangedCallback,
                                        "javascript.options.mem.high_water_mark");
 
   Preferences::RegisterCallbackAndCall(SetMemoryMaxPrefChangedCallback,
--- a/dom/indexedDB/Client.h
+++ b/dom/indexedDB/Client.h
@@ -6,17 +6,16 @@
 
 #ifndef mozilla_dom_indexeddb_client_h__
 #define mozilla_dom_indexeddb_client_h__
 
 #include "IndexedDatabase.h"
 
 #include "mozilla/dom/quota/Client.h"
 
-#define IDB_DIRECTORY_NAME "idb"
 #define JOURNAL_DIRECTORY_NAME "journals"
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class Client : public mozilla::dom::quota::Client
 {
   typedef mozilla::dom::quota::OriginOrPatternString OriginOrPatternString;
   typedef mozilla::dom::quota::PersistenceType PersistenceType;
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -643,18 +643,18 @@ IDBFactory::OpenInternal(const nsAString
         // Chrome and temporary storage doesn't need to check the permission.
         rv = openHelper->WaitForOpenAllowed();
       }
     }
     NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
   }
   else if (aDeleting) {
     nsCString databaseId;
-    QuotaManager::GetStorageId(aPersistenceType, aASCIIOrigin, aName,
-                               databaseId);
+    QuotaManager::GetStorageId(aPersistenceType, aASCIIOrigin, Client::IDB,
+                               aName, databaseId);
     MOZ_ASSERT(!databaseId.IsEmpty());
 
     IndexedDBDeleteDatabaseRequestChild* actor =
       new IndexedDBDeleteDatabaseRequestChild(this, request, databaseId);
 
     mActorChild->SendPIndexedDBDeleteDatabaseRequestConstructor(
                                                               actor,
                                                               nsString(aName),
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -1712,18 +1712,18 @@ private:
 
 } // anonymous namespace
 
 NS_IMPL_ISUPPORTS1(OpenDatabaseHelper, nsIRunnable)
 
 nsresult
 OpenDatabaseHelper::Init()
 {
-  QuotaManager::GetStorageId(mPersistenceType, mASCIIOrigin, mName,
-                             mDatabaseId);
+  QuotaManager::GetStorageId(mPersistenceType, mASCIIOrigin, Client::IDB,
+                             mName, mDatabaseId);
   MOZ_ASSERT(!mDatabaseId.IsEmpty());
 
   return NS_OK;
 }
 
 nsresult
 OpenDatabaseHelper::WaitForOpenAllowed()
 {
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -5,29 +5,31 @@
 #include "base/basictypes.h"
 
 #include "IndexedDBChild.h"
 
 #include "nsIInputStream.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/quota/Client.h"
 #include "mozilla/dom/quota/QuotaManager.h"
 
 #include "AsyncConnectionHelper.h"
 #include "DatabaseInfo.h"
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IDBIndex.h"
 #include "IDBObjectStore.h"
 #include "IDBTransaction.h"
 
 USING_INDEXEDDB_NAMESPACE
 
 using namespace mozilla::dom;
+using mozilla::dom::quota::Client;
 using mozilla::dom::quota::QuotaManager;
 
 namespace {
 
 class IPCOpenDatabaseHelper : public AsyncConnectionHelper
 {
 public:
   IPCOpenDatabaseHelper(IDBDatabase* aDatabase, IDBOpenDBRequest* aRequest)
@@ -283,18 +285,18 @@ IndexedDBDatabaseChild::EnsureDatabase(
                            const DatabaseInfoGuts& aDBInfo,
                            const InfallibleTArray<ObjectStoreInfoGuts>& aOSInfo)
 {
   nsCString databaseId;
   if (mDatabase) {
     databaseId = mDatabase->Id();
   }
   else {
-    QuotaManager::GetStorageId(aDBInfo.persistenceType,
-                               aDBInfo.origin, aDBInfo.name, databaseId);
+    QuotaManager::GetStorageId(aDBInfo.persistenceType, aDBInfo.origin,
+                               Client::IDB, aDBInfo.name, databaseId);
   }
   MOZ_ASSERT(!databaseId.IsEmpty());
 
   nsRefPtr<DatabaseInfo> dbInfo;
   if (DatabaseInfo::Get(databaseId, getter_AddRefs(dbInfo))) {
     dbInfo->version = aDBInfo.version;
   }
   else {
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -12,16 +12,18 @@
 #include "nsQAppInstance.h"
 #endif
 
 #include "ContentChild.h"
 #include "CrashReporterChild.h"
 #include "TabChild.h"
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/asmjscache/AsmJSCache.h"
+#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
 #include "mozilla/dom/ExternalHelperAppChild.h"
 #include "mozilla/dom/PCrashReporterChild.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/ImageBridgeChild.h"
@@ -862,16 +864,32 @@ ContentChild::AllocPIndexedDBChild()
 
 bool
 ContentChild::DeallocPIndexedDBChild(PIndexedDBChild* aActor)
 {
   delete aActor;
   return true;
 }
 
+asmjscache::PAsmJSCacheEntryChild*
+ContentChild::AllocPAsmJSCacheEntryChild(const asmjscache::OpenMode& aOpenMode,
+                                         const int64_t& aSizeToWrite,
+                                         const IPC::Principal& aPrincipal)
+{
+  NS_NOTREACHED("Should never get here!");
+  return nullptr;
+}
+
+bool
+ContentChild::DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild* aActor)
+{
+  asmjscache::DeallocEntryChild(aActor);
+  return true;
+}
+
 PTestShellChild*
 ContentChild::AllocPTestShellChild()
 {
     return new TestShellChild();
 }
 
 bool
 ContentChild::DeallocPTestShellChild(PTestShellChild* shell)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -160,16 +160,23 @@ public:
     virtual bool DeallocPStorageChild(PStorageChild* aActor);
 
     virtual PBluetoothChild* AllocPBluetoothChild();
     virtual bool DeallocPBluetoothChild(PBluetoothChild* aActor);
 
     virtual PFMRadioChild* AllocPFMRadioChild();
     virtual bool DeallocPFMRadioChild(PFMRadioChild* aActor);
 
+    virtual PAsmJSCacheEntryChild* AllocPAsmJSCacheEntryChild(
+                                 const asmjscache::OpenMode& aOpenMode,
+                                 const int64_t& aSizeToWrite,
+                                 const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
+    virtual bool DeallocPAsmJSCacheEntryChild(
+                                    PAsmJSCacheEntryChild* aActor) MOZ_OVERRIDE;
+
     virtual PSpeechSynthesisChild* AllocPSpeechSynthesisChild();
     virtual bool DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor);
 
     virtual bool RecvRegisterChrome(const InfallibleTArray<ChromePackage>& packages,
                                     const InfallibleTArray<ResourceMapping>& resources,
                                     const InfallibleTArray<OverrideMapping>& overrides,
                                     const nsCString& locale);
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -21,16 +21,17 @@
 #include "AudioChannelService.h"
 #include "CrashReporterParent.h"
 #include "IHistory.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
 #include "IndexedDatabaseManager.h"
 #include "mozIApplication.h"
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ExternalHelperAppParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/dom/bluetooth/PBluetoothParent.h"
 #include "mozilla/dom/PFMRadioParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
@@ -2443,16 +2444,32 @@ ContentParent::DeallocPFMRadioParent(PFM
     delete aActor;
     return true;
 #else
     NS_WARNING("No support for FMRadio on this platform!");
     return false;
 #endif
 }
 
+asmjscache::PAsmJSCacheEntryParent*
+ContentParent::AllocPAsmJSCacheEntryParent(
+                                          const asmjscache::OpenMode& aOpenMode,
+                                          const int64_t& aSizeToWrite,
+                                          const IPC::Principal& aPrincipal)
+{
+  return asmjscache::AllocEntryParent(aOpenMode, aSizeToWrite, aPrincipal);
+}
+
+bool
+ContentParent::DeallocPAsmJSCacheEntryParent(PAsmJSCacheEntryParent* aActor)
+{
+  asmjscache::DeallocEntryParent(aActor);
+  return true;
+}
+
 PSpeechSynthesisParent*
 ContentParent::AllocPSpeechSynthesisParent()
 {
 #ifdef MOZ_WEBSPEECH
     return new mozilla::dom::SpeechSynthesisParent();
 #else
     return nullptr;
 #endif
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -363,16 +363,23 @@ private:
 
     virtual PBluetoothParent* AllocPBluetoothParent();
     virtual bool DeallocPBluetoothParent(PBluetoothParent* aActor);
     virtual bool RecvPBluetoothConstructor(PBluetoothParent* aActor);
 
     virtual PFMRadioParent* AllocPFMRadioParent();
     virtual bool DeallocPFMRadioParent(PFMRadioParent* aActor);
 
+    virtual PAsmJSCacheEntryParent* AllocPAsmJSCacheEntryParent(
+                                 const asmjscache::OpenMode& aOpenMode,
+                                 const int64_t& aSizeToWrite,
+                                 const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
+    virtual bool DeallocPAsmJSCacheEntryParent(
+                                   PAsmJSCacheEntryParent* aActor) MOZ_OVERRIDE;
+
     virtual PSpeechSynthesisParent* AllocPSpeechSynthesisParent();
     virtual bool DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* aActor);
     virtual bool RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor);
 
     virtual bool RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs);
     virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue);
 
     virtual bool RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions);
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
 /* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
 /* 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 protocol PAsmJSCacheEntry;
 include protocol PBlob;
 include protocol PBluetooth;
 include protocol PBrowser;
 include protocol PCompositor;
 include protocol PCrashReporter;
 include protocol PExternalHelperApp;
 include protocol PDeviceStorageRequest;
 include protocol PFMRadio;
@@ -35,16 +36,17 @@ using GeoPosition from "nsGeoPositionIPC
 using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h";
 using struct ResourceMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using base::ChildPrivileges from "base/process_util.h";
 using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
+using mozilla::dom::asmjscache::OpenMode from "mozilla/dom/asmjscache/AsmJSCache.h";
 using mozilla::dom::AudioChannelType from "AudioChannelCommon.h";
 using mozilla::dom::AudioChannelState from "AudioChannelCommon.h";
 using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
 using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h";
 using gfxIntSize from "nsSize.h";
 
 namespace mozilla {
 namespace dom {
@@ -170,16 +172,17 @@ struct PrefSetting {
   MaybePrefValue userValue;
 };
 
 intr protocol PContent
 {
     parent opens PCompositor;
     parent opens PImageBridge;
 
+    manages PAsmJSCacheEntry;
     manages PBlob;
     manages PBluetooth;
     manages PBrowser;
     manages PCrashReporter;
     manages PDeviceStorageRequest;
     manages PExternalHelperApp;
     manages PFMRadio;
     manages PHal;
@@ -352,16 +355,19 @@ parent:
     PStorage();
 
     PTelephony();
 
     PBluetooth();
 
     PFMRadio();
 
+    PAsmJSCacheEntry(OpenMode openMode, int64_t sizeToWrite,
+                     Principal principal);
+
     // Services remoting
 
     async StartVisitedQuery(URIParams uri);
     async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags);
     async SetURITitle(URIParams uri, nsString title);
     
     // filepicker remoting
     sync ShowFilePicker(int16_t mode, int16_t selectedType, bool addToRecentDocs,
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -5,24 +5,26 @@
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const PC_CONTRACT = "@mozilla.org/dom/peerconnection;1";
+const WEBRTC_GLOBAL_CONTRACT = "@mozilla.org/dom/webrtcglobalinformation1";
 const PC_OBS_CONTRACT = "@mozilla.org/dom/peerconnectionobserver;1";
 const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
 const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
 const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
 const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
 
 const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
-const PC_OBS_CID = Components.ID("{1d44a18e-4545-4ff3-863d-6dbd6234a583}");
+const WEBRTC_GLOBAL_CID = Components.ID("{f6063d11-f467-49ad-9765-e7923050dc08}");
+const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
 const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
 const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
 const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
 const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
 
 // Global list of PeerConnection objects, so they can be cleaned up when
 // a page is torn down. (Maps inner window ID to an array of PC objects).
 function GlobalPCList() {
@@ -58,16 +60,20 @@ GlobalPCList.prototype = {
   },
 
   removeNullRefs: function(winID) {
     if (this._list[winID] === undefined) {
       return;
     }
     this._list[winID] = this._list[winID].filter(
       function (e,i,a) { return e.get() !== null; });
+
+    if (this._list[winID].length === 0) {
+      delete this._list[winID];
+    }
   },
 
   hasActivePeerConnection: function(winID) {
     this.removeNullRefs(winID);
     return this._list[winID] ? true : false;
   },
 
   observe: function(subject, topic, data) {
@@ -106,19 +112,70 @@ GlobalPCList.prototype = {
       if (data == "offline") {
 	// this._list shold be empty here
         this._networkdown = true;
       } else if (data == "online") {
         this._networkdown = false;
       }
     }
   },
+
+  getStatsForEachPC: function(callback, errorCallback) {
+    for (let winId in this._list) {
+      if (this._list.hasOwnProperty(winId)) {
+        this.removeNullRefs(winId);
+        if (this._list[winId]) {
+          this._list[winId].forEach(function(pcref) {
+            pcref.get().getStatsInternal(null, callback, errorCallback);
+          });
+        }
+      }
+    }
+  },
+
+  getLoggingFromFirstPC: function(pattern, callback, errorCallback) {
+    for (let winId in this._list) {
+      this.removeNullRefs(winId);
+      if (this._list[winId]) {
+        // We expect removeNullRefs to not leave us with an empty array here
+        let pcref = this._list[winId][0];
+        pcref.get().getLogging(pattern, callback, errorCallback);
+        return;
+      }
+    }
+  },
 };
 let _globalPCList = new GlobalPCList();
 
+function WebrtcGlobalInformation() {
+}
+WebrtcGlobalInformation.prototype = {
+  classDescription: "WebrtcGlobalInformation",
+  classID: WEBRTC_GLOBAL_CID,
+  contractID: WEBRTC_GLOBAL_CONTRACT,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+
+  getAllStats: function(successCallback, failureCallback) {
+    if (_globalPCList) {
+      _globalPCList.getStatsForEachPC(successCallback, failureCallback);
+    } else {
+      failureCallback("No global PeerConnection list");
+    }
+  },
+
+  getCandPairLogs: function(candPairId, callback, errorCallback) {
+    let pattern = 'CAND-PAIR(' + candPairId + ')';
+    if (_globalPCList) {
+      _globalPCList.getLoggingFromFirstPC(pattern, callback, errorCallback);
+    } else {
+      errorCallback("No global PeerConnection list");
+    }
+  },
+};
+
 function RTCIceCandidate() {
   this.candidate = this.sdpMid = this.sdpMLineIndex = null;
 }
 RTCIceCandidate.prototype = {
   classDescription: "mozRTCIceCandidate",
   classID: PC_ICE_CID,
   contractID: PC_ICE_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
@@ -146,19 +203,20 @@ RTCSessionDescription.prototype = {
   init: function(win) { this._win = win; },
 
   __init: function(dict) {
     this.type = dict.type;
     this.sdp  = dict.sdp;
   }
 };
 
-function RTCStatsReport(win, report) {
+function RTCStatsReport(win, report, pcid) {
   this._win = win;
   this.report = report;
+  this.mozPcid = pcid;
 }
 RTCStatsReport.prototype = {
   classDescription: "RTCStatsReport",
   classID: PC_STATS_CID,
   contractID: PC_STATS_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 
@@ -199,16 +257,18 @@ function RTCPeerConnection() {
   this._closed = false;
 
   this._onCreateOfferSuccess = null;
   this._onCreateOfferFailure = null;
   this._onCreateAnswerSuccess = null;
   this._onCreateAnswerFailure = null;
   this._onGetStatsSuccess = null;
   this._onGetStatsFailure = null;
+  this._onGetLoggingSuccess = null;
+  this._onGetLoggingFailure = null;
 
   this._pendingType = null;
   this._localType = null;
   this._remoteType = null;
   this._trickleIce = false;
 
   /**
    * Everytime we get a request from content, we put it in the queue. If
@@ -731,16 +791,31 @@ RTCPeerConnection.prototype = {
 
   _getStats: function(selector, onSuccess, onError, internal) {
     this._onGetStatsSuccess = onSuccess;
     this._onGetStatsFailure = onError;
 
     this._getPC().getStats(selector, internal);
   },
 
+  getLogging: function(pattern, onSuccess, onError) {
+    this._queueOrRun({
+      func: this._getLogging,
+      args: [pattern, onSuccess, onError],
+      wait: true
+    });
+  },
+
+  _getLogging: function(pattern, onSuccess, onError) {
+    this._onGetLoggingSuccess = onSuccess;
+    this._onGetLoggingFailure = onError;
+
+    this._getPC().getLogging(pattern);
+  },
+
   createDataChannel: function(label, dict) {
     this._checkClosed();
     if (dict == undefined) {
       dict = {};
     }
     if (dict.maxRetransmitNum != undefined) {
       dict.maxRetransmits = dict.maxRetransmitNum;
       this.reportWarning("Deprecated RTCDataChannelInit dictionary entry maxRetransmitNum used!", null, 0);
@@ -936,31 +1011,18 @@ PeerConnectionObserver.prototype = {
             candidate: candidate,
             sdpMid: mid,
             sdpMLineIndex: level - 1
         }
     ));
   },
 
 
-  // This method is primarily responsible for updating two attributes:
-  // iceGatheringState and iceConnectionState. These states are defined
-  // in the WebRTC specification as follows:
-  //
-  // iceGatheringState:
-  // ------------------
-  //   new        The object was just created, and no networking has occurred
-  //              yet.
-  //
-  //   gathering  The ICE engine is in the process of gathering candidates for
-  //              this RTCPeerConnection.
-  //
-  //   complete   The ICE engine has completed gathering. Events such as adding
-  //              a new interface or a new TURN server will cause the state to
-  //              go back to gathering.
+  // This method is primarily responsible for updating iceConnectionState.
+  // This state is defined in the WebRTC specification as follows:
   //
   // iceConnectionState:
   // -------------------
   //   new           The ICE Agent is gathering addresses and/or waiting for
   //                 remote candidates to be supplied.
   //
   //   checking      The ICE Agent has received remote candidates on at least
   //                 one component, and is checking candidate pairs but has not
@@ -984,46 +1046,48 @@ PeerConnectionObserver.prototype = {
   //   disconnected  Liveness checks have failed for one or more components.
   //                 This is more aggressive than failed, and may trigger
   //                 intermittently (and resolve itself without action) on a
   //                 flaky network.
   //
   //   closed        The ICE Agent has shut down and is no longer responding to
   //                 STUN requests.
 
-  handleIceStateChanges: function(iceState) {
+  handleIceConnectionStateChange: function(iceState) {
     var histogram = Services.telemetry.getHistogramById("WEBRTC_ICE_SUCCESS_RATE");
 
-    const STATE_MAP = {
-      IceGathering:
-        { gathering: "gathering" },
-      IceWaiting:
-        { connection: "new",  gathering: "complete" },
-      IceChecking:
-        { connection: "checking" },
-      IceConnected:
-        { connection: "connected", success: true },
-      IceFailed:
-        { connection: "failed", success: false }
-    };
-    // These are all the allowed inputs.
+    if (iceState === 'failed') {
+      histogram.add(false);
+    }
+    if (this._dompc.iceConnectionState === 'checking' &&
+        (iceState === 'completed' || iceState === 'connected')) {
+          histogram.add(true);
+    }
+    this._dompc.changeIceConnectionState(iceState);
+  },
 
-    let transitions = STATE_MAP[iceState];
+  // This method is responsible for updating iceGatheringState. This
+  // state is defined in the WebRTC specification as follows:
+  //
+  // iceGatheringState:
+  // ------------------
+  //   new        The object was just created, and no networking has occurred
+  //              yet.
+  //
+  //   gathering  The ICE engine is in the process of gathering candidates for
+  //              this RTCPeerConnection.
+  //
+  //   complete   The ICE engine has completed gathering. Events such as adding
+  //              a new interface or a new TURN server will cause the state to
+  //              go back to gathering.
+  //
+  handleIceGatheringStateChange: function(gatheringState) {
+    this._dompc.changeIceGatheringState(gatheringState);
 
-    if ("connection" in transitions) {
-        this._dompc.changeIceConnectionState(transitions.connection);
-    }
-    if ("gathering" in transitions) {
-      this._dompc.changeIceGatheringState(transitions.gathering);
-    }
-    if ("success" in transitions) {
-      histogram.add(transitions.success);
-    }
-
-    if (iceState == "IceWaiting") {
+    if (gatheringState === "complete") {
       if (!this._dompc._trickleIce) {
         // If we are not trickling, then the queue is in a pending state
         // waiting for ICE gathering and executeNext frees it
         this._dompc._executeNext();
       }
       else if (this._dompc.localDescription) {
         // If we are trickling but we have already done setLocal,
         // then we need to send a final foundIceCandidate(null) to indicate
@@ -1035,18 +1099,22 @@ PeerConnectionObserver.prototype = {
 
   onStateChange: function(state) {
     switch (state) {
       case "SignalingState":
         this.callCB(this._dompc.onsignalingstatechange,
                     this._dompc.signalingState);
         break;
 
-      case "IceState":
-        this.handleIceStateChanges(this._dompc._pc.iceState);
+      case "IceConnectionState":
+        this.handleIceConnectionStateChange(this._dompc._pc.iceState);
+        break;
+
+      case "IceGatheringState":
+        this.handleIceGatheringStateChange(this._dompc._pc.iceGatheringState);
         break;
 
       case "SdpState":
         // No-op
         break;
 
       case "ReadyState":
         // No-op
@@ -1081,25 +1149,36 @@ PeerConnectionObserver.prototype = {
     appendStats(dict.iceComponentStats, report);
     appendStats(dict.iceCandidatePairStats, report);
     appendStats(dict.iceCandidateStats, report);
     appendStats(dict.codecStats, report);
 
     this.callCB(this._dompc._onGetStatsSuccess,
                 this._dompc._win.RTCStatsReport._create(this._dompc._win,
                                                         new RTCStatsReport(this._dompc._win,
-                                                                           report)));
+                                                                           report,
+                                                                           dict.pcid)));
     this._dompc._executeNext();
   },
 
   onGetStatsError: function(code, message) {
     this.callCB(this._dompc._onGetStatsFailure, new RTCError(code, message));
     this._dompc._executeNext();
   },
 
+  onGetLoggingSuccess: function(logs) {
+    this.callCB(this._dompc._onGetLoggingSuccess, logs);
+    this._dompc._executeNext();
+  },
+
+  onGetLoggingError: function(code, message) {
+    this.callCB(this._dompc._onGetLoggingFailure, new RTCError(code, message));
+    this._dompc._executeNext();
+  },
+
   onAddStream: function(stream) {
     this.dispatchEvent(new this._dompc._win.MediaStreamEvent("addstream",
                                                              { stream: stream }));
   },
 
   onRemoveStream: function(stream, type) {
     this.dispatchEvent(new this._dompc._win.MediaStreamEvent("removestream",
                                                              { stream: stream }));
@@ -1124,11 +1203,16 @@ PeerConnectionObserver.prototype = {
   },
 
   getSupportedConstraints: function(dict) {
     return dict;
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
-  [GlobalPCList, RTCIceCandidate, RTCSessionDescription, RTCPeerConnection,
-   RTCStatsReport, PeerConnectionObserver]
+  [GlobalPCList,
+   RTCIceCandidate,
+   RTCSessionDescription,
+   RTCPeerConnection,
+   RTCStatsReport,
+   PeerConnectionObserver,
+   WebrtcGlobalInformation]
 );
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -1,13 +1,15 @@
 component {00e0e20d-1494-4776-8e0e-0f0acbea3c79} PeerConnection.js
-component {1d44a18e-4545-4ff3-863d-6dbd6234a583} PeerConnection.js
+component {f6063d11-f467-49ad-9765-e7923050dc08} PeerConnection.js
+component {d1748d4c-7f6a-4dc5-add6-d55b7678537e} PeerConnection.js
 component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
 component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
 component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
 component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
 
 contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
-contract @mozilla.org/dom/peerconnectionobserver;1 {1d44a18e-4545-4ff3-863d-6dbd6234a583}
+contract @mozilla.org/dom/webrtcglobalinformation;1 {f6063d11-f467-49ad-9765-e7923050dc08}
+contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
 contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
 contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
 contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
 contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
new file mode 100644
--- /dev/null
+++ b/dom/mobilemessage/src/MessageUtils.h
@@ -0,0 +1,42 @@
+/* -*- 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 MessageUtils_h
+#define MessageUtils_h
+
+/**
+ * A helper function to convert the JS value to an integer value for time.
+ *
+ * @params aCx
+ *         The JS context.
+ * @params aTime
+ *         Can be an object or a number.
+ * @params aReturn
+ *         The integer value to return.
+ * @return NS_OK if the convertion succeeds.
+ */
+static nsresult
+convertTimeToInt(JSContext* aCx, const JS::Value& aTime, uint64_t& aReturn)
+{
+  if (aTime.isObject()) {
+    JS::Rooted<JSObject*> timestampObj(aCx, &aTime.toObject());
+    if (!JS_ObjectIsDate(aCx, timestampObj)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+    aReturn = js_DateGetMsecSinceEpoch(timestampObj);
+  } else {
+    if (!aTime.isNumber()) {
+      return NS_ERROR_INVALID_ARG;
+    }
+    double number = aTime.toNumber();
+    if (static_cast<uint64_t>(number) != number) {
+      return NS_ERROR_INVALID_ARG;
+    }
+    aReturn = static_cast<uint64_t>(number);
+  }
+  return NS_OK;
+}
+
+#endif
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -11,16 +11,17 @@
 #include "nsContentUtils.h"
 #include "nsIDOMFile.h"
 #include "nsTArrayHelpers.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
 #include "mozilla/dom/mobilemessage/SmsTypes.h"
 #include "nsDOMFile.h"
 #include "nsCxPusher.h"
+#include "MessageUtils.h"
 
 using namespace mozilla::idl;
 using namespace mozilla::dom::mobilemessage;
 
 DOMCI_DATA(MozMmsMessage, mozilla::dom::MmsMessage)
 
 namespace mozilla {
 namespace dom {
@@ -178,49 +179,16 @@ MmsMessage::MmsMessage(const mobilemessa
         info.readTimestamp = OBJECT_TO_JSVAL(dateObj);
       }
     }
 
     mDeliveryInfo.AppendElement(info);
   }
 }
 
-/**
- * A helper function to convert the JS value to an integer value for time.
- *
- * @params aCx
- *         The JS context.
- * @params aTime
- *         Can be an object or a number.
- * @params aReturn
- *         The integer value to return.
- * @return NS_OK if the convertion succeeds.
- */
-static nsresult
-convertTimeToInt(JSContext* aCx, const JS::Value& aTime, uint64_t& aReturn)
-{
-  if (aTime.isObject()) {
-    JS::Rooted<JSObject*> timestampObj(aCx, &aTime.toObject());
-    if (!JS_ObjectIsDate(aCx, timestampObj)) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    aReturn = js_DateGetMsecSinceEpoch(timestampObj);
-  } else {
-    if (!aTime.isNumber()) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    double number = aTime.toNumber();
-    if (static_cast<uint64_t>(number) != number) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    aReturn = static_cast<uint64_t>(number);
-  }
-  return NS_OK;
-}
-
 /* static */ nsresult
 MmsMessage::Create(int32_t               aId,
                    uint64_t              aThreadId,
                    const nsAString&      aIccId,
                    const nsAString&      aDelivery,
                    const JS::Value&      aDeliveryInfo,
                    const nsAString&      aSender,
                    const JS::Value&      aReceivers,
--- a/dom/mobilemessage/src/SmsMessage.cpp
+++ b/dom/mobilemessage/src/SmsMessage.cpp
@@ -3,58 +3,22 @@
  * 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 "SmsMessage.h"
 #include "nsIDOMClassInfo.h"
 #include "jsapi.h" // For OBJECT_TO_JSVAL and JS_NewDateObjectMsec
 #include "jsfriendapi.h" // For js_DateGetMsecSinceEpoch
 #include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
+#include "MessageUtils.h"
 
 using namespace mozilla::dom::mobilemessage;
 
 DOMCI_DATA(MozSmsMessage, mozilla::dom::SmsMessage)
 
-namespace {
-
-/**
- * A helper function to convert the JS value to an integer value for time.
- *
- * @params aCx
- *         The JS context.
- * @params aTime
- *         Can be an object or a number.
- * @params aReturn
- *         The integer value to return.
- * @return NS_OK if the convertion succeeds.
- */
-static nsresult
-convertTimeToInt(JSContext* aCx, const JS::Value& aTime, uint64_t& aReturn)
-{
-  if (aTime.isObject()) {
-    JS::Rooted<JSObject*> timestampObj(aCx, &aTime.toObject());
-    if (!JS_ObjectIsDate(aCx, timestampObj)) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    aReturn = js_DateGetMsecSinceEpoch(timestampObj);
-  } else {
-    if (!aTime.isNumber()) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    double number = aTime.toNumber();
-    if (static_cast<uint64_t>(number) != number) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    aReturn = static_cast<uint64_t>(number);
-  }
-  return NS_OK;
-}
-
-} // anonymous namespace
-
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN(SmsMessage)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozSmsMessage)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsMessage)
 NS_INTERFACE_MAP_END
--- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp
+++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp
@@ -277,17 +277,17 @@ GetSendMmsMessageRequestFromParams(uint3
   // SendMobileMessageRequest.attachments
   mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
 
   if (!params.mAttachments.WasPassed()) {
     return false;
   }
 
   for (uint32_t i = 0; i < params.mAttachments.Value().Length(); i++) {
-    MmsAttachment& attachment = params.mAttachments.Value()[i];
+    dom::MmsAttachment& attachment = params.mAttachments.Value()[i];
     MmsAttachmentData mmsAttachment;
     mmsAttachment.id().Assign(attachment.mId);
     mmsAttachment.location().Assign(attachment.mLocation);
     mmsAttachment.contentChild() = cc->GetOrCreateActorForBlob(attachment.mContent);
     if (!mmsAttachment.contentChild()) {
       return false;
     }
     request.attachments().AppendElement(mmsAttachment);
--- a/dom/mobilemessage/src/moz.build
+++ b/dom/mobilemessage/src/moz.build
@@ -38,17 +38,17 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'go
 EXPORTS.mozilla.dom += [
     'MmsMessage.h',
     'MobileMessageManager.h',
     'SmsFilter.h',
     'SmsMessage.h',
     'SmsSegmentInfo.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'Constants.cpp',
     'ipc/SmsChild.cpp',
     'ipc/SmsIPCService.cpp',
     'ipc/SmsParent.cpp',
     'MmsMessage.cpp',
     'MobileMessageCallback.cpp',
     'MobileMessageCursorCallback.cpp',
     'MobileMessageManager.cpp',
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -45,16 +45,17 @@ PARALLEL_DIRS += [
     'contacts',
     'phonenumberutils',
     'alarm',
     'datastore',
     'devicestorage',
     'encoding',
     'file',
     'fmradio',
+    'asmjscache',
     'media',
     'messages',
     'power',
     'push',
     'quota',
     'settings',
     'mobilemessage',
     'src',
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -783,19 +783,21 @@ nsPluginStreamListenerPeer::UseExistingP
 }
 
 NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
                                                           nsISupports* aContext,
                                                           nsIInputStream *aIStream,
                                                           uint64_t sourceOffset,
                                                           uint32_t aLength)
 {
-  NS_ASSERTION(mRequests.IndexOfObject(GetBaseRequest(request)) != -1,
-               "Received OnDataAvailable for untracked request.");
-  
+  if (mRequests.IndexOfObject(GetBaseRequest(request)) == -1) {
+    MOZ_ASSERT(false, "Received OnDataAvailable for untracked request.");
+    return NS_ERROR_UNEXPECTED;
+  }
+
   if (mRequestFailed)
     return NS_ERROR_FAILURE;
   
   if (mAbort) {
     uint32_t magicNumber = 0;  // set it to something that is not the magic number.
     nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
     if (container)
       container->GetData(&magicNumber);
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -21,16 +21,17 @@
 #include "gfxSharedImageSurface.h"
 #include "nsNPAPIPluginInstance.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #include "gfxContext.h"
 #include "gfxColor.h"
 #include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
 #include "Layers.h"
 #include "SharedTextureImage.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 #ifdef XP_MACOSX
 #include "MacIOSurfaceImage.h"
 #endif
@@ -809,23 +810,25 @@ PluginInstanceParent::BeginUpdateBackgro
         NS_ABORT_IF_FALSE(aRect.TopLeft() == nsIntPoint(0, 0),
                           "Expecting rect for whole frame");
         if (!CreateBackground(aRect.Size())) {
             *aCtx = nullptr;
             return NS_OK;
         }
     }
 
+    gfxIntSize sz = mBackground->GetSize();
 #ifdef DEBUG
-    gfxIntSize sz = mBackground->GetSize();
     NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
                       "Update outside of background area");
 #endif
 
-    nsRefPtr<gfxContext> ctx = new gfxContext(mBackground);
+    RefPtr<gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->
+      CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height));
+    nsRefPtr<gfxContext> ctx = new gfxContext(dt);
     *aCtx = ctx.forget().get();
 
     return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx,
                                           const nsIntRect& aRect)
--- a/dom/quota/Client.h
+++ b/dom/quota/Client.h
@@ -9,16 +9,19 @@
 
 #include "mozilla/dom/quota/QuotaCommon.h"
 
 #include "PersistenceType.h"
 
 class nsIOfflineStorage;
 class nsIRunnable;
 
+#define IDB_DIRECTORY_NAME "idb"
+#define ASMJSCACHE_DIRECTORY_NAME "asmjs"
+
 BEGIN_QUOTA_NAMESPACE
 
 class OriginOrPatternString;
 class UsageInfo;
 
 // An abstract interface for quota manager clients.
 // Each storage API must provide an implementation of this interface in order
 // to participate in centralized quota and storage handling.
@@ -30,45 +33,53 @@ public:
 
   NS_IMETHOD_(nsrefcnt)
   Release() = 0;
 
   enum Type {
     IDB = 0,
     //LS,
     //APPCACHE,
+    ASMJS,
     TYPE_MAX
   };
 
   virtual Type
   GetType() = 0;
 
   static nsresult
   TypeToText(Type aType, nsAString& aText)
   {
     switch (aType) {
       case IDB:
-        aText.AssignLiteral("idb");
+        aText.AssignLiteral(IDB_DIRECTORY_NAME);
+        break;
+
+      case ASMJS:
+        aText.AssignLiteral(ASMJSCACHE_DIRECTORY_NAME);
         break;
 
       case TYPE_MAX:
       default:
         NS_NOTREACHED("Bad id value!");
         return NS_ERROR_UNEXPECTED;
     }
 
     return NS_OK;
   }
 
   static nsresult
   TypeFromText(const nsAString& aText, Type& aType)
   {
-    if (aText.EqualsLiteral("idb")) {
+    if (aText.EqualsLiteral(IDB_DIRECTORY_NAME)) {
       aType = IDB;
     }
+    else if (aText.EqualsLiteral(ASMJSCACHE_DIRECTORY_NAME)) {
+      aType = ASMJS;
+    }
     else {
       return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
   }
 
   // Methods which are called on the IO thred.
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -21,16 +21,17 @@
 #include "nsITimer.h"
 #include "nsIURI.h"
 #include "nsIUsageCallback.h"
 
 #include <algorithm>
 #include "GeckoProfiler.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/CondVar.h"
+#include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/file/FileService.h"
 #include "mozilla/dom/indexedDB/Client.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/LazyIdleThread.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsComponentManagerUtils.h"
@@ -1093,24 +1094,25 @@ QuotaManager::Init()
     NS_WARNING("Unable to respond to temp storage pref changes!");
   }
 
   if (NS_FAILED(Preferences::AddBoolVarCache(&gTestingEnabled,
                                              PREF_TESTING_FEATURES, false))) {
     NS_WARNING("Unable to respond to testing pref changes!");
   }
 
-  static_assert(Client::IDB == 0 && Client::TYPE_MAX == 1,
+  static_assert(Client::IDB == 0 && Client::ASMJS == 1 && Client::TYPE_MAX == 2,
                 "Fix the registration!");
 
   NS_ASSERTION(mClients.Capacity() == Client::TYPE_MAX,
                "Should be using an auto array with correct capacity!");
 
   // Register IndexedDB
   mClients.AppendElement(new indexedDB::Client());
+  mClients.AppendElement(asmjscache::CreateClient());
 
   return NS_OK;
 }
 
 void
 QuotaManager::InitQuotaForOrigin(PersistenceType aPersistenceType,
                                  const nsACString& aGroup,
                                  const nsACString& aOrigin,
@@ -2001,24 +2003,27 @@ QuotaManager::GetStorageQuotaMB()
 {
   return uint32_t(std::max(gStorageQuotaMB, 0));
 }
 
 // static
 void
 QuotaManager::GetStorageId(PersistenceType aPersistenceType,
                            const nsACString& aOrigin,
+                           Client::Type aClientType,
                            const nsAString& aName,
                            nsACString& aDatabaseId)
 {
   nsAutoCString str;
   str.AppendInt(aPersistenceType);
   str.Append('*');
   str.Append(aOrigin);
   str.Append('*');
+  str.AppendInt(aClientType);
+  str.Append('*');
   str.Append(NS_ConvertUTF16toUTF8(aName));
 
   aDatabaseId = str;
 }
 
 // static
 nsresult
 QuotaManager::GetInfoFromURI(nsIURI* aURI,
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -283,16 +283,17 @@ public:
   }
 
   static uint32_t
   GetStorageQuotaMB();
 
   static void
   GetStorageId(PersistenceType aPersistenceType,
                const nsACString& aOrigin,
+               Client::Type aClientType,
                const nsAString& aName,
                nsACString& aDatabaseId);
 
   static nsresult
   GetInfoFromURI(nsIURI* aURI,
                  uint32_t aAppId,
                  bool aInMozBrowser,
                  nsACString* aGroup,
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -28,20 +28,27 @@ interface PeerConnectionImpl  {
   void createOffer(optional MediaConstraintsInternal constraints);
   [Throws]
   void createAnswer(optional MediaConstraintsInternal constraints);
   [Throws]
   void setLocalDescription(long action, DOMString sdp);
   [Throws]
   void setRemoteDescription(long action, DOMString sdp);
 
-  /* Stats call */
+  /* Stats call, calls either |onGetStatsSuccess| or |onGetStatsError| on our
+     observer. (see the |PeerConnectionObserver| interface) */
   [Throws]
   void getStats(MediaStreamTrack? selector, boolean internalStats);
 
+  /* Scrapes the RLogRingbuffer, and calls either |onGetLoggingSuccess|
+     or |onGetLoggingError| on our observer.
+     (see the |PeerConnectionObserver| interface) */
+  [Throws]
+  void getLogging(DOMString pattern);
+
   /* Adds the stream created by GetUserMedia */
   [Throws]
   void addStream(MediaStream stream);
   [Throws]
   void removeStream(MediaStream stream);
   [Throws]
   void closeStreams();
 
@@ -58,17 +65,18 @@ interface PeerConnectionImpl  {
 
   /* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
   void close();
 
   /* Attributes */
   readonly attribute DOMString localDescription;
   readonly attribute DOMString remoteDescription;
 
-  readonly attribute PCImplIceState iceState;
+  readonly attribute PCImplIceConnectionState iceConnectionState;
+  readonly attribute PCImplIceGatheringState iceGatheringState;
   readonly attribute PCImplReadyState readyState;
   readonly attribute PCImplSignalingState signalingState;
   readonly attribute PCImplSipccState sipccState;
 
   /* Data channels */
   [Throws]
   DataChannel createDataChannel(DOMString label, DOMString protocol,
     unsigned short type, boolean outOfOrderAllowed,
--- a/dom/webidl/PeerConnectionImplEnums.webidl
+++ b/dom/webidl/PeerConnectionImplEnums.webidl
@@ -26,16 +26,25 @@ enum PCImplSignalingState {
 };
 
 enum PCImplSipccState {
   "Idle",
   "Starting",
   "Started"
 };
 
-// TODO(ekr@rtfm.com): make this conform to the specifications
-enum PCImplIceState {
-  "IceGathering",
-  "IceWaiting",
-  "IceChecking",
-  "IceConnected",
-  "IceFailed"
+enum PCImplIceConnectionState {
+    "new",
+    "checking",
+    "connected",
+    "completed",
+    "failed",
+    "disconnected",
+    "closed"
 };
+
+// Deliberately identical to the values specified in webrtc
+enum PCImplIceGatheringState {
+  "new",
+  "gathering",
+  "complete"
+};
+
--- a/dom/webidl/PeerConnectionObserver.webidl
+++ b/dom/webidl/PeerConnectionObserver.webidl
@@ -23,16 +23,20 @@ interface PeerConnectionObserver
   void onAddIceCandidateSuccess();
   void onAddIceCandidateError(unsigned long name, DOMString message);
   void onIceCandidate(unsigned short level, DOMString mid, DOMString candidate);
 
   /* Stats callbacks */
   void onGetStatsSuccess(optional RTCStatsReportInternal report);
   void onGetStatsError(unsigned long name, DOMString message);
 
+  /* Logging callbacks */
+  void onGetLoggingSuccess(sequence<DOMString> logs);
+  void onGetLoggingError(unsigned long name, DOMString message);
+
   /* Data channel callbacks */
   void notifyDataChannel(DataChannel channel);
   void notifyConnection();
   void notifyClosedConnection();
 
   /* Notification of one of several types of state changed */
   void onStateChange(PCObserverStateType state);
 
--- a/dom/webidl/PeerConnectionObserverEnums.webidl
+++ b/dom/webidl/PeerConnectionObserverEnums.webidl
@@ -4,13 +4,14 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * This is in a separate file so it can be shared with unittests.
  */
 
 enum PCObserverStateType {
     "None",
     "ReadyState",
-    "IceState",
+    "IceConnectionState",
+    "IceGatheringState",
     "SdpState",
     "SipccState",
     "SignalingState"
 };
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -132,8 +132,24 @@ interface mozRTCPeerConnection : EventTa
 
   // Data channel.
   RTCDataChannel createDataChannel (DOMString label,
                                     optional RTCDataChannelInit dataChannelDict);
   attribute EventHandler ondatachannel;
   attribute EventHandler onconnection;
   attribute EventHandler onclosedconnection;
 };
+
+callback RTCLogCallback = void (sequence<DOMString> logMessages);
+
+[JSImplementation="@mozilla.org/dom/webrtcglobalinformation;1",
+ ChromeOnly,
+ Constructor ()]
+interface WebrtcGlobalInformation {
+    void getAllStats(RTCStatsCallback callback,
+                     RTCPeerConnectionErrorCallback errorCallback);
+    void getCandPairLogs(DOMString candPairId,
+                         RTCLogCallback callback,
+                         RTCPeerConnectionErrorCallback errorCallback);
+};
+
+
+
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -119,16 +119,17 @@ dictionary RTCCodecStats : RTCStats {
 };
 
 callback RTCStatsReportCallback = void (RTCStatsReport obj);
 
 // This is the internal representation of the report in this implementation
 // to be received from c++
 
 dictionary RTCStatsReportInternal {
+  DOMString                           pcid;
   sequence<RTCRTPStreamStats>         rtpStreamStats;
   sequence<RTCInboundRTPStreamStats>  inboundRTPStreamStats;
   sequence<RTCOutboundRTPStreamStats> outboundRTPStreamStats;
   sequence<RTCMediaStreamTrackStats>  mediaStreamTrackStats;
   sequence<RTCMediaStreamStats>       mediaStreamStats;
   sequence<RTCTransportStats>         transportStats;
   sequence<RTCIceComponentStats>      iceComponentStats;
   sequence<RTCIceCandidatePairStats>  iceCandidatePairStats;
@@ -136,12 +137,14 @@ dictionary RTCStatsReportInternal {
   sequence<RTCCodecStats>             codecStats;
 };
 
 [Pref="media.peerconnection.enabled",
 // TODO: Use MapClass here once it's available (Bug 928114)
 // MapClass(DOMString, object)
  JSImplementation="@mozilla.org/dom/rtcstatsreport;1"]
 interface RTCStatsReport {
+  [ChromeOnly]
+  readonly attribute DOMString mozPcid;
   void forEach(RTCStatsReportCallback callbackFn, optional any thisArg);
   object get(DOMString key);
   boolean has(DOMString key);
 };
--- a/gfx/2d/ScaledFontBase.cpp
+++ b/gfx/2d/ScaledFontBase.cpp
@@ -92,16 +92,18 @@ ScaledFontBase::GetPathForGlyphs(const G
     // Convert our GlyphBuffer into an array of Cairo glyphs.
     std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
     for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
       glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
       glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
       glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
     }
 
+    cairo_new_path(ctx);
+
     cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
 
     RefPtr<PathCairo> newPath = new PathCairo(ctx);
     if (isNewContext) {
       cairo_destroy(ctx);
     }
 
     return newPath;
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -61,17 +61,16 @@ namespace mozilla {
         class GLContext;
         class GLLibraryEGL;
         class GLScreenBuffer;
         class TextureGarbageBin;
     }
 
     namespace layers {
         class ColorTextureLayerProgram;
-        class LayerManagerOGL;
     }
 }
 
 namespace mozilla {
 namespace gl {
 
 /** GLFeature::Enum
  * We don't use typed enum to keep the implicit integer conversion.
rename from gfx/layers/ThebesLayerBuffer.cpp
rename to gfx/layers/RotatedBuffer.cpp
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -1,29 +1,25 @@
 /* -*- 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 "ThebesLayerBuffer.h"
+#include "RotatedBuffer.h"
 #include <sys/types.h>                  // for int32_t
 #include <algorithm>                    // for max
 #include "BasicImplData.h"              // for BasicImplData
 #include "BasicLayersImpl.h"            // for ToData
 #include "BufferUnrotate.h"             // for BufferUnrotate
 #include "GeckoProfiler.h"              // for PROFILER_LABEL
 #include "Layers.h"                     // for ThebesLayer, Layer, etc
-#include "gfxColor.h"                   // for gfxRGBA
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxMatrix.h"                  // for gfxMatrix
-#include "gfxPattern.h"                 // for gfxPattern
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPoint.h"                   // for gfxPoint
-#include "gfxRect.h"                    // for gfxRect
-#include "gfxTeeSurface.h"              // for gfxTeeSurface
 #include "gfxUtils.h"                   // for gfxUtils
 #include "mozilla/Util.h"               // for ArrayLength
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Matrix.h"         // for Matrix
 #include "mozilla/gfx/Point.h"          // for Point, IntPoint
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
@@ -77,116 +73,16 @@ RotatedBuffer::GetSourceRectangle(XSide 
  * the right side of the buffer (which is drawn on the left side of
  * mBufferRect).
  * @param aYSide TOP means we draw from the top side of the buffer (which
  * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
  * the bottom side of the buffer (which is drawn on the top side of
  * mBufferRect).
  */
 void
-RotatedBuffer::DrawBufferQuadrant(gfxContext* aTarget,
-                                  XSide aXSide, YSide aYSide,
-                                  ContextSource aSource,
-                                  float aOpacity,
-                                  gfxASurface* aMask,
-                                  const gfxMatrix* aMaskTransform) const
-{
-  // The rectangle that we're going to fill. Basically we're going to
-  // render the buffer at mBufferRect + quadrantTranslation to get the
-  // pixels in the right place, but we're only going to paint within
-  // mBufferRect
-  nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide);
-  nsIntRect fillRect;
-  if (!fillRect.IntersectRect(mBufferRect, quadrantRect)) {
-    return;
-  }
-
-  nsRefPtr<gfxASurface> source;
-
-  if (aSource == BUFFER_BLACK) {
-    if (mBuffer) {
-      source = mBuffer;
-    } else if (mDTBuffer) {
-      source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBuffer);
-    } else {
-      NS_WARNING("Can't draw a RotatedBuffer without any buffer!");
-      return;
-    }
-  } else {
-    MOZ_ASSERT(aSource == BUFFER_WHITE);
-    if (mBufferOnWhite) {
-      source = mBufferOnWhite;
-    } else if (mDTBufferOnWhite) {
-      source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBufferOnWhite);
-    } else {
-      NS_WARNING("Can't draw a RotatedBuffer without any buffer!");
-      return;
-    }
-  }
-
-
-  aTarget->NewPath();
-  aTarget->Rectangle(gfxRect(fillRect.x, fillRect.y,
-                             fillRect.width, fillRect.height),
-                     true);
-
-  gfxPoint quadrantTranslation(quadrantRect.x, quadrantRect.y);
-  nsRefPtr<gfxPattern> pattern = new gfxPattern(source);
-
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-  GraphicsFilter filter = GraphicsFilter::FILTER_NEAREST;
-  pattern->SetFilter(filter);
-#endif
-
-  gfxContextMatrixAutoSaveRestore saveMatrix(aTarget);
-
-  // Transform from user -> buffer space.
-  gfxMatrix transform;
-  transform.Translate(-quadrantTranslation);
-
-  pattern->SetMatrix(transform);
-  aTarget->SetPattern(pattern);
-
-  if (aMask) {
-    if (aOpacity == 1.0) {
-      aTarget->SetMatrix(*aMaskTransform);
-      aTarget->Mask(aMask);
-    } else {
-      aTarget->PushGroup(GFX_CONTENT_COLOR_ALPHA);
-      aTarget->Paint(aOpacity);
-      aTarget->PopGroupToSource();
-      aTarget->SetMatrix(*aMaskTransform);
-      aTarget->Mask(aMask);
-    }
-  } else {
-    if (aOpacity == 1.0) {
-      aTarget->Fill();
-    } else {
-      aTarget->Save();
-      aTarget->Clip();
-      aTarget->Paint(aOpacity);
-      aTarget->Restore();
-    }
-  }
-
-  nsRefPtr<gfxASurface> surf = aTarget->CurrentSurface();
-  surf->Flush();
-}
-
-/**
- * @param aXSide LEFT means we draw from the left side of the buffer (which
- * is drawn on the right side of mBufferRect). RIGHT means we draw from
- * the right side of the buffer (which is drawn on the left side of
- * mBufferRect).
- * @param aYSide TOP means we draw from the top side of the buffer (which
- * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
- * the bottom side of the buffer (which is drawn on the top side of
- * mBufferRect).
- */
-void
 RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
                                   XSide aXSide, YSide aYSide,
                                   ContextSource aSource,
                                   float aOpacity,
                                   gfx::CompositionOp aOperator,
                                   gfx::SourceSurface* aMask,
                                   const gfx::Matrix* aMaskTransform) const
 {
@@ -260,31 +156,16 @@ RotatedBuffer::DrawBufferQuadrant(gfx::D
   if (aOperator == OP_SOURCE) {
     aTarget->PopClip();
   }
 
   aTarget->Flush();
 }
 
 void
-RotatedBuffer::DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource,
-                                      float aOpacity,
-                                      gfxASurface* aMask,
-                                      const gfxMatrix* aMaskTransform) const
-{
-  PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation");
-  // Draw four quadrants. We could use REPEAT_, but it's probably better
-  // not to, to be performance-safe.
-  DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aMask, aMaskTransform);
-  DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aMask, aMaskTransform);
-  DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
-  DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
-}
-
-void
 RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
                                       float aOpacity,
                                       gfx::CompositionOp aOperator,
                                       gfx::SourceSurface* aMask,
                                       const gfx::Matrix* aMaskTransform) const
 {
   PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation");
   // See above, in Azure Repeat should always be a safe, even faster choice
@@ -292,152 +173,98 @@ RotatedBuffer::DrawBufferWithRotation(gf
   // into that. TODO[Bas]
   DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
   DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
   DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aOperator, aMask, aMaskTransform);
   DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aOperator,aMask, aMaskTransform);
 }
 
 /* static */ bool
-ThebesLayerBuffer::IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
+RotatedContentBuffer::IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
 {
   // Assume clipping is cheap if the context just has an integer
   // translation, and the visible region is simple.
   return !aTarget->CurrentMatrix().HasNonIntegerTranslation() &&
          aRegion.GetNumRects() <= 1;
 }
 
 void
-ThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
-                          gfxContext* aTarget,
-                          float aOpacity,
-                          gfxASurface* aMask,
-                          const gfxMatrix* aMaskTransform)
+RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
+                             gfxContext* aTarget,
+                             float aOpacity,
+                             gfxASurface* aMask,
+                             const gfxMatrix* aMaskTransform)
 {
   if (!EnsureBuffer()) {
     return;
   }
 
-  if (aTarget->IsCairo()) {
-    aTarget->Save();
-    // If the entire buffer is valid, we can just draw the whole thing,
-    // no need to clip. But we'll still clip if clipping is cheap ---
-    // that might let us copy a smaller region of the buffer.
-    // Also clip to the visible region if we're told to.
-    if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
-        (ToData(aLayer)->GetClipToVisibleRegion() &&
-         !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
-        IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
-      // We don't want to draw invalid stuff, so we need to clip. Might as
-      // well clip to the smallest area possible --- the visible region.
-      // Bug 599189 if there is a non-integer-translation transform in aTarget,
-      // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
-      // and may cause gray lines.
-      gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
-    }
-
-    DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aMask, aMaskTransform);
-    aTarget->Restore();
-  } else {
-    RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
-    bool clipped = false;
+  RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
+  MOZ_ASSERT(dt, "Did you pass a non-Azure gfxContext?");
+  bool clipped = false;
 
-    // If the entire buffer is valid, we can just draw the whole thing,
-    // no need to clip. But we'll still clip if clipping is cheap ---
-    // that might let us copy a smaller region of the buffer.
-    // Also clip to the visible region if we're told to.
-    if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
-        (ToData(aLayer)->GetClipToVisibleRegion() &&
-         !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
-        IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
-      // We don't want to draw invalid stuff, so we need to clip. Might as
-      // well clip to the smallest area possible --- the visible region.
-      // Bug 599189 if there is a non-integer-translation transform in aTarget,
-      // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
-      // and may cause gray lines.
-      gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
-      clipped = true;
-    }
+  // If the entire buffer is valid, we can just draw the whole thing,
+  // no need to clip. But we'll still clip if clipping is cheap ---
+  // that might let us copy a smaller region of the buffer.
+  // Also clip to the visible region if we're told to.
+  if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
+      (ToData(aLayer)->GetClipToVisibleRegion() &&
+       !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
+      IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
+    // We don't want to draw invalid stuff, so we need to clip. Might as
+    // well clip to the smallest area possible --- the visible region.
+    // Bug 599189 if there is a non-integer-translation transform in aTarget,
+    // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
+    // and may cause gray lines.
+    gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
+    clipped = true;
+  }
 
-    RefPtr<gfx::SourceSurface> mask;
-    if (aMask) {
-      mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
-    }
+  RefPtr<gfx::SourceSurface> mask;
+  if (aMask) {
+    mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
+  }
 
-    Matrix maskTransform;
-    if (aMaskTransform) {
-      maskTransform = ToMatrix(*aMaskTransform);
-    }
+  Matrix maskTransform;
+  if (aMaskTransform) {
+    maskTransform = ToMatrix(*aMaskTransform);
+  }
 
-    CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
-    DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
-    if (clipped) {
-      dt->PopClip();
-    }
+  CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
+  DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
+  if (clipped) {
+    dt->PopClip();
   }
 }
 
-static void
-FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
-            const nsIntPoint& aOffset, const gfxRGBA& aColor)
-{
-  nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
-  ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
-  gfxUtils::ClipToRegion(ctx, aRegion);
-  ctx->SetColor(aColor);
-  ctx->Paint();
-}
-
 already_AddRefed<gfxContext>
-ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint *aTopLeft)
+RotatedContentBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds,
+                                                  ContextSource aSource,
+                                                  nsIntPoint *aTopLeft)
 {
   if (!EnsureBuffer()) {
     return nullptr;
   }
 
   nsRefPtr<gfxContext> ctx;
   if (aSource == BUFFER_BOTH && HaveBufferOnWhite()) {
     if (!EnsureBufferOnWhite()) {
       return nullptr;
     }
-    if (mBuffer) {
-      MOZ_ASSERT(mBufferOnWhite);
-      gfxASurface* surfaces[2] = { mBuffer, mBufferOnWhite };
-      nsRefPtr<gfxTeeSurface> surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
-
-      // XXX If the device offset is set on the individual surfaces instead of on
-      // the tee surface, we render in the wrong place. Why?
-      gfxPoint deviceOffset = mBuffer->GetDeviceOffset();
-      surfaces[0]->SetDeviceOffset(gfxPoint(0, 0));
-      surfaces[1]->SetDeviceOffset(gfxPoint(0, 0));
-      surf->SetDeviceOffset(deviceOffset);
-
-      surf->SetAllowUseAsSource(false);
-      ctx = new gfxContext(surf);
-    } else {
-      MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
-      RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
-      ctx = new gfxContext(dualDT);
-    }
+    MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
+    RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
+    ctx = new gfxContext(dualDT);
   } else if (aSource == BUFFER_WHITE) {
     if (!EnsureBufferOnWhite()) {
       return nullptr;
     }
-    if (mBufferOnWhite) {
-      ctx = new gfxContext(mBufferOnWhite);
-    } else {
-      ctx = new gfxContext(mDTBufferOnWhite);
-    }
+    ctx = new gfxContext(mDTBufferOnWhite);
   } else {
     // BUFFER_BLACK, or BUFFER_BOTH with a single buffer.
-    if (mBuffer) {
-      ctx = new gfxContext(mBuffer);
-    } else {
-      ctx = new gfxContext(mDTBuffer);
-    }
+    ctx = new gfxContext(mDTBuffer);
   }
 
   // Figure out which quadrant to draw in
   int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
   int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
   XSide sideX = aBounds.XMost() <= xBoundary ? RIGHT : LEFT;
   YSide sideY = aBounds.YMost() <= yBoundary ? BOTTOM : TOP;
   nsIntRect quadrantRect = GetQuadrantRectangle(sideX, sideY);
@@ -447,21 +274,18 @@ ThebesLayerBuffer::GetContextForQuadrant
   if (aTopLeft) {
     *aTopLeft = nsIntPoint(quadrantRect.x, quadrantRect.y);
   }
 
   return ctx.forget();
 }
 
 gfxContentType
-ThebesLayerBuffer::BufferContentType()
+RotatedContentBuffer::BufferContentType()
 {
-  if (mBuffer) {
-    return mBuffer->GetContentType();
-  }
   if (mBufferProvider) {
     return mBufferProvider->GetContentType();
   }
   if (mDTBuffer) {
     switch (mDTBuffer->GetFormat()) {
     case FORMAT_A8:
       return GFX_CONTENT_ALPHA;
     case FORMAT_B8G8R8A8:
@@ -470,84 +294,55 @@ ThebesLayerBuffer::BufferContentType()
     default:
       return GFX_CONTENT_COLOR;
     }
   }
   return GFX_CONTENT_SENTINEL;
 }
 
 bool
-ThebesLayerBuffer::BufferSizeOkFor(const nsIntSize& aSize)
+RotatedContentBuffer::BufferSizeOkFor(const nsIntSize& aSize)
 {
   return (aSize == mBufferRect.Size() ||
           (SizedToVisibleBounds != mBufferSizePolicy &&
            aSize < mBufferRect.Size()));
 }
 
 bool
-ThebesLayerBuffer::IsAzureBuffer()
+RotatedContentBuffer::EnsureBuffer()
 {
-  MOZ_ASSERT(!(mDTBuffer && mBuffer), "Trying to use Azure and Thebes in the same buffer?");
-  if (mDTBuffer) {
-    return true;
+  if (!mDTBuffer && mBufferProvider) {
+    mDTBuffer = mBufferProvider->LockDrawTarget();
   }
-  if (mBuffer) {
-    return false;
-  }
-  if (mBufferProvider) {
-    return gfxPlatform::GetPlatform()->SupportsAzureContentForType(
-      mBufferProvider->BackendType());
-  }
-  return SupportsAzureContent();
+
+  NS_WARN_IF_FALSE(mDTBuffer, "no buffer");
+  return !!mDTBuffer;
 }
 
 bool
-ThebesLayerBuffer::EnsureBuffer()
+RotatedContentBuffer::EnsureBufferOnWhite()
 {
-  if ((!mBuffer && !mDTBuffer) && mBufferProvider) {
-    if (IsAzureBuffer()) {
-      mDTBuffer = mBufferProvider->LockDrawTarget();
-      mBuffer = nullptr;
-    } else {
-      mBuffer = mBufferProvider->LockSurface();
-      mDTBuffer = nullptr;
-    }
+  if (!mDTBufferOnWhite && mBufferProviderOnWhite) {
+    mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget();
   }
 
-  NS_WARN_IF_FALSE(mBuffer || mDTBuffer, "no buffer");
-  return mBuffer || mDTBuffer;
+  NS_WARN_IF_FALSE(mDTBufferOnWhite, "no buffer");
+  return mDTBufferOnWhite;
 }
 
 bool
-ThebesLayerBuffer::EnsureBufferOnWhite()
+RotatedContentBuffer::HaveBuffer() const
 {
-  if ((!mBufferOnWhite && !mDTBufferOnWhite) && mBufferProviderOnWhite) {
-    if (IsAzureBuffer()) {
-      mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget();
-      mBufferOnWhite = nullptr;
-    } else {
-      mBufferOnWhite = mBufferProviderOnWhite->LockSurface();
-      mDTBufferOnWhite = nullptr;
-    }
-  }
-
-  NS_WARN_IF_FALSE(mBufferOnWhite || mDTBufferOnWhite, "no buffer");
-  return mBufferOnWhite || mDTBufferOnWhite;
+  return mDTBuffer || mBufferProvider;
 }
 
 bool
-ThebesLayerBuffer::HaveBuffer() const
+RotatedContentBuffer::HaveBufferOnWhite() const
 {
-  return mDTBuffer || mBuffer || mBufferProvider;
-}
-
-bool
-ThebesLayerBuffer::HaveBufferOnWhite() const
-{
-  return mDTBufferOnWhite || mBufferOnWhite || mBufferProviderOnWhite;
+  return mDTBufferOnWhite || mBufferProviderOnWhite;
 }
 
 static void
 WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize)
 {
   if (*aRotationPoint < 0) {
     *aRotationPoint += aSize;
   } else if (*aRotationPoint >= aSize) {
@@ -577,19 +372,19 @@ ComputeBufferRect(const nsIntRect& aRequ
   // the height problem.
   if (rect.height > 0) {
     rect.height = std::max(aRequestedRect.height, 32);
   }
 #endif
   return rect;
 }
 
-ThebesLayerBuffer::PaintState
-ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
-                              uint32_t aFlags)
+RotatedContentBuffer::PaintState
+RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
+                                 uint32_t aFlags)
 {
   PaintState result;
   // We need to disable rotation if we're going to be resampled when
   // drawing, because we might sample across the rotation boundary.
   bool canHaveRotation = gfxPlatform::BufferRotationEnabled() &&
                          !(aFlags & (PAINT_WILL_RESAMPLE | PAINT_NO_ROTATION));
 
   nsIntRegion validRegion = aLayer->GetValidRegion();
@@ -660,46 +455,44 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         (mode == Layer::SURFACE_COMPONENT_ALPHA) != HaveBufferOnWhite())) {
 
       // We're effectively clearing the valid region, so we need to draw
       // the entire needed region now.
       result.mRegionToInvalidate = aLayer->GetValidRegion();
       validRegion.SetEmpty();
       Clear();
       // Restart decision process with the cleared buffer. We can only go
-      // around the loop one more iteration, since mBuffer is null now.
+      // around the loop one more iteration, since mDTBuffer is null now.
       continue;
     }
 
     break;
   }
 
   NS_ASSERTION(destBufferRect.Contains(neededRegion.GetBounds()),
                "Destination rect doesn't contain what we need to paint");
 
   result.mRegionToDraw.Sub(neededRegion, validRegion);
   if (result.mRegionToDraw.IsEmpty())
     return result;
 
   nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
-  nsRefPtr<gfxASurface> destBuffer;
-  nsRefPtr<gfxASurface> destBufferOnWhite;
   RefPtr<DrawTarget> destDTBuffer;
   RefPtr<DrawTarget> destDTBufferOnWhite;
   uint32_t bufferFlags = canHaveRotation ? ALLOW_REPEAT : 0;
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
     bufferFlags |= BUFFER_COMPONENT_ALPHA;
   }
   if (canReuseBuffer) {
     if (!EnsureBuffer()) {
       return result;
     }
     nsIntRect keepArea;
     if (keepArea.IntersectRect(destBufferRect, mBufferRect)) {
-      // Set mBufferRotation so that the pixels currently in mBuffer
+      // Set mBufferRotation so that the pixels currently in mDTBuffer
       // will still be rendered in the right place when mBufferRect
       // changes to destBufferRect.
       nsIntPoint newRotation = mBufferRotation +
         (destBufferRect.TopLeft() - mBufferRect.TopLeft());
       WrapRotationAxis(&newRotation.x, mBufferRect.width);
       WrapRotationAxis(&newRotation.y, mBufferRect.height);
       NS_ASSERTION(nsIntRect(nsIntPoint(0,0), mBufferRect.Size()).Contains(newRotation),
                    "newRotation out of bounds");
@@ -709,151 +502,107 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
           (drawBounds.y < yBoundary && yBoundary < drawBounds.YMost()) ||
           (newRotation != nsIntPoint(0,0) && !canHaveRotation)) {
         // The stuff we need to redraw will wrap around an edge of the
         // buffer, so move the pixels we can keep into a position that
         // lets us redraw in just one quadrant.
         if (mBufferRotation == nsIntPoint(0,0)) {
           nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
           nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
-          if (IsAzureBuffer()) {
-            MOZ_ASSERT(mDTBuffer);
-            mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
-                                IntPoint(dest.x, dest.y));
-            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-              if (!EnsureBufferOnWhite()) {
-                return result;
-              }
-              MOZ_ASSERT(mDTBufferOnWhite);
-              mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
-                                         IntPoint(dest.x, dest.y));
+          MOZ_ASSERT(mDTBuffer);
+          mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
+                              IntPoint(dest.x, dest.y));
+          if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
+            if (!EnsureBufferOnWhite()) {
+              return result;
             }
-          } else {
-            MOZ_ASSERT(mBuffer);
-            mBuffer->MovePixels(srcRect, dest);
-            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-              if (!EnsureBufferOnWhite()) {
-                return result;
-              }
-              MOZ_ASSERT(mBufferOnWhite);
-              mBufferOnWhite->MovePixels(srcRect, dest);
-            }
+            MOZ_ASSERT(mDTBufferOnWhite);
+            mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
+                                       IntPoint(dest.x, dest.y));
           }
           result.mDidSelfCopy = true;
           mDidSelfCopy = true;
           // Don't set destBuffer; we special-case self-copies, and
           // just did the necessary work above.
           mBufferRect = destBufferRect;
         } else {
           // With azure and a data surface perform an buffer unrotate
           // (SelfCopy).
-          if (IsAzureBuffer()) {
-            unsigned char* data;
-            IntSize size;
-            int32_t stride;
-            SurfaceFormat format;
+          unsigned char* data;
+          IntSize size;
+          int32_t stride;
+          SurfaceFormat format;
 
-            if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
+          if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
+            uint8_t bytesPerPixel = BytesPerPixel(format);
+            BufferUnrotate(data,
+                           size.width * bytesPerPixel,
+                           size.height, stride,
+                           newRotation.x * bytesPerPixel, newRotation.y);
+            mDTBuffer->ReleaseBits(data);
+
+            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
+              if (!EnsureBufferOnWhite()) {
+                return result;
+              }
+              MOZ_ASSERT(mDTBufferOnWhite);
+              mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
               uint8_t bytesPerPixel = BytesPerPixel(format);
               BufferUnrotate(data,
                              size.width * bytesPerPixel,
                              size.height, stride,
                              newRotation.x * bytesPerPixel, newRotation.y);
-              mDTBuffer->ReleaseBits(data);
+              mDTBufferOnWhite->ReleaseBits(data);
+            }
 
-              if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-                if (!EnsureBufferOnWhite()) {
-                  return result;
-                }
-                MOZ_ASSERT(mDTBufferOnWhite);
-                mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
-                uint8_t bytesPerPixel = BytesPerPixel(format);
-                BufferUnrotate(data,
-                               size.width * bytesPerPixel,
-                               size.height, stride,
-                               newRotation.x * bytesPerPixel, newRotation.y);
-                mDTBufferOnWhite->ReleaseBits(data);
-              }
-
-              // Buffer unrotate moves all the pixels, note that
-              // we self copied for SyncBackToFrontBuffer
-              result.mDidSelfCopy = true;
-              mDidSelfCopy = true;
-              mBufferRect = destBufferRect;
-              mBufferRotation = nsIntPoint(0, 0);
-            }
+            // Buffer unrotate moves all the pixels, note that
+            // we self copied for SyncBackToFrontBuffer
+            result.mDidSelfCopy = true;
+            mDidSelfCopy = true;
+            mBufferRect = destBufferRect;
+            mBufferRotation = nsIntPoint(0, 0);
           }
 
           if (!result.mDidSelfCopy) {
             destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
             CreateBuffer(contentType, destBufferRect, bufferFlags,
-                         getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
                          &destDTBuffer, &destDTBufferOnWhite);
-            if (!destBuffer && !destDTBuffer)
+            if (!destDTBuffer) {
               return result;
+            }
           }
         }
       } else {
         mBufferRect = destBufferRect;
         mBufferRotation = newRotation;
       }
     } else {
       // No pixels are going to be kept. The whole visible region
       // will be redrawn, so we don't need to copy anything, so we don't
       // set destBuffer.
       mBufferRect = destBufferRect;
       mBufferRotation = nsIntPoint(0,0);
     }
   } else {
     // The buffer's not big enough, so allocate a new one
     CreateBuffer(contentType, destBufferRect, bufferFlags,
-                 getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
                  &destDTBuffer, &destDTBufferOnWhite);
-    if (!destBuffer && !destDTBuffer)
+    if (!destDTBuffer) {
       return result;
+    }
   }
 
   NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(),
                "If we're resampling, we need to validate the entire buffer");
 
   // If we have no buffered data already, then destBuffer will be a fresh buffer
   // and we do not need to clear it below.
   bool isClear = !HaveBuffer();
 
-  if (destBuffer) {
-    if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
-      // Copy the bits
-      nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBuffer);
-      nsIntPoint offset = -destBufferRect.TopLeft();
-      tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
-      tmpCtx->Translate(gfxPoint(offset.x, offset.y));
-      if (!EnsureBuffer()) {
-        return result;
-      }
-      DrawBufferWithRotation(tmpCtx, BUFFER_BLACK);
-
-      if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-        if (!EnsureBufferOnWhite()) {
-          return result;
-        }
-        NS_ASSERTION(destBufferOnWhite, "Must have a white buffer!");
-        nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBufferOnWhite);
-        tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
-        tmpCtx->Translate(gfxPoint(offset.x, offset.y));
-        DrawBufferWithRotation(tmpCtx, BUFFER_WHITE);
-      }
-    }
-
-    mBuffer = destBuffer.forget();
-    mDTBuffer = nullptr;
-    mBufferRect = destBufferRect;
-    mBufferOnWhite = destBufferOnWhite.forget();
-    mDTBufferOnWhite = nullptr;
-    mBufferRotation = nsIntPoint(0,0);
-  } else if (destDTBuffer) {
+  if (destDTBuffer) {
     if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
       // Copy the bits
       nsIntPoint offset = -destBufferRect.TopLeft();
       Matrix mat;
       mat.Translate(offset.x, offset.y);
       destDTBuffer->SetTransform(mat);
       if (!EnsureBuffer()) {
         return result;
@@ -870,65 +619,46 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         }
         MOZ_ASSERT(mDTBufferOnWhite, "Have we got a Thebes buffer for some reason?");
         DrawBufferWithRotation(destDTBufferOnWhite, BUFFER_WHITE, 1.0, OP_SOURCE);
         destDTBufferOnWhite->SetTransform(Matrix());
       }
     }
 
     mDTBuffer = destDTBuffer.forget();
-    mBuffer = nullptr;
     mDTBufferOnWhite = destDTBufferOnWhite.forget();
-    mBufferOnWhite = nullptr;
     mBufferRect = destBufferRect;
     mBufferRotation = nsIntPoint(0,0);
   }
   NS_ASSERTION(canHaveRotation || mBufferRotation == nsIntPoint(0,0),
                "Rotation disabled, but we have nonzero rotation?");
 
   nsIntRegion invalidate;
   invalidate.Sub(aLayer->GetValidRegion(), destBufferRect);
   result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate);
 
   nsIntPoint topLeft;
   result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
   result.mClip = CLIP_DRAW_SNAPPED;
 
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-    if (IsAzureBuffer()) {
-      MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
-      nsIntRegionRectIterator iter(result.mRegionToDraw);
-      const nsIntRect *iterRect;
-      while ((iterRect = iter.Next())) {
-        mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
-                            ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
-        mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
-                                   ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
-      }
-    } else {
-      MOZ_ASSERT(mBuffer && mBufferOnWhite);
-      FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
-      FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
+    MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
+    nsIntRegionRectIterator iter(result.mRegionToDraw);
+    const nsIntRect *iterRect;
+    while ((iterRect = iter.Next())) {
+      mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
+                          ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
+      mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
+                                 ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
     }
   } else if (contentType == GFX_CONTENT_COLOR_ALPHA && !isClear) {
-    if (IsAzureBuffer()) {
-      nsIntRegionRectIterator iter(result.mRegionToDraw);
-      const nsIntRect *iterRect;
-      while ((iterRect = iter.Next())) {
-        result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
-      }
-      // Clear will do something expensive with a complex clip pushed, so clip
-      // here.
-    } else {
-      MOZ_ASSERT(result.mContext->IsCairo());
-      result.mContext->Save();
-      gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
-      result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
-      result.mContext->Paint();
-      result.mContext->Restore();
+    nsIntRegionRectIterator iter(result.mRegionToDraw);
+    const nsIntRect *iterRect;
+    while ((iterRect = iter.Next())) {
+      result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     }
   }
 
   return result;
 }
 
 }
 }
rename from gfx/layers/ThebesLayerBuffer.h
rename to gfx/layers/RotatedBuffer.h
--- a/gfx/layers/ThebesLayerBuffer.h
+++ b/gfx/layers/RotatedBuffer.h
@@ -1,27 +1,26 @@
 /* -*- 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 THEBESLAYERBUFFER_H_
-#define THEBESLAYERBUFFER_H_
+#ifndef ROTATEDBUFFER_H_
+#define ROTATEDBUFFER_H_
 
 #include <stdint.h>                     // for uint32_t
 #include "gfxASurface.h"                // for gfxASurface, etc
 #include "gfxContext.h"                 // for gfxContext
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef
 #include "mozilla/gfx/2D.h"             // for DrawTarget, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
-#include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRect.h"                     // for nsIntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "LayersTypes.h"
 
 struct gfxMatrix;
 struct nsIntSize;
@@ -50,25 +49,16 @@ class ThebesLayer;
  * at row 0 on the screen, and then painting rows 0 to N-1 of the buffer
  * at row H-N on the screen.
  * mBufferRotation.y would be N in this example.
  */
 class RotatedBuffer {
 public:
   typedef gfxContentType ContentType;
 
-  RotatedBuffer(gfxASurface* aBuffer, gfxASurface* aBufferOnWhite,
-                const nsIntRect& aBufferRect,
-                const nsIntPoint& aBufferRotation)
-    : mBuffer(aBuffer)
-    , mBufferOnWhite(aBufferOnWhite)
-    , mBufferRect(aBufferRect)
-    , mBufferRotation(aBufferRotation)
-    , mDidSelfCopy(false)
-  { }
   RotatedBuffer(gfx::DrawTarget* aDTBuffer, gfx::DrawTarget* aDTBufferOnWhite,
                 const nsIntRect& aBufferRect,
                 const nsIntPoint& aBufferRotation)
     : mDTBuffer(aDTBuffer)
     , mDTBufferOnWhite(aDTBufferOnWhite)
     , mBufferRect(aBufferRect)
     , mBufferRotation(aBufferRotation)
     , mDidSelfCopy(false)
@@ -80,37 +70,32 @@ public:
   /*
    * Which buffer should be drawn to/read from.
    */
   enum ContextSource {
     BUFFER_BLACK, // The normal buffer, or buffer with black background when using component alpha.
     BUFFER_WHITE, // The buffer with white background, only valid with component alpha.
     BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading.
   };
-  void DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource,
-                              float aOpacity = 1.0,
-                              gfxASurface* aMask = nullptr,
-                              const gfxMatrix* aMaskTransform = nullptr) const;
-
   void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
                               float aOpacity = 1.0,
                               gfx::CompositionOp aOperator = gfx::OP_OVER,
                               gfx::SourceSurface* aMask = nullptr,
                               const gfx::Matrix* aMaskTransform = nullptr) const;
 
   /**
    * |BufferRect()| is the rect of device pixels that this
-   * ThebesLayerBuffer covers.  That is what DrawBufferWithRotation()
+   * RotatedBuffer covers.  That is what DrawBufferWithRotation()
    * will paint when it's called.
    */
   const nsIntRect& BufferRect() const { return mBufferRect; }
   const nsIntPoint& BufferRotation() const { return mBufferRotation; }
 
-  virtual bool HaveBuffer() const { return mBuffer || mDTBuffer; }
-  virtual bool HaveBufferOnWhite() const { return mBufferOnWhite || mDTBufferOnWhite; }
+  virtual bool HaveBuffer() const { return mDTBuffer; }
+  virtual bool HaveBufferOnWhite() const { return mDTBufferOnWhite; }
 
 protected:
 
   enum XSide {
     LEFT, RIGHT
   };
   enum YSide {
     TOP, BOTTOM
@@ -119,30 +104,23 @@ protected:
 
   gfx::Rect GetSourceRectangle(XSide aXSide, YSide aYSide) const;
 
   /*
    * If aMask is non-null, then it is used as an alpha mask for rendering this
    * buffer. aMaskTransform must be non-null if aMask is non-null, and is used
    * to adjust the coordinate space of the mask.
    */
-  void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide,
-                          ContextSource aSource,
-                          float aOpacity,
-                          gfxASurface* aMask,
-                          const gfxMatrix* aMaskTransform) const;
   void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide,
                           ContextSource aSource,
                           float aOpacity,
                           gfx::CompositionOp aOperator,
                           gfx::SourceSurface* aMask,
                           const gfx::Matrix* aMaskTransform) const;
 
-  nsRefPtr<gfxASurface> mBuffer;
-  nsRefPtr<gfxASurface> mBufferOnWhite;
   RefPtr<gfx::DrawTarget> mDTBuffer;
   RefPtr<gfx::DrawTarget> mDTBufferOnWhite;
   /** The area of the ThebesLayer that is covered by the buffer as a whole */
   nsIntRect             mBufferRect;
   /**
    * The x and y rotation of the buffer. Conceptually the buffer
    * has its origin translated to mBufferRect.TopLeft() - mBufferRotation,
    * is tiled to fill the plane, and the result is clipped to mBufferRect.
@@ -157,63 +135,61 @@ protected:
   // It's not possible to sync with another buffer without a full copy.
   bool                  mDidSelfCopy;
 };
 
 /**
  * This class encapsulates the buffer used to retain ThebesLayer contents,
  * i.e., the contents of the layer's GetVisibleRegion().
  */
-class ThebesLayerBuffer : public RotatedBuffer {
+class RotatedContentBuffer : public RotatedBuffer {
 public:
   typedef gfxContentType ContentType;
 
   /**
    * Controls the size of the backing buffer of this.
    * - SizedToVisibleBounds: the backing buffer is exactly the same
    *   size as the bounds of ThebesLayer's visible region
    * - ContainsVisibleBounds: the backing buffer is large enough to
    *   fit visible bounds.  May be larger.
    */
   enum BufferSizePolicy {
     SizedToVisibleBounds,
     ContainsVisibleBounds
   };
 
-  ThebesLayerBuffer(BufferSizePolicy aBufferSizePolicy)
+  RotatedContentBuffer(BufferSizePolicy aBufferSizePolicy)
     : mBufferProvider(nullptr)
     , mBufferProviderOnWhite(nullptr)
     , mBufferSizePolicy(aBufferSizePolicy)
   {
-    MOZ_COUNT_CTOR(ThebesLayerBuffer);
+    MOZ_COUNT_CTOR(RotatedContentBuffer);
   }
-  virtual ~ThebesLayerBuffer()
+  virtual ~RotatedContentBuffer()
   {
-    MOZ_COUNT_DTOR(ThebesLayerBuffer);
+    MOZ_COUNT_DTOR(RotatedContentBuffer);
   }
 
   /**
    * Wipe out all retained contents. Call this when the entire
    * buffer becomes invalid.
    */
   void Clear()
   {
-    mBuffer = nullptr;
-    mBufferOnWhite = nullptr;
     mDTBuffer = nullptr;
     mDTBufferOnWhite = nullptr;
     mBufferProvider = nullptr;
     mBufferProviderOnWhite = nullptr;
     mBufferRect.SetEmpty();
   }
 
   /**
    * This is returned by BeginPaint. The caller should draw into mContext.
    * mRegionToDraw must be drawn. mRegionToInvalidate has been invalidated
-   * by ThebesLayerBuffer and must be redrawn on the screen.
+   * by RotatedContentBuffer and must be redrawn on the screen.
    * mRegionToInvalidate is set when the buffer has changed from
    * opaque to transparent or vice versa, since the details of rendering can
    * depend on the buffer type.  mDidSelfCopy is true if we kept our buffer
    * but used MovePixels() to shift its content.
    */
   struct PaintState {
     PaintState()
       : mDidSelfCopy(false)
@@ -259,137 +235,102 @@ public:
    * @param aFlags if ALLOW_REPEAT is set, then the buffer should be configured
    * to allow repeat-mode, otherwise it should be in pad (clamp) mode
    * If the created buffer supports azure content, then the result(s) will
    * be returned in aBlackDT/aWhiteDT, otherwise aBlackSurface/aWhiteSurface
    * will be used.
    */
   virtual void
   CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
-               gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
                RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) = 0;
-  virtual bool SupportsAzureContent() const 
-  { return false; }
 
   /**
    * Get the underlying buffer, if any. This is useful because we can pass
    * in the buffer as the default "reference surface" if there is one.
    * Don't use it for anything else!
    */
-  gfxASurface* GetBuffer() { return mBuffer; }
-  gfxASurface* GetBufferOnWhite() { return mBufferOnWhite; }
   gfx::DrawTarget* GetDTBuffer() { return mDTBuffer; }
   gfx::DrawTarget* GetDTBufferOnWhite() { return mDTBufferOnWhite; }
 
   /**
    * Complete the drawing operation. The region to draw must have been
    * drawn before this is called. The contents of the buffer are drawn
    * to aTarget.
    */
   void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
               gfxASurface* aMask, const gfxMatrix* aMaskTransform);
 
 protected:
-  // If this buffer is currently using Azure.
-  bool IsAzureBuffer();
-
-  already_AddRefed<gfxASurface>
-  SetBuffer(gfxASurface* aBuffer,
-            const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
-  {
-    MOZ_ASSERT(!SupportsAzureContent());
-    nsRefPtr<gfxASurface> tmp = mBuffer.forget();
-    mBuffer = aBuffer;
-    mBufferRect = aBufferRect;
-    mBufferRotation = aBufferRotation;
-    return tmp.forget();
-  }
-
-  already_AddRefed<gfxASurface>
-  SetBufferOnWhite(gfxASurface* aBuffer)
-  {
-    MOZ_ASSERT(!SupportsAzureContent());
-    nsRefPtr<gfxASurface> tmp = mBufferOnWhite.forget();
-    mBufferOnWhite = aBuffer;
-    return tmp.forget();
-  }
-
   TemporaryRef<gfx::DrawTarget>
   SetDTBuffer(gfx::DrawTarget* aBuffer,
-            const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
+              const nsIntRect& aBufferRect,
+              const nsIntPoint& aBufferRotation)
   {
-    MOZ_ASSERT(SupportsAzureContent());
     RefPtr<gfx::DrawTarget> tmp = mDTBuffer.forget();
     mDTBuffer = aBuffer;
     mBufferRect = aBufferRect;
     mBufferRotation = aBufferRotation;
     return tmp.forget();
   }
 
   TemporaryRef<gfx::DrawTarget>
   SetDTBufferOnWhite(gfx::DrawTarget* aBuffer)
   {
-    MOZ_ASSERT(SupportsAzureContent());
     RefPtr<gfx::DrawTarget> tmp = mDTBufferOnWhite.forget();
     mDTBufferOnWhite = aBuffer;
     return tmp.forget();
   }
 
   /**
    * Set the texture client only.  This is used with surfaces that
    * require explicit lock/unlock, which |aClient| is used to do on
    * demand in this code.
    *
    * It's the caller's responsibility to ensure |aClient| is valid
    * for the duration of operations it requests of this
-   * ThebesLayerBuffer.  It's also the caller's responsibility to
+   * RotatedContentBuffer.  It's also the caller's responsibility to
    * unset the provider when inactive, by calling
    * SetBufferProvider(nullptr).
    */
   void SetBufferProvider(DeprecatedTextureClient* aClient)
   {
     // Only this buffer provider can give us a buffer.  If we
     // already have one, something has gone wrong.
-    MOZ_ASSERT(!aClient || (!mBuffer && !mDTBuffer));
+    MOZ_ASSERT(!aClient || !mDTBuffer);
 
     mBufferProvider = aClient;
     if (!mBufferProvider) {
-      mBuffer = nullptr;
       mDTBuffer = nullptr;
     } 
   }
   
   void SetBufferProviderOnWhite(DeprecatedTextureClient* aClient)
   {
     // Only this buffer provider can give us a buffer.  If we
     // already have one, something has gone wrong.
-    MOZ_ASSERT(!aClient || (!mBufferOnWhite && !mDTBufferOnWhite));
+    MOZ_ASSERT(!aClient || !mDTBufferOnWhite);
 
     mBufferProviderOnWhite = aClient;
     if (!mBufferProviderOnWhite) {
-      mBufferOnWhite = nullptr;
       mDTBufferOnWhite = nullptr;
     } 
   }
 
   /**
    * Get a context at the specified resolution for updating |aBounds|,
    * which must be contained within a single quadrant.
    *
    * Optionally returns the TopLeft coordinate of the quadrant being drawn to.
    */
   already_AddRefed<gfxContext>
   GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint* aTopLeft = nullptr);
 
   static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion);
 
 protected:
-  // Buffer helpers.  Don't use mBuffer directly; instead use one of
-  // these helpers.
-
   /**
    * Return the buffer's content type.  Requires a valid buffer or
    * buffer provider.
    */
   gfxContentType BufferContentType();
   bool BufferSizeOkFor(const nsIntSize& aSize);
   /**
    * If the buffer hasn't been mapped, map it.
@@ -399,22 +340,22 @@ protected:
   /**
    * True if we have a buffer where we can get it (but not necessarily
    * mapped currently).
    */
   virtual bool HaveBuffer() const;
   virtual bool HaveBufferOnWhite() const;
 
   /**
-   * These members are only set transiently.  They're used to map mBuffer
+   * These members are only set transiently.  They're used to map mDTBuffer
    * when we're using surfaces that require explicit map/unmap. Only one
    * may be used at a time.
    */
   DeprecatedTextureClient* mBufferProvider;
   DeprecatedTextureClient* mBufferProviderOnWhite;
 
   BufferSizePolicy      mBufferSizePolicy;
 };
 
 }
 }
 
-#endif /* THEBESLAYERBUFFER_H_ */
+#endif /* ROTATEDBUFFER_H_ */
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -92,16 +92,17 @@ BasicLayerManager::PushGroupForLayer(gfx
   if (aLayer->CanUseOpaqueSurface() &&
       ((didCompleteClip && aRegion.GetNumRects() == 1) ||
        !aContext->CurrentMatrix().HasNonIntegerTranslation())) {
     // If the layer is opaque in its visible region we can push a GFX_CONTENT_COLOR
     // group. We need to make sure that only pixels inside the layer's visible
     // region are copied back to the destination. Remember if we've already
     // clipped precisely to the visible region.
     *aNeedsClipToVisibleRegion = !didCompleteClip || aRegion.GetNumRects() > 1;
+    MOZ_ASSERT(!aContext->IsCairo());
     result = PushGroupWithCachedSurface(aContext, GFX_CONTENT_COLOR);
   } else {
     *aNeedsClipToVisibleRegion = false;
     result = aContext;
     if (aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) {
       aContext->PushGroupAndCopyBackground(GFX_CONTENT_COLOR_ALPHA);
     } else {
       aContext->PushGroup(GFX_CONTENT_COLOR_ALPHA);
@@ -709,33 +710,33 @@ BasicLayerManager_Matrix3DToPixman(const
 
   pixman_transform result;
   pixman_transform_from_pixman_f_transform(&result, &transform);
 
   return result;
 }
 
 static void
-PixmanTransform(const gfxImageSurface *aDest, 
-                const gfxImageSurface *aSrc, 
-                const gfx3DMatrix& aTransform, 
+PixmanTransform(const gfxImageSurface* aDest,
+                RefPtr<DataSourceSurface> aSrc,
+                const gfx3DMatrix& aTransform,
                 gfxPoint aDestOffset)
 {
   gfxIntSize destSize = aDest->GetSize();
   pixman_image_t* dest = pixman_image_create_bits(aDest->Format() == gfxImageFormatARGB32 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
                                                   destSize.width,
                                                   destSize.height,
                                                   (uint32_t*)aDest->Data(),
                                                   aDest->Stride());
 
-  gfxIntSize srcSize = aSrc->GetSize();
-  pixman_image_t* src = pixman_image_create_bits(aSrc->Format() == gfxImageFormatARGB32 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
+  IntSize srcSize = aSrc->GetSize();
+  pixman_image_t* src = pixman_image_create_bits(aSrc->GetFormat() == FORMAT_B8G8R8A8 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
                                                  srcSize.width,
                                                  srcSize.height,
-                                                 (uint32_t*)aSrc->Data(),
+                                                 (uint32_t*)aSrc->GetData(),
                                                  aSrc->Stride());
 
   NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?");
 
   pixman_transform pixTransform = BasicLayerManager_Matrix3DToPixman(aTransform);
   pixman_transform pixTransformInverted;
 
   // If the transform is singular then nothing would be drawn anyway, return here
@@ -767,72 +768,50 @@ PixmanTransform(const gfxImageSurface *a
  *
  * @param aSource       Source surface.
  * @param aDest         Desintation context.
  * @param aBounds       Area represented by aSource.
  * @param aTransform    Transformation matrix.
  * @param aDestRect     Output: rectangle in which to draw returned surface on aDest
  *                      (same size as aDest). Only filled in if this returns
  *                      a surface.
- * @param aDontBlit     Never draw to aDest if this is true.
- * @return              Transformed surface, or nullptr if it has been drawn to aDest.
+ * @return              Transformed surface
  */
-static already_AddRefed<gfxASurface> 
-Transform3D(gfxASurface* aSource, gfxContext* aDest, 
-            const gfxRect& aBounds, const gfx3DMatrix& aTransform, 
-            gfxRect& aDestRect, bool aDontBlit)
+static already_AddRefed<gfxASurface>
+Transform3D(RefPtr<SourceSurface> aSource,
+            gfxContext* aDest,
+            const gfxRect& aBounds,
+            const gfx3DMatrix& aTransform,
+            gfxRect& aDestRect)
 {
-  nsRefPtr<gfxImageSurface> sourceImage = aSource->GetAsImageSurface();
-  if (!sourceImage) {
-    sourceImage = new gfxImageSurface(gfxIntSize(aBounds.width, aBounds.height), gfxPlatform::GetPlatform()->OptimalFormatForContent(aSource->GetContentType()));
-    nsRefPtr<gfxContext> ctx = new gfxContext(sourceImage);
-
-    aSource->SetDeviceOffset(gfxPoint(0, 0));
-    ctx->SetSource(aSource);
-    ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-    ctx->Paint();
-  }
-
   // Find the transformed rectangle of our layer.
   gfxRect offsetRect = aTransform.TransformBounds(aBounds);
 
   // Intersect the transformed layer with the destination rectangle.
   // This is in device space since we have an identity transform set on aTarget.
   aDestRect = aDest->GetClipExtents();
   aDestRect.IntersectRect(aDestRect, offsetRect);
   aDestRect.RoundOut();
 
   // Create a surface the size of the transformed object.
   nsRefPtr<gfxASurface> dest = aDest->CurrentSurface();
-  nsRefPtr<gfxImageSurface> destImage;
-  gfxPoint offset;
-  bool blitComplete;
-  if (!destImage || aDontBlit || !aDest->ClipContainsRect(aDestRect)) {
-    destImage = new gfxImageSurface(gfxIntSize(aDestRect.width, aDestRect.height),
-                                    gfxImageFormatARGB32);
-    offset = aDestRect.TopLeft();
-    blitComplete = false;
-  } else {
-    offset = -dest->GetDeviceOffset();
-    blitComplete = true;
-  }
+  nsRefPtr<gfxImageSurface> destImage = new gfxImageSurface(gfxIntSize(aDestRect.width,
+                                                                       aDestRect.height),
+                                                            gfxImageFormatARGB32);
+  gfxPoint offset = aDestRect.TopLeft();
 
   // Include a translation to the correct origin.
   gfx3DMatrix translation = gfx3DMatrix::Translation(aBounds.x, aBounds.y, 0);
 
   // Transform the content and offset it such that the content begins at the origin.
-  PixmanTransform(destImage, sourceImage, translation * aTransform, offset);
-
-  if (blitComplete) {
-    return nullptr;
-  }
+  PixmanTransform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
 
   // If we haven't actually drawn to aDest then return our temporary image so
   // that the caller can do this.
-  return destImage.forget(); 
+  return destImage.forget();
 }
 
 void
 BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
                                        gfxContext* aGroupTarget)
 {
   BasicImplData* data = ToData(aPaintContext.mLayer);
 
@@ -967,50 +946,50 @@ BasicLayerManager::PaintLayer(gfxContext
       PaintSelfOrChildren(paintLayerContext, groupTarget);
       PopGroupToSourceWithCachedSurface(aTarget, groupTarget);
       FlushGroup(paintLayerContext, needsClipToVisibleRegion);
     } else {
       PaintSelfOrChildren(paintLayerContext, aTarget);
     }
   } else {
     const nsIntRect& bounds = visibleRegion.GetBounds();
-    nsRefPtr<gfxASurface> untransformedSurface =
-      gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
-                                                         GFX_CONTENT_COLOR_ALPHA);
-    if (!untransformedSurface) {
+    RefPtr<DrawTarget> untransformedDT =
+      gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(bounds.width, bounds.height),
+                                                                   FORMAT_B8G8R8A8);
+    if (!untransformedDT) {
       return;
     }
-    untransformedSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y));
-    nsRefPtr<gfxContext> groupTarget = new gfxContext(untransformedSurface);
+
+    nsRefPtr<gfxContext> groupTarget = new gfxContext(untransformedDT);
+    groupTarget->Translate(gfxPoint(-bounds.x, -bounds.y));
 
     PaintSelfOrChildren(paintLayerContext, groupTarget);
 
     // Temporary fast fix for bug 725886
     // Revert these changes when 725886 is ready
-    NS_ABORT_IF_FALSE(untransformedSurface,
+    NS_ABORT_IF_FALSE(untransformedDT,
                       "We should always allocate an untransformed surface with 3d transforms!");
     gfxRect destRect;
-    bool dontBlit = needsClipToVisibleRegion || mTransactionIncomplete ||
-                      aLayer->GetEffectiveOpacity() != 1.0f;
 #ifdef DEBUG
     if (aLayer->GetDebugColorIndex() != 0) {
       gfxRGBA  color((aLayer->GetDebugColorIndex() & 1) ? 1.0 : 0.0,
                      (aLayer->GetDebugColorIndex() & 2) ? 1.0 : 0.0,
                      (aLayer->GetDebugColorIndex() & 4) ? 1.0 : 0.0,
                      1.0);
 
-      nsRefPtr<gfxContext> temp = new gfxContext(untransformedSurface);
+      nsRefPtr<gfxContext> temp = new gfxContext(untransformedDT);
+      temp->Translate(gfxPoint(-bounds.x, -bounds.y));
       temp->SetColor(color);
       temp->Paint();
     }
 #endif
     const gfx3DMatrix& effectiveTransform = aLayer->GetEffectiveTransform();
     nsRefPtr<gfxASurface> result =
-      Transform3D(untransformedSurface, aTarget, bounds,
-                  effectiveTransform, destRect, dontBlit);
+      Transform3D(untransformedDT->Snapshot(), aTarget, bounds,
+                  effectiveTransform, destRect);
 
     if (result) {
       aTarget->SetSource(result, destRect.TopLeft());
       // Azure doesn't support EXTEND_NONE, so to avoid extending the edges
       // of the source surface out to the current clip region, clip to
       // the rectangle of the result surface now.
       aTarget->NewPath();
       aTarget->SnappedRectangle(destRect);
--- a/gfx/layers/basic/BasicThebesLayer.cpp
+++ b/gfx/layers/basic/BasicThebesLayer.cpp
@@ -168,26 +168,26 @@ BasicThebesLayer::Validate(LayerManager:
   bool canUseOpaqueSurface = CanUseOpaqueSurface();
   ContentType contentType =
     canUseOpaqueSurface ? GFX_CONTENT_COLOR :
                           GFX_CONTENT_COLOR_ALPHA;
 
   uint32_t flags = 0;
 #ifndef MOZ_WIDGET_ANDROID
   if (BasicManager()->CompositorMightResample()) {
-    flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
+    flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
   }
-  if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
+  if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) {
     if (MayResample()) {
-      flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
+      flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
     }
   }
 #endif
   if (mDrawAtomically) {
-    flags |= ThebesLayerBuffer::PAINT_NO_ROTATION;
+    flags |= RotatedContentBuffer::PAINT_NO_ROTATION;
   }
   PaintState state =
     mContentClient->BeginPaintBuffer(this, contentType, flags);
   mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
   if (state.mContext) {
     // The area that became invalid and is visible needs to be repainted
     // (this could be the whole visible area if our buffer switched
--- a/gfx/layers/basic/BasicThebesLayer.h
+++ b/gfx/layers/basic/BasicThebesLayer.h
@@ -2,17 +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 GFX_BASICTHEBESLAYER_H
 #define GFX_BASICTHEBESLAYER_H
 
 #include "Layers.h"                     // for ThebesLayer, LayerManager, etc
-#include "ThebesLayerBuffer.h"          // for ThebesLayerBuffer, etc
+#include "RotatedBuffer.h"              // for RotatedContentBuffer, etc
 #include "BasicImplData.h"              // for BasicImplData
 #include "BasicLayers.h"                // for BasicLayerManager
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
 #include "gfxPoint.h"                   // for gfxPoint
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/layers/ContentClient.h"  // for ContentClientBasic
 #include "mozilla/mozalloc.h"           // for operator delete
@@ -23,18 +23,18 @@ class gfxContext;
 
 namespace mozilla {
 namespace layers {
 
 class ReadbackProcessor;
 
 class BasicThebesLayer : public ThebesLayer, public BasicImplData {
 public:
-  typedef ThebesLayerBuffer::PaintState PaintState;
-  typedef ThebesLayerBuffer::ContentType ContentType;
+  typedef RotatedContentBuffer::PaintState PaintState;
+  typedef RotatedContentBuffer::ContentType ContentType;
 
   BasicThebesLayer(BasicLayerManager* aLayerManager) :
     ThebesLayer(aLayerManager,
                 static_cast<BasicImplData*>(MOZ_THIS_IN_INITIALIZER_LIST())),
     mContentClient(nullptr)
   {
     MOZ_COUNT_CTOR(BasicThebesLayer);
   }
--- a/gfx/layers/client/ClientThebesLayer.cpp
+++ b/gfx/layers/client/ClientThebesLayer.cpp
@@ -44,21 +44,21 @@ ClientThebesLayer::PaintThebes()
   ContentType contentType =
     canUseOpaqueSurface ? GFX_CONTENT_COLOR :
                           GFX_CONTENT_COLOR_ALPHA;
 
   {
     uint32_t flags = 0;
 #ifndef MOZ_WIDGET_ANDROID
     if (ClientManager()->CompositorMightResample()) {
-      flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
+      flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
     }
-    if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
+    if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) {
       if (MayResample()) {
-        flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
+        flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
       }
     }
 #endif
     PaintState state =
       mContentClient->BeginPaintBuffer(this, contentType, flags);
     mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
     if (state.mContext) {
--- a/gfx/layers/client/ClientThebesLayer.h
+++ b/gfx/layers/client/ClientThebesLayer.h
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_CLIENTTHEBESLAYER_H
 #define GFX_CLIENTTHEBESLAYER_H
 
 #include "ClientLayerManager.h"         // for ClientLayerManager, etc
 #include "Layers.h"                     // for ThebesLayer, etc
-#include "ThebesLayerBuffer.h"          // for ThebesLayerBuffer, etc
+#include "RotatedBuffer.h"              // for RotatedContentBuffer, etc
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/layers/ContentClient.h"  // for ContentClient
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "mozilla/layers/PLayerTransaction.h" // for ThebesLayerAttributes
@@ -25,18 +25,18 @@ namespace layers {
 
 class CompositableClient;
 class ShadowableLayer;
 class SpecificLayerAttributes;
 
 class ClientThebesLayer : public ThebesLayer, 
                           public ClientLayer {
 public:
-  typedef ThebesLayerBuffer::PaintState PaintState;
-  typedef ThebesLayerBuffer::ContentType ContentType;
+  typedef RotatedContentBuffer::PaintState PaintState;
+  typedef RotatedContentBuffer::ContentType ContentType;
 
   ClientThebesLayer(ClientLayerManager* aLayerManager) :
     ThebesLayer(aLayerManager,
                 static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST())),
     mContentClient(nullptr)
   {
     MOZ_COUNT_CTOR(ClientThebesLayer);
   }
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -70,54 +70,36 @@ ContentClient::CreateContentClient(Compo
   }
 #endif
   return new ContentClientSingleBuffered(aForwarder);
 
 }
 
 ContentClientBasic::ContentClientBasic(CompositableForwarder* aForwarder,
                                        BasicLayerManager* aManager)
-: ContentClient(aForwarder), ThebesLayerBuffer(ContainsVisibleBounds), mManager(aManager)
+  : ContentClient(aForwarder)
+  , RotatedContentBuffer(ContainsVisibleBounds)
+  , mManager(aManager)
 {}
 
 void
 ContentClientBasic::CreateBuffer(ContentType aType,
                                  const nsIntRect& aRect,
                                  uint32_t aFlags,
-                                 gfxASurface** aBlackSurface,
-                                 gfxASurface** aWhiteSurface,
                                  RefPtr<gfx::DrawTarget>* aBlackDT,
                                  RefPtr<gfx::DrawTarget>* aWhiteDT)
 {
   MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA));
-  if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
-    gfxImageFormat format =
-      gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
-
-    *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
-      IntSize(aRect.width, aRect.height),
-      ImageFormatToSurfaceFormat(format));
-    return;
-  }
+  MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
+  gfxImageFormat format =
+    gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
 
-  nsRefPtr<gfxASurface> referenceSurface = GetBuffer();
-  if (!referenceSurface) {
-    gfxContext* defaultTarget = mManager->GetDefaultTarget();
-    if (defaultTarget) {
-      referenceSurface = defaultTarget->CurrentSurface();
-    } else {
-      nsIWidget* widget = mManager->GetRetainerWidget();
-      if (!widget || !(referenceSurface = widget->GetThebesSurface())) {
-        referenceSurface = mManager->GetTarget()->CurrentSurface();
-      }
-    }
-  }
-  nsRefPtr<gfxASurface> ret = referenceSurface->CreateSimilarSurface(
-    aType, gfxIntSize(aRect.width, aRect.height));
-  *aBlackSurface = ret.forget().get();
+  *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+    IntSize(aRect.width, aRect.height),
+    ImageFormatToSurfaceFormat(format));
 }
 
 void
 ContentClientRemoteBuffer::DestroyBuffers()
 {
   if (!mDeprecatedTextureClient) {
     return;
   }
@@ -214,58 +196,33 @@ ContentClientRemoteBuffer::BuildDeprecat
     }
     mTextureInfo.mTextureFlags |= TEXTURE_COMPONENT_ALPHA;
   }
 
   CreateFrontBufferAndNotify(aRect);
   mIsNewBuffer = true;
 }
 
-bool
-ContentClientBasic::SupportsAzureContent() const
-{
-  return gfxPlatform::GetPlatform()->SupportsAzureContent();
-}
- 
-bool
-ContentClientRemoteBuffer::SupportsAzureContent() const
-{
-  MOZ_ASSERT(mDeprecatedTextureClient);
-
-  return gfxPlatform::GetPlatform()->SupportsAzureContentForType(
-    mDeprecatedTextureClient->BackendType());
-}
-
 void
 ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
                                         const nsIntRect& aRect,
                                         uint32_t aFlags,
-                                        gfxASurface** aBlackSurface,
-                                        gfxASurface** aWhiteSurface,
                                         RefPtr<gfx::DrawTarget>* aBlackDT,
                                         RefPtr<gfx::DrawTarget>* aWhiteDT)
 {
   BuildDeprecatedTextureClients(aType, aRect, aFlags);
   if (!mDeprecatedTextureClient) {
     return;
   }
 
-  if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(
-        mDeprecatedTextureClient->BackendType())) {
-    *aBlackDT = mDeprecatedTextureClient->LockDrawTarget();
-    if (aFlags & BUFFER_COMPONENT_ALPHA) {
-      *aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget();
-    }
-  } else {
-    nsRefPtr<gfxASurface> ret = mDeprecatedTextureClient->LockSurface();
-    *aBlackSurface = ret.forget().get();
-    if (aFlags & BUFFER_COMPONENT_ALPHA) {
-     nsRefPtr<gfxASurface> retWhite = mDeprecatedTextureClientOnWhite->LockSurface();
-      *aWhiteSurface = retWhite.forget().get();
-    }
+  MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContentForType(
+        mDeprecatedTextureClient->BackendType()));
+  *aBlackDT = mDeprecatedTextureClient->LockDrawTarget();
+  if (aFlags & BUFFER_COMPONENT_ALPHA) {
+    *aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget();
   }
 }
 
 nsIntRegion
 ContentClientRemoteBuffer::GetUpdatedRegion(const nsIntRegion& aRegionToDraw,
                                             const nsIntRegion& aVisibleRegion,
                                             bool aDidSelfCopy)
 {
@@ -466,25 +423,16 @@ struct AutoDeprecatedTextureClient {
     : mTexture(nullptr)
   {}
   ~AutoDeprecatedTextureClient()
   {
     if (mTexture) {
       mTexture->Unlock();
     }
   }
-  gfxASurface* GetSurface(DeprecatedTextureClient* aTexture)
-  {
-    MOZ_ASSERT(!mTexture);
-    mTexture = aTexture;
-    if (mTexture) {
-      return mTexture->LockSurface();
-    }
-    return nullptr;
-  }
   DrawTarget* GetDrawTarget(DeprecatedTextureClient* aTexture)
   {
     MOZ_ASSERT(!mTexture);
     mTexture = aTexture;
     if (mTexture) {
       return mTexture->LockDrawTarget();
     }
     return nullptr;
@@ -531,35 +479,25 @@ ContentClientDoubleBuffered::SyncFrontBu
     updateRegion = mBufferRect;
   } else {
     mBufferRect = mFrontBufferRect;
     mBufferRotation = mFrontBufferRotation;
   }
  
   AutoDeprecatedTextureClient autoTextureFront;
   AutoDeprecatedTextureClient autoTextureFrontOnWhite;
-  if (SupportsAzureContent()) {
-    // We need to ensure that we lock these two buffers in the same
-    // order as the compositor to prevent deadlocks.
-    DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient);
-    DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite);
-    RotatedBuffer frontBuffer(dt,
-                              dtOnWhite,
-                              mFrontBufferRect,
-                              mFrontBufferRotation);
-    UpdateDestinationFrom(frontBuffer, updateRegion);
-  } else {
-    gfxASurface* surf = autoTextureFront.GetSurface(mFrontClient);
-    gfxASurface* surfOnWhite = autoTextureFrontOnWhite.GetSurface(mFrontClientOnWhite);
-    RotatedBuffer frontBuffer(surf,
-                              surfOnWhite,
-                              mFrontBufferRect,
-                              mFrontBufferRotation);
-    UpdateDestinationFrom(frontBuffer, updateRegion);
-  }
+  // We need to ensure that we lock these two buffers in the same
+  // order as the compositor to prevent deadlocks.
+  DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient);
+  DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite);
+  RotatedBuffer frontBuffer(dt,
+                            dtOnWhite,
+                            mFrontBufferRect,
+                            mFrontBufferRotation);
+  UpdateDestinationFrom(frontBuffer, updateRegion);
 
   mFrontAndBackBufferDiffer = false;
 }
 
 void
 ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
                                                    const nsIntRegion& aUpdateRegion)
 {
@@ -570,40 +508,30 @@ ContentClientDoubleBuffered::UpdateDesti
   }
   destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
 
   bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
   if (isClippingCheap) {
     gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
   }
 
-  if (SupportsAzureContent()) {
-    MOZ_ASSERT(!destCtx->IsCairo());
-    aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
-  } else {
-    aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK);
-  }
+  aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
 
   if (aSource.HaveBufferOnWhite()) {
     MOZ_ASSERT(HaveBufferOnWhite());
     nsRefPtr<gfxContext> destCtx =
       GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
     destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
 
     bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
     if (isClippingCheap) {
       gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
     }
 
-    if (SupportsAzureContent()) {
-      MOZ_ASSERT(!destCtx->IsCairo());
-      aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
-    } else {
-      aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE);
-    }
+    aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
   }
 }
 
 ContentClientSingleBuffered::~ContentClientSingleBuffered()
 {
   if (mDeprecatedTextureClient) {
     mDeprecatedTextureClient->SetDescriptor(SurfaceDescriptor());
   }
@@ -625,67 +553,40 @@ void
 ContentClientSingleBuffered::SyncFrontBufferToBackBuffer()
 {
   mIsNewBuffer = false;
   if (!mFrontAndBackBufferDiffer) {
     return;
   }
   mFrontAndBackBufferDiffer = false;
 
-  if (SupportsAzureContent()) {
-    DrawTarget* backBuffer = GetDTBuffer();
-    if (!backBuffer && mDeprecatedTextureClient) {
-      backBuffer = mDeprecatedTextureClient->LockDrawTarget();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client");
-      return;
-    }
-
-    RefPtr<DrawTarget> oldBuffer;
-    oldBuffer = SetDTBuffer(backBuffer,
-                            mBufferRect,
-                            mBufferRotation);
+  DrawTarget* backBuffer = GetDTBuffer();
+  if (!backBuffer && mDeprecatedTextureClient) {
+    backBuffer = mDeprecatedTextureClient->LockDrawTarget();
+  }
+  if (!backBuffer) {
+    NS_WARNING("Could not lock texture client");
+    return;
+  }
 
-    backBuffer = GetDTBufferOnWhite();
-    if (!backBuffer && mDeprecatedTextureClientOnWhite) {
-      backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client (on white)");
-      return;
-    }
-
-    oldBuffer = SetDTBufferOnWhite(backBuffer);
-  } else {
-    gfxASurface* backBuffer = GetBuffer();
-    if (!backBuffer && mDeprecatedTextureClient) {
-      backBuffer = mDeprecatedTextureClient->LockSurface();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client");
-      return;
-    }
-
-    nsRefPtr<gfxASurface> oldBuffer;
-    oldBuffer = SetBuffer(backBuffer,
+  RefPtr<DrawTarget> oldBuffer;
+  oldBuffer = SetDTBuffer(backBuffer,
                           mBufferRect,
                           mBufferRotation);
 
-    backBuffer = GetBufferOnWhite();
-    if (!backBuffer && mDeprecatedTextureClientOnWhite) {
-      backBuffer = mDeprecatedTextureClientOnWhite->LockSurface();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client (on white)");
-      return;
-    }
+  backBuffer = GetDTBufferOnWhite();
+  if (!backBuffer && mDeprecatedTextureClientOnWhite) {
+    backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget();
+  }
+  if (!backBuffer) {
+    NS_WARNING("Could not lock texture client (on white)");
+    return;
+  }
 
-    oldBuffer = SetBufferOnWhite(backBuffer);
-  }
+  oldBuffer = SetDTBufferOnWhite(backBuffer);
 }
 
 static void
 WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize)
 {
   if (*aRotationPoint < 0) {
     *aRotationPoint += aSize;
   } else if (*aRotationPoint >= aSize) {
@@ -699,43 +600,43 @@ FillSurface(gfxASurface* aSurface, const
 {
   nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
   ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
   gfxUtils::ClipToRegion(ctx, aRegion);
   ctx->SetColor(aColor);
   ctx->Paint();
 }
 
-ThebesLayerBuffer::PaintState
+RotatedContentBuffer::PaintState
 ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
-                                           ThebesLayerBuffer::ContentType aContentType,
+                                           RotatedContentBuffer::ContentType aContentType,
                                            uint32_t aFlags)
 {
   mTextureInfo.mDeprecatedTextureHostFlags = 0;
   PaintState result;
   // We need to disable rotation if we're going to be resampled when
   // drawing, because we might sample across the rotation boundary.
-  bool canHaveRotation =  !(aFlags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE);
+  bool canHaveRotation =  !(aFlags & RotatedContentBuffer::PAINT_WILL_RESAMPLE);
 
   nsIntRegion validRegion = aLayer->GetValidRegion();
 
   Layer::SurfaceMode mode;
   ContentType contentType;
   nsIntRegion neededRegion;
   bool canReuseBuffer;
   nsIntRect destBufferRect;
 
   while (true) {
     mode = aLayer->GetSurfaceMode();
     contentType = aContentType;
     neededRegion = aLayer->GetVisibleRegion();
     // If we're going to resample, we need a buffer that's in clamp mode.
     canReuseBuffer = neededRegion.GetBounds().Size() <= mBufferRect.Size() &&
       mHasBuffer &&
-      (!(aFlags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE) ||
+      (!(aFlags & RotatedContentBuffer::PAINT_WILL_RESAMPLE) ||
        !(mTextureInfo.mTextureFlags & TEXTURE_ALLOW_REPEAT));
 
     if (canReuseBuffer) {
       if (mBufferRect.Contains(neededRegion.GetBounds())) {
         // We don't need to adjust mBufferRect.
         destBufferRect = mBufferRect;
       } else {
         // The buffer's big enough but doesn't contain everything that's
@@ -751,17 +652,17 @@ ContentClientIncremental::BeginPaintBuff
           !aLayer->GetParent() ||
           !aLayer->GetParent()->SupportsComponentAlphaChildren()) {
         mode = Layer::SURFACE_SINGLE_CHANNEL_ALPHA;
       } else {
         contentType = GFX_CONTENT_COLOR;
       }
     }
 
-    if ((aFlags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE) &&
+    if ((aFlags & RotatedContentBuffer::PAINT_WILL_RESAMPLE) &&
         (!neededRegion.GetBounds().IsEqualInterior(destBufferRect) ||
          neededRegion.GetNumRects() > 1)) {
       // The area we add to neededRegion might not be painted opaquely
       if (mode == Layer::SURFACE_OPAQUE) {
         contentType = GFX_CONTENT_COLOR_ALPHA;
         mode = Layer::SURFACE_SINGLE_CHANNEL_ALPHA;
       }
       // For component alpha layers, we leave contentType as GFX_CONTENT_COLOR.
@@ -854,17 +755,17 @@ ContentClientIncremental::BeginPaintBuff
       // set destBuffer.
       mBufferRect = destBufferRect;
       mBufferRotation = nsIntPoint(0,0);
     }
   } else {
     // The buffer's not big enough, so allocate a new one
     createdBuffer = true;
   }
-  NS_ASSERTION(!(aFlags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE) ||
+  NS_ASSERTION(!(aFlags & RotatedContentBuffer::PAINT_WILL_RESAMPLE) ||
                destBufferRect == neededRegion.GetBounds(),
                "If we're resampling, we need to validate the entire buffer");
 
   if (!createdBuffer && !mHasBuffer) {
     return result;
   }
 
   if (createdBuffer) {
@@ -895,49 +796,29 @@ ContentClientIncremental::BeginPaintBuff
     nsIntRegion drawRegionCopy = result.mRegionToDraw;
     nsRefPtr<gfxASurface> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy);
     nsRefPtr<gfxASurface> onWhite = GetUpdateSurface(BUFFER_WHITE, result.mRegionToDraw);
     if (onBlack && onWhite) {
       NS_ASSERTION(result.mRegionToDraw == drawRegionCopy,
                    "BeginUpdate should always modify the draw region in the same way!");
       FillSurface(onBlack, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
       FillSurface(onWhite, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
-      if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
-        RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
-        RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
-        RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
-        result.mContext = new gfxContext(dt);
-      } else {
-        gfxASurface* surfaces[2] = { onBlack.get(), onWhite.get() };
-        nsRefPtr<gfxTeeSurface> surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
-
-        // XXX If the device offset is set on the individual surfaces instead of on
-        // the tee surface, we render in the wrong place. Why?
-        gfxPoint deviceOffset = onBlack->GetDeviceOffset();
-        onBlack->SetDeviceOffset(gfxPoint(0, 0));
-        onWhite->SetDeviceOffset(gfxPoint(0, 0));
-        surf->SetDeviceOffset(deviceOffset);
-
-        // Using this surface as a source will likely go horribly wrong, since
-        // only the onBlack surface will really be used, so alpha information will
-        // be incorrect.
-        surf->SetAllowUseAsSource(false);
-        result.mContext = new gfxContext(surf);
-      }
+      MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
+      RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
+      RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
+      RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
+      result.mContext = new gfxContext(dt);
     } else {
       result.mContext = nullptr;
     }
   } else {
     nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw);
-    if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
-      RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
-      result.mContext = new gfxContext(dt);
-    } else {
-      result.mContext = new gfxContext(surf);
-    }
+    MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
+    RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
+    result.mContext = new gfxContext(dt);
   }
   if (!result.mContext) {
     NS_WARNING("unable to get context for update");
     return result;
   }
   result.mContext->Translate(-gfxPoint(drawBounds.x, drawBounds.y));
 
   // If we do partial updates, we have to clip drawing to the regionToDraw.
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -2,17 +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_GFX_CONTENTCLIENT_H
 #define MOZILLA_GFX_CONTENTCLIENT_H
 
 #include <stdint.h>                     // for uint32_t
-#include "ThebesLayerBuffer.h"          // for ThebesLayerBuffer, etc
+#include "RotatedBuffer.h"              // for RotatedContentBuffer, etc
 #include "gfxTypes.h"
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "mozilla/Assertions.h"         // for MOZ_CRASH
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
 #include "mozilla/layers/CompositableForwarder.h"
@@ -39,32 +39,32 @@ class DrawTarget;
 namespace layers {
 
 class BasicLayerManager;
 class ThebesLayer;
 
 /**
  * A compositable client for Thebes layers. These are different to Image/Canvas
  * clients due to sending a valid region across IPC and because we do a lot more
- * optimisation work, encapsualted in ThebesLayerBuffers.
+ * optimisation work, encapsualted in RotatedContentBuffers.
  *
  * We use content clients for OMTC and non-OMTC, basic rendering so that
  * BasicThebesLayer has only one interface to deal with. We support single and
  * double buffered flavours. For tiled layers, we do not use a ContentClient
  * although we do have a ContentHost, and we do use texture clients and texture
  * hosts.
  *
  * The interface presented by ContentClient is used by the BasicThebesLayer
  * methods - PaintThebes, which is the same for MT and OMTC, and PaintBuffer
  * which is different (the OMTC one does a little more). The 'buffer' in the
  * names of a lot of these method is actually the TextureClient. But, 'buffer'
- * for the ThebesLayerBuffer (as in SetBuffer) means a gfxSurface. See the
- * comments for SetBuffer and SetBufferProvider in ThebesLayerBuffer. To keep
+ * for the RotatedContentBuffer (as in SetBuffer) means a gfxSurface. See the
+ * comments for SetBuffer and SetBufferProvider in RotatedContentBuffer. To keep
  * these mapped buffers alive, we store a pointer in mOldTextures if the
- * ThebesLayerBuffer's surface is not the one from our texture client, once we
+ * RotatedContentBuffer's surface is not the one from our texture client, once we
  * are done painting we unmap the surface/texture client and don't need to keep
  * it alive anymore, so we clear mOldTextures.
  *
  * The sequence for painting is: BeginPaint (lock our texture client into the
  * buffer), Paint the layer which calls SyncFrontBufferToBackBuffer (which gets
  * the surface back from the buffer and puts it back in again with the buffer
  * attributes), call BeginPaint on the buffer, call PaintBuffer on the layer
  * (which does the actual painting via the callback, then calls Updated on the
@@ -89,19 +89,19 @@ public:
   ContentClient(CompositableForwarder* aForwarder)
   : CompositableClient(aForwarder)
   {}
   virtual ~ContentClient()
   {}
 
 
   virtual void Clear() = 0;
-  virtual ThebesLayerBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
-                                                         ThebesLayerBuffer::ContentType aContentType,
-                                                         uint32_t aFlags) = 0;
+  virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
+                                                            RotatedContentBuffer::ContentType aContentType,
+                                                            uint32_t aFlags) = 0;
 
   // Sync front/back buffers content
   // After executing, the new back buffer has the same (interesting) pixels as
   // the new front buffer, and mValidRegion et al. are correct wrt the new
   // back buffer (i.e. as they were for the old back buffer)
   virtual void SyncFrontBufferToBackBuffer() {}
 
   // Called as part of the layers transation reply. Conveys data about our
@@ -124,129 +124,124 @@ public:
     : ContentClient(aForwarder)
   {}
 
   virtual void Updated(const nsIntRegion& aRegionToDraw,
                        const nsIntRegion& aVisibleRegion,
                        bool aDidSelfCopy) = 0;
 };
 
-// thin wrapper around BasicThebesLayerBuffer, for on-mtc
+// thin wrapper around RotatedContentBuffer, for on-mtc
 class ContentClientBasic : public ContentClient
-                         , protected ThebesLayerBuffer
+                         , protected RotatedContentBuffer
 {
 public:
   ContentClientBasic(CompositableForwarder* aForwarder,
                      BasicLayerManager* aManager);
 
-  typedef ThebesLayerBuffer::PaintState PaintState;
-  typedef ThebesLayerBuffer::ContentType ContentType;
+  typedef RotatedContentBuffer::PaintState PaintState;
+  typedef RotatedContentBuffer::ContentType ContentType;
 
-  virtual void Clear() { ThebesLayerBuffer::Clear(); }
+  virtual void Clear() { RotatedContentBuffer::Clear(); }
   PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
                               uint32_t aFlags)
   {
-    return ThebesLayerBuffer::BeginPaint(aLayer, aContentType, aFlags);
+    return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
   }
 
   void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
               gfxASurface* aMask, const gfxMatrix* aMaskTransform)
   {
-    ThebesLayerBuffer::DrawTo(aLayer, aTarget, aOpacity, aMask, aMaskTransform);
+    RotatedContentBuffer::DrawTo(aLayer, aTarget, aOpacity, aMask, aMaskTransform);
   }
 
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
-                            gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
-  virtual bool SupportsAzureContent() const;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     MOZ_CRASH("Should not be called on non-remote ContentClient");
   }
 
   virtual void OnActorDestroy() MOZ_OVERRIDE {}
 
 private:
   BasicLayerManager* mManager;
 };
 
 /**
- * A ContentClientRemote backed by a ThebesLayerBuffer.
+ * A ContentClientRemote backed by a RotatedContentBuffer.
  *
  * When using a ContentClientRemote, SurfaceDescriptors are created on
  * the rendering side and destroyed on the compositing side. They are only
  * passed from one side to the other when the TextureClient/Hosts are created.
  * *Ownership* of the SurfaceDescriptor moves from the rendering side to the
  * compositing side with the create message (send from CreateBuffer) which
  * tells the compositor that TextureClients have been created and that the
  * compositor should assign the corresponding TextureHosts to our corresponding
  * ContentHost.
  *
  * If the size or type of our buffer(s) change(s), then we simply destroy and
  * create them.
  */
 class ContentClientRemoteBuffer : public ContentClientRemote
-                                , protected ThebesLayerBuffer
+                                , protected RotatedContentBuffer
 {
-  using ThebesLayerBuffer::BufferRect;
-  using ThebesLayerBuffer::BufferRotation;
+  using RotatedContentBuffer::BufferRect;
+  using RotatedContentBuffer::BufferRotation;
 public:
   ContentClientRemoteBuffer(CompositableForwarder* aForwarder)
     : ContentClientRemote(aForwarder)
-    , ThebesLayerBuffer(ContainsVisibleBounds)
+    , RotatedContentBuffer(ContainsVisibleBounds)
     , mDeprecatedTextureClient(nullptr)
     , mIsNewBuffer(false)
     , mFrontAndBackBufferDiffer(false)
     , mContentType(GFX_CONTENT_COLOR_ALPHA)
   {}
 
-  typedef ThebesLayerBuffer::PaintState PaintState;
-  typedef ThebesLayerBuffer::ContentType ContentType;
+  typedef RotatedContentBuffer::PaintState PaintState;
+  typedef RotatedContentBuffer::ContentType ContentType;
 
-  virtual void Clear() { ThebesLayerBuffer::Clear(); }
+  virtual void Clear() { RotatedContentBuffer::Clear(); }
   PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
                               uint32_t aFlags)
   {
-    return ThebesLayerBuffer::BeginPaint(aLayer, aContentType, aFlags);
+    return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
   }
 
   /**
    * Begin/End Paint map a gfxASurface from the texture client
-   * into the buffer of ThebesLayerBuffer. The surface is only
+   * into the buffer of RotatedContentBuffer. The surface is only
    * valid when the texture client is locked, so is mapped out
-   * of ThebesLayerBuffer when we are done painting.
+   * of RotatedContentBuffer when we are done painting.
    * None of the underlying buffer attributes (rect, rotation)
    * are affected by mapping/unmapping.
    */
   virtual void BeginPaint() MOZ_OVERRIDE;
   virtual void EndPaint() MOZ_OVERRIDE;
 
   virtual void Updated(const nsIntRegion& aRegionToDraw,
                        const nsIntRegion& aVisibleRegion,
                        bool aDidSelfCopy);
 
   virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) MOZ_OVERRIDE;
 
   // Expose these protected methods from the superclass.
   virtual const nsIntRect& BufferRect() const
   {
-    return ThebesLayerBuffer::BufferRect();
+    return RotatedContentBuffer::BufferRect();
   }
   virtual const nsIntPoint& BufferRotation() const
   {
-    return ThebesLayerBuffer::BufferRotation();
+    return RotatedContentBuffer::BufferRotation();
   }
 
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
-                            gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
 
-  virtual bool SupportsAzureContent() const MOZ_OVERRIDE;
-
   void DestroyBuffers();
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
   virtual void OnActorDestroy() MOZ_OVERRIDE;
@@ -364,33 +359,33 @@ public:
     : ContentClientRemote(aFwd)
     , mContentType(GFX_CONTENT_COLOR_ALPHA)
     , mHasBuffer(false)
     , mHasBufferOnWhite(false)
   {
     mTextureInfo.mCompositableType = BUFFER_CONTENT_INC;
   }
 
-  typedef ThebesLayerBuffer::PaintState PaintState;
-  typedef ThebesLayerBuffer::ContentType ContentType;
+  typedef RotatedContentBuffer::PaintState PaintState;
+  typedef RotatedContentBuffer::ContentType ContentType;
 
   virtual TextureInfo GetTextureInfo() const
   {
     return mTextureInfo;
   }
 
   virtual void Clear()
   {
     mBufferRect.SetEmpty();
     mHasBuffer = false;
     mHasBufferOnWhite = false;
   }
-  virtual ThebesLayerBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
-                                                         ThebesLayerBuffer::ContentType aContentType,
-                                                         uint32_t aFlags);
+  virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
+                                                            RotatedContentBuffer::ContentType aContentType,
+                                                            uint32_t aFlags);
 
   virtual void Updated(const nsIntRegion& aRegionToDraw,
                        const nsIntRegion& aVisibleRegion,
                        bool aDidSelfCopy);
 
   virtual void EndPaint()
   {
     if (IsSurfaceDescriptorValid(mUpdateDescriptor)) {
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -5,17 +5,17 @@
 
 #ifndef GFX_CONTENTHOST_H
 #define GFX_CONTENTHOST_H
 
 #include <stdint.h>                     // for uint32_t
 #include <stdio.h>                      // for FILE
 #include "mozilla-config.h"             // for MOZ_DUMP_PAINTING
 #include "CompositableHost.h"           // for CompositableHost, etc
-#include "ThebesLayerBuffer.h"          // for ThebesLayerBuffer, etc
+#include "RotatedBuffer.h"              // for RotatedContentBuffer, etc
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
 #include "mozilla/gfx/Point.h"          // for Point
 #include "mozilla/gfx/Rect.h"           // for Rect
 #include "mozilla/gfx/Types.h"          // for Filter
 #include "mozilla/layers/CompositorTypes.h"  // for TextureInfo, etc
 #include "mozilla/layers/ISurfaceAllocator.h"  // for ISurfaceAllocator
@@ -82,18 +82,18 @@ protected:
  * texture hosts (for single and double buffering) to the ContentHost.
  *
  * It is the responsibility of the ContentHost to destroy its resources when
  * they are recreated or the ContentHost dies.
  */
 class ContentHostBase : public ContentHost
 {
 public:
-  typedef ThebesLayerBuffer::ContentType ContentType;
-  typedef ThebesLayerBuffer::PaintState PaintState;
+  typedef RotatedContentBuffer::ContentType ContentType;
+  typedef RotatedContentBuffer::PaintState PaintState;
 
   ContentHostBase(const TextureInfo& aTextureInfo);
   ~ContentHostBase();
 
   virtual void Composite(EffectChain& aEffectChain,
                          float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Filter& aFilter,
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -27,20 +27,18 @@ EXPORTS += [
     'ipc/CompositorChild.h',
     'ipc/CompositorParent.h',
     'ipc/ShadowLayersManager.h',
     'Layers.h',
     'LayersLogging.h',
     'LayerSorter.h',
     'LayerTreeInvalidation.h',
     'opengl/Composer2D.h',
-    'opengl/ImageLayerOGL.h',
-    'opengl/LayerManagerOGL.h',
-    'opengl/LayerManagerOGLProgram.h',
-    'opengl/LayerManagerOGLShaders.h',
+    'opengl/OGLShaderProgram.h',
+    'opengl/OGLShaders.h',
     'opengl/TexturePoolOGL.h',
     'ReadbackLayer.h',
     'SharedTextureImage.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     UNIFIED_SOURCES += [
         'D3D9SurfaceImage.cpp',
@@ -250,31 +248,25 @@ UNIFIED_SOURCES += [
     'ipc/ShadowLayers.cpp',
     'ipc/SharedPlanarYCbCrImage.cpp',
     'ipc/SharedRGBImage.cpp',
     'ipc/TaskThrottler.cpp',
     'Layers.cpp',
     'LayersLogging.cpp',
     'LayerSorter.cpp',
     'LayerTreeInvalidation.cpp',
-    'opengl/CanvasLayerOGL.cpp',
-    'opengl/ColorLayerOGL.cpp',
     'opengl/CompositingRenderTargetOGL.cpp',
     'opengl/CompositorOGL.cpp',
-    'opengl/ContainerLayerOGL.cpp',
-    'opengl/ImageLayerOGL.cpp',
-    'opengl/LayerManagerOGL.cpp',
-    'opengl/LayerManagerOGLProgram.cpp',
+    'opengl/OGLShaderProgram.cpp',
     'opengl/TextureClientOGL.cpp',
     'opengl/TextureHostOGL.cpp',
     'opengl/TexturePoolOGL.cpp',
-    'opengl/ThebesLayerOGL.cpp',
     'ReadbackProcessor.cpp',
     'RenderTrace.cpp',
-    'ThebesLayerBuffer.cpp',
+    'RotatedBuffer.cpp',
     'YCbCrImageDataSerializer.cpp',
 ]
 
 SOURCES += [
     'basic/BasicImageLayer.cpp',
     'ImageContainer.cpp',
 ]
 
deleted file mode 100644
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/* -*- 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 "CanvasLayerOGL.h"
-#include "GLContext.h"                  // for GLContext
-#include "GLScreenBuffer.h"             // for GLScreenBuffer
-#include "SharedSurface.h"              // for SharedSurface
-#include "SharedSurfaceGL.h"            // for SharedSurface_Basic, etc
-#include "SurfaceStream.h"              // for SurfaceStream, etc
-#include "SurfaceTypes.h"               // for SharedSurfaceType, etc
-#include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxImageSurface.h"            // for gfxImageSurface
-#include "gfxPlatform.h"                // for gfxPlatform
-#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
-#include "mozilla/gfx/Types.h"          // for SurfaceFormat, etc
-#include "nsDebug.h"                    // for NS_ABORT_IF_FALSE, etc
-#include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
-#include "nsRegion.h"                   // for nsIntRegion
-#include "nsSize.h"                     // for nsIntSize
-#include "LayerManagerOGL.h"            // for LayerOGL::GLContext, etc
-
-#ifdef XP_MACOSX
-#include "mozilla/gfx/MacIOSurface.h"
-#include "SharedSurfaceIO.h"
-#endif
-
-#ifdef XP_WIN
-#include "gfxWindowsSurface.h"
-#include "WGLLibrary.h"
-#endif
-
-#ifdef XP_MACOSX
-#include <OpenGL/OpenGL.h>
-#endif
-
-#ifdef GL_PROVIDER_GLX
-#include "GLXLibrary.h"                 // for GLXLibrary, sDefGLXLib
-#include "gfxXlibSurface.h"
-#endif
-
-using namespace mozilla;
-using namespace mozilla::layers;
-using namespace mozilla::gl;
-using namespace mozilla::gfx;
-
-CanvasLayerOGL::CanvasLayerOGL(LayerManagerOGL *aManager)
-  : CanvasLayer(aManager, nullptr)
-  , LayerOGL(aManager)
-  , mLayerProgram(RGBALayerProgramType)
-  , mTexture(0)
-  , mTextureTarget(LOCAL_GL_TEXTURE_2D)
-  , mDelayedUpdates(false)
-  , mIsGLAlphaPremult(false)
-  , mUploadTexture(0)
-#if defined(GL_PROVIDER_GLX)
-  , mPixmap(0)
-#endif
-{
-  mImplData = static_cast<LayerOGL*>(this);
-  mForceReadback = Preferences::GetBool("webgl.force-layers-readback", false);
-}
-
-CanvasLayerOGL::~CanvasLayerOGL() {
-  Destroy();
-}
-
-static void
-MakeTextureIfNeeded(GLContext* gl, GLuint& aTexture)
-{
-  if (aTexture != 0)
-    return;
-
-  gl->fGenTextures(1, &aTexture);
-
-  gl->fActiveTexture(LOCAL_GL_TEXTURE0);
-  gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
-
-  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
-  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-}
-
-#ifdef XP_MACOSX
-static GLuint
-MakeIOSurfaceTexture(void* aCGIOSurfaceContext, mozilla::gl::GLContext* aGL)
-{
-  GLuint ioSurfaceTexture;
-
-  aGL->MakeCurrent();
-
-  aGL->fGenTextures(1, &ioSurfaceTexture);
-
-  aGL->fActiveTexture(LOCAL_GL_TEXTURE0);
-  aGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, ioSurfaceTexture);
-
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-
-  RefPtr<MacIOSurface> ioSurface = MacIOSurface::IOSurfaceContextGetSurface((CGContextRef)aCGIOSurfaceContext);
-
-  ioSurface->CGLTexImageIOSurface2D(static_cast<CGLContextObj>(aGL->GetNativeData(GLContext::NativeCGLContext)));
-
-  aGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
-
-  return ioSurfaceTexture;
-}
-#endif
-
-void
-CanvasLayerOGL::Destroy()
-{
-  if (!mDestroyed) {
-    CleanupResources();
-    mDestroyed = true;
-  }
-}
-
-void
-CanvasLayerOGL::Initialize(const Data& aData)
-{
-  NS_ASSERTION(mCanvasSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
-
-  if (aData.mGLContext != nullptr &&
-      aData.mSurface != nullptr)
-  {
-    NS_WARNING("CanvasLayerOGL can't have both surface and WebGLContext");
-    return;
-  }
-
-  mOGLManager->MakeCurrent();
-
-  if (aData.mDrawTarget &&
-      aData.mDrawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED)) {
-    mDrawTarget = aData.mDrawTarget;
-    mNeedsYFlip = false;
-    mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
-    return;
-  } else if (aData.mDrawTarget) {
-    mDrawTarget = aData.mDrawTarget;
-    mCanvasSurface = gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
-    mNeedsYFlip = false;
-  } else if (aData.mSurface) {
-    mCanvasSurface = aData.mSurface;
-    mNeedsYFlip = false;
-#if defined(GL_PROVIDER_GLX)
-    if (aData.mSurface->GetType() == gfxSurfaceTypeXlib) {
-        gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(aData.mSurface);
-        mPixmap = xsurf->GetGLXPixmap();
-        if (mPixmap) {
-            mLayerProgram = ShaderProgramFromContentType(aData.mSurface->GetContentType());
-            MakeTextureIfNeeded(gl(), mUploadTexture);
-        }
-    }
-#endif
-  } else if (aData.mGLContext) {
-    mGLContext = aData.mGLContext;
-    NS_ASSERTION(mGLContext->IsOffscreen(), "Canvas GLContext must be offscreen.");
-    mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
-    mNeedsYFlip = true;
-
-    // [OGL Layers, MTC] WebGL layer init.
-
-    GLScreenBuffer* screen = mGLContext->Screen();
-    SurfaceStreamType streamType =
-        SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
-                                          screen->PreserveBuffer());
-    SurfaceFactory_GL* factory = nullptr;
-    if (!mForceReadback) {
-      factory = new SurfaceFactory_GLTexture(mGLContext, gl(), screen->Caps());
-    }
-
-    if (factory) {
-      screen->Morph(factory, streamType);
-    }
-  } else {
-    NS_WARNING("CanvasLayerOGL::Initialize called without surface or GL context!");
-    return;
-  }
-
-  mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
-      
-  // Check the maximum texture size supported by GL. glTexImage2D supports
-  // images of up to 2 + GL_MAX_TEXTURE_SIZE
-  GLint texSize = 0;
-  gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &texSize);
-  MOZ_ASSERT(texSize != 0);
-  if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
-    mDelayedUpdates = true;
-    MakeTextureIfNeeded(gl(), mUploadTexture);
-    // This should only ever occur with 2d canvas, WebGL can't already have a texture
-    // of this size can it?
-    NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, 
-                      "Invalid texture size when WebGL surface already exists at that size?");
-  }
-}
-
-/**
- * Following UpdateSurface(), mTexture on context this->gl() should contain the data we want,
- * unless mDelayedUpdates is true because of a too-large surface.
- */
-void
-CanvasLayerOGL::UpdateSurface()
-{
-  if (!IsDirty())
-    return;
-  Painted();
-
-  if (mDestroyed || mDelayedUpdates) {
-    return;
-  }
-
-#if defined(GL_PROVIDER_GLX)
-  if (mPixmap) {
-    return;
-  }
-#endif
-
-  gfxASurface* updatedSurface = nullptr;
-  gfxImageSurface* temporarySurface = nullptr;
-  bool nothingToShow = false;
-  if (mGLContext) {
-    SharedSurface* surf = mGLContext->RequestFrame();
-    if (surf) {
-      mLayerProgram = surf->HasAlpha() ? RGBALayerProgramType
-                                       : RGBXLayerProgramType;
-      switch (surf->Type()) {
-        case SharedSurfaceType::Basic: {
-          SharedSurface_Basic* readbackSurf = SharedSurface_Basic::Cast(surf);
-          updatedSurface = readbackSurf->GetData();
-          break;
-        }
-        case SharedSurfaceType::GLTextureShare: {
-          SharedSurface_GLTexture* textureSurf = SharedSurface_GLTexture::Cast(surf);
-          mTexture = textureSurf->Texture();
-          break;
-        }
-#ifdef XP_MACOSX
-        case SharedSurfaceType::IOSurface: {
-          SharedSurface_IOSurface *ioSurf = SharedSurface_IOSurface::Cast(surf);
-          mTexture = ioSurf->Texture();
-          mTextureTarget = ioSurf->TextureTarget();
-          mLayerProgram = ioSurf->HasAlpha() ? RGBARectLayerProgramType : RGBXRectLayerProgramType;
-          break;
-        }
-#endif
-        default:
-          MOZ_CRASH("Unacceptable SharedSurface type.");
-      }
-    } else {
-      nothingToShow = true;
-    }
-  } else if (mCanvasSurface) {
-#ifdef XP_MACOSX
-    if (mDrawTarget && mDrawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED)) {
-      if (!mTexture) {
-        mTexture = MakeIOSurfaceTexture((CGContextRef)mDrawTarget->GetNativeSurface(
-                                        gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED),
-                                        gl());
-        mTextureTarget = LOCAL_GL_TEXTURE_RECTANGLE_ARB;
-        mLayerProgram = RGBARectLayerProgramType;
-      }
-      mDrawTarget->Flush();
-      return;
-    }
-#endif
-    updatedSurface = mCanvasSurface;
-  } else {
-    MOZ_CRASH("Unhandled canvas layer type.");
-  }
-
-  if (updatedSurface) {
-    mOGLManager->MakeCurrent();
-    gfx::SurfaceFormat format =
-      gl()->UploadSurfaceToTexture(updatedSurface,
-                                   mBounds,
-                                   mUploadTexture,
-                                   true,//false,
-                                   nsIntPoint(0, 0));
-    mLayerProgram = ShaderProgramFromSurfaceFormat(format);
-    mTexture = mUploadTexture;
-
-    if (temporarySurface)
-      delete temporarySurface;
-  }
-
-  MOZ_ASSERT(mTexture || nothingToShow);
-}
-
-void
-CanvasLayerOGL::RenderLayer(int aPreviousDestination,
-                            const nsIntPoint& aOffset)
-{
-  FirePreTransactionCallback();
-  UpdateSurface();
-  if (mOGLManager->CompositingDisabled()) {
-    return;
-  }
-  FireDidTransactionCallback();
-
-  mOGLManager->MakeCurrent();
-
-  // XXX We're going to need a different program depending on if
-  // mGLBufferIsPremultiplied is TRUE or not.  The RGBLayerProgram
-  // assumes that it's true.
-
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-
-  if (mTexture) {
-    gl()->fBindTexture(mTextureTarget, mTexture);
-  }
-
-  ShaderProgramOGL *program = nullptr;
-
-  nsIntRect drawRect = mBounds;
-  if (mDelayedUpdates) {
-    NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
-    
-    drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
-
-    gfx::SurfaceFormat format =
-      gl()->UploadSurfaceToTexture(mCanvasSurface,
-                                   nsIntRect(0, 0, drawRect.width, drawRect.height),
-                                   mUploadTexture,
-                                   true,
-                                   drawRect.TopLeft());
-    mLayerProgram = ShaderProgramFromSurfaceFormat(format);
-    mTexture = mUploadTexture;
-  }
-
-  if (!program) {
-    program = mOGLManager->GetProgram(mLayerProgram, GetMaskLayer());
-  }
-
-#if defined(GL_PROVIDER_GLX)
-  if (mPixmap && !mDelayedUpdates) {
-    sDefGLXLib.BindTexImage(mPixmap);
-  }
-#endif
-
-  gl()->ApplyFilterToBoundTexture(mFilter);
-
-  program->Activate();
-  if (mLayerProgram == RGBARectLayerProgramType ||
-      mLayerProgram == RGBXRectLayerProgramType) {
-    // This is used by IOSurface that use 0,0...w,h coordinate rather then 0,0..1,1.
-    program->SetTexCoordMultiplier(mBounds.width, mBounds.height);
-  }
-  program->SetLayerQuadRect(drawRect);
-  program->SetLayerTransform(GetEffectiveTransform());
-  program->SetTextureTransform(gfx3DMatrix());
-  program->SetLayerOpacity(GetEffectiveOpacity());
-  program->SetRenderOffset(aOffset);
-  program->SetTextureUnit(0);
-  program->LoadMask(GetMaskLayer());
-
-  if (gl()->CanUploadNonPowerOfTwo()) {
-    mOGLManager->BindAndDrawQuad(program, mNeedsYFlip ? true : false);
-  } else {
-    mOGLManager->BindAndDrawQuadWithTextureRect(program, drawRect, drawRect.Size());
-  }
-
-#if defined(GL_PROVIDER_GLX)
-  if (mPixmap && !mDelayedUpdates) {
-    sDefGLXLib.ReleaseTexImage(mPixmap);
-  }
-#endif
-}
-
-void
-CanvasLayerOGL::CleanupResources()
-{
-  if (mUploadTexture) {
-    gl()->MakeCurrent();
-    gl()->fDeleteTextures(1, &mUploadTexture);
-    mUploadTexture = 0;
-  }
-}
-
-gfxImageSurface*
-CanvasLayerOGL::GetTempSurface(const gfxIntSize& aSize,
-                               const gfxImageFormat aFormat)
-{
-  if (!mCachedTempSurface ||
-      aSize.width != mCachedSize.width ||
-      aSize.height != mCachedSize.height ||
-      aFormat != mCachedFormat)
-  {
-    mCachedTempSurface = new gfxImageSurface(aSize, aFormat);
-    mCachedSize = aSize;
-    mCachedFormat = aFormat;
-  }
-
-  return mCachedTempSurface;
-}
deleted file mode 100644
--- a/gfx/layers/opengl/CanvasLayerOGL.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- 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 GFX_CANVASLAYEROGL_H
-#define GFX_CANVASLAYEROGL_H
-
-#include "GLContextTypes.h"             // for GLContext
-#include "GLDefs.h"                     // for GLuint, LOCAL_GL_TEXTURE_2D
-#include "LayerManagerOGL.h"            // for LayerOGL::GLContext, etc
-#include "Layers.h"                     // for CanvasLayer, etc
-#include "gfxTypes.h"
-#include "gfxPoint.h"                   // for gfxIntSize
-#include "mozilla/Preferences.h"        // for Preferences
-#include "mozilla/RefPtr.h"             // for RefPtr
-#include "mozilla/gfx/2D.h"             // for DrawTarget
-#include "mozilla/mozalloc.h"           // for operator delete, etc
-#include "nsAutoPtr.h"                  // for nsRefPtr
-#include "opengl/LayerManagerOGLProgram.h"  // for ShaderProgramType, etc
-#if defined(GL_PROVIDER_GLX)
-#include "GLXLibrary.h"
-#include "mozilla/X11Util.h"
-#endif
-
-struct nsIntPoint;
-class gfxASurface;
-class gfxImageSurface;
-
-namespace mozilla {
-namespace layers {
-
-class CanvasLayerOGL :
-  public CanvasLayer,
-  public LayerOGL
-{
-public:
-  CanvasLayerOGL(LayerManagerOGL *aManager);
-  ~CanvasLayerOGL();
-
-  // CanvasLayer implementation
-  virtual void Initialize(const Data& aData);
-
-  // LayerOGL implementation
-  virtual void Destroy();
-  virtual Layer* GetLayer() { return this; }
-  virtual void RenderLayer(int aPreviousFrameBuffer,
-                           const nsIntPoint& aOffset);
-  virtual void CleanupResources();
-
-protected:
-  void UpdateSurface();
-
-  nsRefPtr<gfxASurface> mCanvasSurface;
-  nsRefPtr<GLContext> mGLContext;
-  ShaderProgramType mLayerProgram;
-  RefPtr<gfx::DrawTarget> mDrawTarget;
-
-  GLuint mTexture;
-  GLenum mTextureTarget;
-
-  bool mDelayedUpdates;
-  bool mIsGLAlphaPremult;
-  bool mNeedsYFlip;
-  bool mForceReadback;
-  GLuint mUploadTexture;
-#if defined(GL_PROVIDER_GLX)
-  GLXPixmap mPixmap;
-#endif
-
-  nsRefPtr<gfxImageSurface> mCachedTempSurface;
-  gfxIntSize mCachedSize;
-  gfxImageFormat mCachedFormat;
-
-  gfxImageSurface* GetTempSurface(const gfxIntSize& aSize,
-                                  const gfxImageFormat aFormat);
-
-  void DiscardTempSurface() {
-    mCachedTempSurface = nullptr;
-  }
-};
-
-} /* layers */
-} /* mozilla */
-#endif /* GFX_IMAGELAYEROGL_H */
deleted file mode 100644
--- a/gfx/layers/opengl/ColorLayerOGL.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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 "ColorLayerOGL.h"
-#include "gfxColor.h"                   // for gfxRGBA
-#include "LayerManagerOGL.h"            // for LayerManagerOGL
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL, etc
-
-struct nsIntPoint;
-
-namespace mozilla {
-namespace layers {
-
-static void
-RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager,
-                 const nsIntPoint& aOffset)
-{
-  if (aManager->CompositingDisabled()) {
-    return;
-  }
-
-  aManager->MakeCurrent();
-
-  // XXX we might be able to improve performance by using glClear
-
-  /* Multiply color by the layer opacity, as the shader
-   * ignores layer opacity and expects a final color to
-   * write to the color buffer.  This saves a needless
-   * multiply in the fragment shader.
-   */
-  gfxRGBA color(aLayer->GetColor());
-  float opacity = aLayer->GetEffectiveOpacity() * color.a;
-  color.r *= opacity;
-  color.g *= opacity;
-  color.b *= opacity;
-  color.a = opacity;
-
-  ShaderProgramOGL *program = aManager->GetProgram(ColorLayerProgramType,
-                                                   aLayer->GetMaskLayer());
-  program->Activate();
-  program->SetLayerQuadRect(aLayer->GetBounds());
-  program->SetLayerTransform(aLayer->GetEffectiveTransform());
-  program->SetRenderOffset(aOffset);
-  program->SetRenderColor(color);
-  program->LoadMask(aLayer->GetMaskLayer());
-
-  aManager->BindAndDrawQuad(program);
-}
-
-void
-ColorLayerOGL::RenderLayer(int,
-                           const nsIntPoint& aOffset)
-{
-  RenderColorLayer(this, mOGLManager, aOffset);
-}
-
-} /* layers */
-} /* mozilla */
deleted file mode 100644
--- a/gfx/layers/opengl/ColorLayerOGL.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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 GFX_COLORLAYEROGL_H
-#define GFX_COLORLAYEROGL_H
-
-#include "LayerManagerOGL.h"            // for LayerOGL, LayerManagerOGL
-#include "Layers.h"                     // for ColorLayer, etc
-
-struct nsIntPoint;
-
-namespace mozilla {
-namespace layers {
-
-class ColorLayerOGL : public ColorLayer,
-                      public LayerOGL
-{
-public:
-  ColorLayerOGL(LayerManagerOGL *aManager)
-    : ColorLayer(aManager, nullptr)
-    , LayerOGL(aManager)
-  { 
-    mImplData = static_cast<LayerOGL*>(this);
-  }
-  ~ColorLayerOGL() { Destroy(); }
-
-  // LayerOGL Implementation
-  virtual Layer* GetLayer() { return this; }
-
-  virtual void Destroy() { mDestroyed = true; }
-
-  virtual void RenderLayer(int aPreviousFrameBuffer,
-                           const nsIntPoint& aOffset);
-  virtual void CleanupResources() {};
-};
-
-} /* layers */
-} /* mozilla */
-#endif /* GFX_COLORLAYEROGL_H */
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -5,17 +5,16 @@
 
 #include "CompositorOGL.h"
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint32_t, uint8_t
 #include <stdlib.h>                     // for free, malloc
 #include "FPSCounter.h"                 // for FPSState, FPSCounter
 #include "GLContextProvider.h"          // for GLContextProvider
 #include "GLContext.h"                  // for GLContext
-#include "LayerManagerOGL.h"            // for BUFFER_OFFSET
 #include "Layers.h"                     // for WriteSnapshotToDumpFile
 #include "gfx2DGlue.h"                  // for ThebesFilter
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
 #include "gfxASurface.h"                // for gfxASurface, etc
 #include "gfxCrashReporterUtils.h"      // for ScopedGfxFeatureReporter
 #include "gfxImageSurface.h"            // for gfxImageSurface
 #include "gfxMatrix.h"                  // for gfxMatrix
 #include "GraphicsFilter.h"             // for GraphicsFilter
@@ -44,16 +43,18 @@
 #include "TexturePoolOGL.h"
 #endif
 #include "GeckoProfiler.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "GfxInfo.h"
 #endif
 
+#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
+ 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 using namespace mozilla::gl;
 
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_COMPOSITOROGL_H
 #define MOZILLA_GFX_COMPOSITOROGL_H
 
 #include "GLContextTypes.h"             // for GLContext, etc
 #include "GLDefs.h"                     // for GLuint, LOCAL_GL_TEXTURE_2D, etc
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL, etc
+#include "OGLShaderProgram.h"           // for ShaderProgramOGL, etc
 #include "Units.h"                      // for ScreenPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE, MOZ_FINAL
 #include "mozilla/RefPtr.h"             // for TemporaryRef, RefPtr
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
deleted file mode 100644
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/* -*- 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 "ContainerLayerOGL.h"
-#include <stdint.h>                     // for uint32_t
-#include <algorithm>                    // for min
-#include "GLContext.h"
-#include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxMatrix.h"                  // for gfxMatrix
-#include "gfxPlatform.h"                // for gfxPlatform
-#include "gfxUtils.h"                   // for gfxUtils, etc
-#include "mozilla/gfx/BaseRect.h"       // for BaseRect
-#include "mozilla/layers/CompositorTypes.h"  // for MaskType, etc
-#include "nsAutoPtr.h"                  // for nsRefPtr
-#include "nsDebug.h"                    // for NS_ASSERTION
-#include "nsISupportsUtils.h"           // for NS_ADDREF, NS_RELEASE
-#include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
-#include "nsRegion.h"                   // for nsIntRegion
-#include "nsTArray.h"                   // for nsAutoTArray
-#include "LayerManagerOGL.h"            // for LayerManagerOGL, LayerOGL, etc
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL
-class gfxImageSurface;
-
-namespace mozilla {
-namespace layers {
-
-static inline LayerOGL*
-GetNextSibling(LayerOGL* aLayer)
-{
-   Layer* layer = aLayer->GetLayer()->GetNextSibling();
-   return layer ? static_cast<LayerOGL*>(layer->
-                                         ImplData())
-                 : nullptr;
-}
-
-ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *mOGLManager)
-  : ContainerLayer(mOGLManager, nullptr)
-  , LayerOGL(mOGLManager)
-{
-  mImplData = static_cast<LayerOGL*>(this);
-}
-
-ContainerLayerOGL::~ContainerLayerOGL()
-{
-  Destroy();
-}
-
-void
-ContainerLayerOGL::Destroy()
-{
-  if (!mDestroyed) {
-    while (mFirstChild) {
-      GetFirstChildOGL()->Destroy();
-      RemoveChild(mFirstChild);
-    }
-    mDestroyed = true;
-  }
-}
-
-LayerOGL*
-ContainerLayerOGL::GetFirstChildOGL()
-{
-  if (!mFirstChild) {
-    return nullptr;
-  }
-  return static_cast<LayerOGL*>(mFirstChild->ImplData());
-}
-
-void
-ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
-                               const nsIntPoint& aOffset)
-{
-  /**
-   * Setup our temporary texture for rendering the contents of this container.
-   */
-  GLuint containerSurface;
-  GLuint frameBuffer;
-
-  nsIntPoint childOffset(aOffset);
-  nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds();
-
-  nsIntRect cachedScissor = gl()->ScissorRect();
-  gl()->PushScissorRect();
-  mSupportsComponentAlphaChildren = false;
-
-  float opacity = GetEffectiveOpacity();
-  const gfx3DMatrix& transform = GetEffectiveTransform();
-  bool needsFramebuffer = UseIntermediateSurface();
-  if (needsFramebuffer) {
-    nsIntRect framebufferRect = visibleRect;
-    // we're about to create a framebuffer backed by textures to use as an intermediate
-    // surface. What to do if its size (as given by framebufferRect) would exceed the
-    // maximum texture size supported by the GL? The present code chooses the compromise
-    // of just clamping the framebuffer's size to the max supported size.
-    // This gives us a lower resolution rendering of the intermediate surface (children layers).
-    // See bug 827170 for a discussion.
-    GLint maxTexSize;
-    gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize);
-    framebufferRect.width = std::min(framebufferRect.width, maxTexSize);
-    framebufferRect.height = std::min(framebufferRect.height, maxTexSize);
-
-    LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear;
-    if (GetEffectiveVisibleRegion().GetNumRects() == 1 && 
-        (GetContentFlags() & Layer::CONTENT_OPAQUE))
-    {
-      // don't need a background, we're going to paint all opaque stuff
-      mSupportsComponentAlphaChildren = true;
-      mode = LayerManagerOGL::InitModeNone;
-    } else {
-      const gfx3DMatrix& transform3D = GetEffectiveTransform();
-      gfxMatrix transform;
-      // If we have an opaque ancestor layer, then we can be sure that
-      // all the pixels we draw into are either opaque already or will be
-      // covered by something opaque. Otherwise copying up the background is
-      // not safe.
-      if (HasOpaqueAncestorLayer(this) &&
-          transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) {
-        mode = gfxPlatform::ComponentAlphaEnabled() ?
-          LayerManagerOGL::InitModeCopy :
-          LayerManagerOGL::InitModeClear;
-        framebufferRect.x += transform.x0;
-        framebufferRect.y += transform.y0;
-        mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled();
-      }
-    }
-
-    gl()->PushViewportRect();
-    framebufferRect -= childOffset;
-    if (!mOGLManager->CompositingDisabled()) {
-      if (!mOGLManager->CreateFBOWithTexture(framebufferRect,
-                                          mode,
-                                          aPreviousFrameBuffer,
-                                          &frameBuffer,
-                                          &containerSurface)) {
-        gl()->PopViewportRect();
-        gl()->PopScissorRect();
-        gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
-        return;
-      }
-    }
-    childOffset.x = visibleRect.x;
-    childOffset.y = visibleRect.y;
-  } else {
-    frameBuffer = aPreviousFrameBuffer;
-    mSupportsComponentAlphaChildren = (GetContentFlags() & Layer::CONTENT_OPAQUE) ||
-      (GetParent() && GetParent()->SupportsComponentAlphaChildren());
-  }
-
-  nsAutoTArray<Layer*, 12> children;
-  SortChildrenBy3DZOrder(children);
-
-  /**
-   * Render this container's contents.
-   */
-  for (uint32_t i = 0; i < children.Length(); i++) {
-    LayerOGL* layerToRender = static_cast<LayerOGL*>(children.ElementAt(i)->ImplData());
-
-    if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
-      continue;
-    }
-
-    nsIntRect scissorRect = layerToRender->GetLayer()->
-        CalculateScissorRect(cachedScissor, &mOGLManager->GetWorldTransform());
-    if (scissorRect.IsEmpty()) {
-      continue;
-    }
-
-    gl()->fScissor(scissorRect.x, 
-                               scissorRect.y, 
-                               scissorRect.width, 
-                               scissorRect.height);
-
-    layerToRender->RenderLayer(frameBuffer, childOffset);
-    gl()->MakeCurrent();
-  }
-
-
-  if (needsFramebuffer) {
-    // Unbind the current framebuffer and rebind the previous one.
-#ifdef MOZ_DUMP_PAINTING
-    if (gfxUtils::sDumpPainting) {
-      nsRefPtr<gfxImageSurface> surf = 
-        gl()->GetTexImage(containerSurface, true, mOGLManager->GetFBOTextureFormat());
-
-      WriteSnapshotToDumpFile(this, surf);
-    }
-#endif
-    
-    // Restore the viewport
-    gl()->PopViewportRect();
-    nsIntRect viewport = gl()->ViewportRect();
-    mOGLManager->SetupPipeline(viewport.width, viewport.height,
-                            LayerManagerOGL::ApplyWorldTransform);
-    gl()->PopScissorRect();
-
-    if (!mOGLManager->CompositingDisabled()) {
-      gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
-      gl()->fDeleteFramebuffers(1, &frameBuffer);
-
-      gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-
-      gl()->fBindTexture(mOGLManager->FBOTextureTarget(), containerSurface);
-
-      MaskType maskType = MaskNone;
-      if (GetMaskLayer()) {
-        if (!GetTransform().CanDraw2D()) {
-          maskType = Mask3d;
-        } else {
-          maskType = Mask2d;
-        }
-      }
-      ShaderProgramOGL *rgb =
-        mOGLManager->GetFBOLayerProgram(maskType);
-
-      rgb->Activate();
-      rgb->SetLayerQuadRect(visibleRect);
-      rgb->SetLayerTransform(transform);
-      rgb->SetTextureTransform(gfx3DMatrix());
-      rgb->SetLayerOpacity(opacity);
-      rgb->SetRenderOffset(aOffset);
-      rgb->SetTextureUnit(0);
-      rgb->LoadMask(GetMaskLayer());
-
-      if (rgb->GetTexCoordMultiplierUniformLocation() != -1) {
-        // 2DRect case, get the multiplier right for a sampler2DRect
-        rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height);
-      }
-
-      // Drawing is always flipped, but when copying between surfaces we want to avoid
-      // this. Pass true for the flip parameter to introduce a second flip
-      // that cancels the other one out.
-      mOGLManager->BindAndDrawQuad(rgb, true);
-
-      // Clean up resources.  This also unbinds the texture.
-      gl()->fDeleteTextures(1, &containerSurface);
-    }
-  } else {
-    gl()->PopScissorRect();
-  }
-}
-
-void
-ContainerLayerOGL::CleanupResources()
-{
-  for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) {
-    LayerOGL* layerToRender = static_cast<LayerOGL*>(l->ImplData());
-    layerToRender->CleanupResources();
-  }
-}
-
-} /* layers */
-} /* mozilla */
deleted file mode 100644
--- a/gfx/layers/opengl/ContainerLayerOGL.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- 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 GFX_CONTAINERLAYEROGL_H
-#define GFX_CONTAINERLAYEROGL_H
-
-#include "LayerManagerOGL.h"            // for LayerOGL
-#include "Layers.h"                     // for Layer (ptr only), etc
-class gfx3DMatrix;
-struct nsIntPoint;
-
-namespace mozilla {
-namespace layers {
-
-class ContainerLayerOGL : public ContainerLayer,
-                          public LayerOGL
-{
-public:
-  ContainerLayerOGL(LayerManagerOGL *aManager);
-  ~ContainerLayerOGL();
-
-  /** LayerOGL implementation */
-  Layer* GetLayer() { return this; }
-
-  void Destroy();
-
-  LayerOGL* GetFirstChildOGL();
-
-  virtual void RenderLayer(int aPreviousFrameBuffer,
-                           const nsIntPoint& aOffset);
-
-  virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
-  {
-    DefaultComputeEffectiveTransforms(aTransformToSurface);
-  }
-
-  virtual void CleanupResources();
-};
-
-} /* layers */
-} /* mozilla */
-
-#endif /* GFX_CONTAINERLAYEROGL_H */
--- a/gfx/layers/opengl/GLManager.cpp
+++ b/gfx/layers/opengl/GLManager.cpp
@@ -1,59 +1,32 @@
 /* -*- 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 "GLManager.h"
 #include "CompositorOGL.h"              // for CompositorOGL
 #include "GLContext.h"                  // for GLContext
-#include "LayerManagerOGL.h"            // for LayerManagerOGL
 #include "Layers.h"                     // for LayerManager
 #include "mozilla/Assertions.h"         // for MOZ_CRASH
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsISupportsImpl.h"            // for LayerManager::AddRef, etc
 
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
-class GLManagerLayerManager : public GLManager
-{
-public:
-  GLManagerLayerManager(LayerManagerOGL* aManager)
-    : mImpl(aManager)
-  {}
-
-  virtual GLContext* gl() const MOZ_OVERRIDE
-  {
-    return mImpl->gl();
-  }
-
-  virtual ShaderProgramOGL* GetProgram(ShaderProgramType aType) MOZ_OVERRIDE
-  {
-    return mImpl->GetProgram(aType);
-  }
-
-  virtual void BindAndDrawQuad(ShaderProgramOGL *aProg) MOZ_OVERRIDE
-  {
-    mImpl->BindAndDrawQuad(aProg);
-  }
-
-private:
-  nsRefPtr<LayerManagerOGL> mImpl;
-};
-
 class GLManagerCompositor : public GLManager
 {
 public:
   GLManagerCompositor(CompositorOGL* aCompositor)
     : mImpl(aCompositor)
   {}
 
   virtual GLContext* gl() const MOZ_OVERRIDE
@@ -75,18 +48,16 @@ private:
   RefPtr<CompositorOGL> mImpl;
 };
 
 /* static */ GLManager*
 GLManager::CreateGLManager(LayerManager* aManager)
 {
   if (!aManager) {
     return nullptr;
-  } else if (aManager->GetBackendType() == LAYERS_OPENGL) {
-    return new GLManagerLayerManager(static_cast<LayerManagerOGL*>(aManager));
   }
   if (aManager->GetBackendType() == LAYERS_NONE) {
     if (Compositor::GetBackend() == LAYERS_OPENGL) {
       return new GLManagerCompositor(static_cast<CompositorOGL*>(
         static_cast<LayerManagerComposite*>(aManager)->GetCompositor()));
     } else {
       return nullptr;
     }
--- a/gfx/layers/opengl/GLManager.h
+++ b/gfx/layers/opengl/GLManager.h
@@ -2,31 +2,31 @@
  * 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_GLMANAGER_H
 #define MOZILLA_GFX_GLMANAGER_H
 
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
-#include "LayerManagerOGLProgram.h"
+#include "OGLShaderProgram.h"
 
 namespace mozilla {
 namespace gl {
 class GLContext;
 }
 
 namespace layers {
 
 class LayerManager;
 
 /**
  * Minimal interface to allow widgets to draw using OpenGL. Abstracts
- * LayerManagerOGL and CompositorOGL. Call CreateGLManager with either a
- * LayerManagerOGL or a LayerManagerComposite backed by a CompositorOGL.
+ * CompositorOGL. Call CreateGLManager with a LayerManagerComposite
+ * backed by a CompositorOGL.
  */
 class GLManager
 {
 public:
   static GLManager* CreateGLManager(LayerManager* aManager);
 
   virtual ~GLManager() {}
 
deleted file mode 100644
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/* -*- 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 "ImageLayerOGL.h"
-#include <stdint.h>                     // for uint32_t
-#include "mozilla-config.h"             // for GL_PROVIDER_GLX
-#include "GLContext.h"                  // for GLContext, etc
-#include "ImageContainer.h"             // for CairoImage, etc
-#include "ImageTypes.h"                 // for ImageFormat::CAIRO_SURFACE, etc
-#include "SharedTextureImage.h"         // for SharedTextureImage::Data, etc
-#include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxASurface.h"                // for gfxASurface, etc
-#include "gfxImageSurface.h"            // for gfxImageSurface
-#include "gfxUtils.h"                   // for NextPowerOfTwo
-#include "mozilla/gfx/BaseSize.h"       // for BaseSize
-#include "mozilla/gfx/Types.h"          // for SurfaceFormat
-#include "mozilla/layers/LayersTypes.h"
-#include "nsAutoRef.h"                  // for nsCountedRef, nsAutoRefBase
-#include "nsCOMPtr.h"                   // for nsCOMPtr, already_AddRefed
-#include "nsDebug.h"                    // for NS_ASSERTION, NS_ERROR
-#include "nsIRunnable.h"                // for nsIRunnable
-#include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
-#include "nsSize.h"                     // for nsIntSize
-#include "nsThreadUtils.h"              // for nsRunnable
-#include "nscore.h"                     // for NS_IMETHOD
-#include "LayerManagerOGL.h"            // for LayerOGL::GLContext, etc
-#if defined(GL_PROVIDER_GLX)
-# include "GLXLibrary.h"
-# include "gfxXlibSurface.h"
-#endif
-
-using namespace mozilla::gfx;
-using namespace mozilla::gl;
-
-namespace mozilla {
-namespace layers {
-
-class Layer;
-
-/**
- * This is an event used to unref a GLContext on the main thread and
- * optionally delete a texture associated with that context.
- */
-class TextureDeleter : public nsRunnable {
-public:
-  TextureDeleter(already_AddRefed<GLContext> aContext,
-                 GLuint aTexture)
-      : mContext(aContext), mTexture(aTexture)
-  {
-    NS_ASSERTION(aTexture, "TextureDeleter instantiated with nothing to do");
-  }
-
-  NS_IMETHOD Run() {
-    mContext->MakeCurrent();
-    mContext->fDeleteTextures(1, &mTexture);
-
-    // Ensure context is released on the main thread
-    mContext = nullptr;
-    return NS_OK;
-  }
-
-  nsRefPtr<GLContext> mContext;
-  GLuint mTexture;
-};
-
-GLTexture::GLTexture()
-  : mTexture(0)
-{
-}
-
-GLTexture::~GLTexture()
-{
-  Release();
-}
-
-void
-GLTexture::Allocate(GLContext *aContext)
-{
-  NS_ASSERTION(aContext->IsGlobalSharedContext() || aContext->IsOwningThreadCurrent(),
-               "Can only allocate texture on context's owning thread or with cx sharing");
-
-  Release();
-
-  mContext = aContext;
-
-  mContext->MakeCurrent();
-  mContext->fGenTextures(1, &mTexture);
-}
-
-void
-GLTexture::TakeFrom(GLTexture *aOther)
-{
-  Release();
-
-  mContext = aOther->mContext.forget();
-  mTexture = aOther->mTexture;
-  aOther->mTexture = 0;
-}
-
-void
-GLTexture::Release()
-{
-  if (!mContext) {
-    NS_ASSERTION(!mTexture, "Can't delete texture without a context");
-    return;
-  }
-
-  if (mContext->IsDestroyed() && !mContext->IsGlobalSharedContext()) {
-    mContext = mContext->GetSharedContext();
-    if (!mContext) {
-      NS_ASSERTION(!mTexture, 
-                   "Context has been destroyed and couldn't find a shared context!");
-      return;
-    }
-  }
-
-  if (mTexture) {
-    if (mContext->IsOwningThreadCurrent() || mContext->IsGlobalSharedContext()) {
-      mContext->MakeCurrent();
-      mContext->fDeleteTextures(1, &mTexture);
-    } else {
-      already_AddRefed<GLContext> context = mContext.forget();
-      nsCOMPtr<nsIRunnable> runnable = new TextureDeleter(context, mTexture);
-      context.get()->DispatchToOwningThread(runnable);
-    }
-
-    mTexture = 0;
-  }
-
-  mContext = nullptr;
-}
-
-TextureRecycleBin::TextureRecycleBin()
-  : mLock("mozilla.layers.TextureRecycleBin.mLock")
-{
-}
-
-void
-TextureRecycleBin::RecycleTexture(GLTexture *aTexture, TextureType aType,
-                           const gfxIntSize& aSize)
-{
-  MutexAutoLock lock(mLock);
-
-  if (!aTexture->IsAllocated())
-    return;
-
-  if (!mRecycledTextures[aType].IsEmpty() && aSize != mRecycledTextureSizes[aType]) {
-    mRecycledTextures[aType].Clear();
-  }
-  mRecycledTextureSizes[aType] = aSize;
-  mRecycledTextures[aType].AppendElement()->TakeFrom(aTexture);
-}
-
-void
-TextureRecycleBin::GetTexture(TextureType aType, const gfxIntSize& aSize,
-                       GLContext *aContext, GLTexture *aOutTexture)
-{
-  MutexAutoLock lock(mLock);
-
-  if (mRecycledTextures[aType].IsEmpty() || mRecycledTextureSizes[aType] != aSize) {
-    aOutTexture->Allocate(aContext);
-    return;
-  }
-  uint32_t last = mRecycledTextures[aType].Length() - 1;
-  aOutTexture->TakeFrom(&mRecycledTextures[aType].ElementAt(last));
-  mRecycledTextures[aType].RemoveElementAt(last);
-}
-
-struct ImageOGLBackendData : public ImageBackendData
-{
-  GLTexture mTexture;
-};
-
-void
-AllocateTextureSharedTexture(SharedTextureImage *aTexImage, mozilla::gl::GLContext* aGL, GLenum aTarget)
-{
-  nsAutoPtr<ImageOGLBackendData> backendData(
-    new ImageOGLBackendData);
-
-  backendData->mTexture.Allocate(aGL);
-
-  aGL->fBindTexture(aTarget, backendData->mTexture.GetTextureID());
-  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
-  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-
-  aTexImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
-}
-
-Layer*
-ImageLayerOGL::GetLayer()
-{
-  return this;
-}
-
-void
-ImageLayerOGL::RenderLayer(int,
-                           const nsIntPoint& aOffset)
-{
-  nsRefPtr<ImageContainer> container = GetContainer();
-
-  if (!container || mOGLManager->CompositingDisabled())
-    return;
-
-  mOGLManager->MakeCurrent();
-
-  AutoLockImage autoLock(container);
-
-  Image *image = autoLock.GetImage();
-  if (!image) {
-    return;
-  }
-
-  NS_ASSERTION(image->GetFormat() != REMOTE_IMAGE_BITMAP,
-    "Remote images aren't handled yet in OGL layers!");
-
-  if (image->GetFormat() == PLANAR_YCBCR) {
-    PlanarYCbCrImage *yuvImage =
-      static_cast<PlanarYCbCrImage*>(image);
-
-    if (!yuvImage->IsValid()) {
-      return;
-    }
-
-    PlanarYCbCrOGLBackendData *data =
-      static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LAYERS_OPENGL));
-
-    if (data && data->mTextures->GetGLContext() != gl()) {
-      // If these textures were allocated by another layer manager,
-      // clear them out and re-allocate below.
-      data = nullptr;
-      yuvImage->SetBackendData(LAYERS_OPENGL, nullptr);
-    }
-
-    if (!data) {
-      AllocateTexturesYCbCr(yuvImage);
-      data = static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LAYERS_OPENGL));
-    }
-
-    if (!data || data->mTextures->GetGLContext() != gl()) {
-      // XXX - Can this ever happen? If so I need to fix this!
-      return;
-    }
-
-    gl()->MakeCurrent();
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE2);
-    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[2].GetTextureID());
-    gl()->ApplyFilterToBoundTexture(mFilter);
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE1);
-    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[1].GetTextureID());
-    gl()->ApplyFilterToBoundTexture(mFilter);
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[0].GetTextureID());
-    gl()->ApplyFilterToBoundTexture(mFilter);
-
-    ShaderProgramOGL *program = mOGLManager->GetProgram(YCbCrLayerProgramType,
-                                                        GetMaskLayer());
-
-    program->Activate();
-    program->SetLayerQuadRect(nsIntRect(0, 0,
-                                        yuvImage->GetSize().width,
-                                        yuvImage->GetSize().height));
-    program->SetLayerTransform(GetEffectiveTransform());
-    program->SetTextureTransform(gfx3DMatrix());
-    program->SetLayerOpacity(GetEffectiveOpacity());
-    program->SetRenderOffset(aOffset);
-    program->SetYCbCrTextureUnits(0, 1, 2);
-    program->LoadMask(GetMaskLayer());
-
-    mOGLManager->BindAndDrawQuadWithTextureRect(program,
-                                                yuvImage->GetData()->GetPictureRect(),
-                                                nsIntSize(yuvImage->GetData()->mYSize.width,
-                                                          yuvImage->GetData()->mYSize.height));
-
-    // We shouldn't need to do this, but do it anyway just in case
-    // someone else forgets.
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-  } else if (image->GetFormat() == CAIRO_SURFACE) {
-    CairoImage *cairoImage =
-      static_cast<CairoImage*>(image);
-
-    if (!cairoImage->mSurface) {
-      return;
-    }
-
-    NS_ASSERTION(cairoImage->mSurface->GetContentType() != GFX_CONTENT_ALPHA,
-                 "Image layer has alpha image");
-
-    CairoOGLBackendData *data =
-      static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LAYERS_OPENGL));
-
-    if (data && data->mTexture.GetGLContext() != gl()) {
-      // If this texture was allocated by another layer manager, clear
-      // it out and re-allocate below.
-      data = nullptr;
-      cairoImage->SetBackendData(LAYERS_OPENGL, nullptr);
-    }
-
-    if (!data) {
-      AllocateTexturesCairo(cairoImage);
-      data = static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LAYERS_OPENGL));
-    }
-
-    if (!data || data->mTexture.GetGLContext() != gl()) {
-      // XXX - Can this ever happen? If so I need to fix this!
-      return;
-    }
-
-    gl()->MakeCurrent();
-
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTexture.GetTextureID());
-
-    ShaderProgramOGL *program = mOGLManager->GetProgram(data->mLayerProgram, GetMaskLayer());
-
-    gl()->ApplyFilterToBoundTexture(mFilter);
-
-    program->Activate();
-    program->SetLayerQuadRect(nsIntRect(0, 0, 
-                                        cairoImage->GetSize().width, 
-                                        cairoImage->GetSize().height));
-    program->SetLayerTransform(GetEffectiveTransform());
-    program->SetTextureTransform(gfx3DMatrix());
-    program->SetLayerOpacity(GetEffectiveOpacity());
-    program->SetRenderOffset(aOffset);
-    program->SetTextureUnit(0);
-    program->LoadMask(GetMaskLayer());
-
-    mOGLManager->BindAndDrawQuad(program);
-  } else if (image->GetFormat() == SHARED_TEXTURE) {
-    SharedTextureImage* texImage =
-      static_cast<SharedTextureImage*>(image);
-    const SharedTextureImage::Data* data = texImage->GetData();
-    GLContext::SharedHandleDetails handleDetails;
-    if (!gl()->GetSharedHandleDetails(data->mShareType, data->mHandle, handleDetails)) {
-      NS_ERROR("Failed to get shared handle details");
-      return;
-    }
-
-    ShaderProgramType programType =
-      ShaderProgramFromTargetAndFormat(handleDetails.mTarget,
-                                       handleDetails.mTextureFormat);
-    ShaderProgramOGL* program = mOGLManager->GetProgram(programType, GetMaskLayer());
-
-    program->Activate();
-    if (programType == RGBARectLayerProgramType) {
-      // 2DRect case, get the multiplier right for a sampler2DRect
-      program->SetTexCoordMultiplier(data->mSize.width, data->mSize.height);
-    }
-    program->SetLayerTransform(GetEffectiveTransform());
-    program->SetTextureTransform(gfx3DMatrix());
-    program->SetLayerOpacity(GetEffectiveOpacity());
-    program->SetRenderOffset(aOffset);
-    program->SetTextureUnit(0);
-    program->SetTextureTransform(handleDetails.mTextureTransform);
-    program->LoadMask(GetMaskLayer());
-
-    if (!texImage->GetBackendData(LAYERS_OPENGL)) {
-      AllocateTextureSharedTexture(texImage, gl(), handleDetails.mTarget);
-    }
-
-    ImageOGLBackendData *backendData =
-      static_cast<ImageOGLBackendData*>(texImage->GetBackendData(LAYERS_OPENGL));
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-    gl()->fBindTexture(handleDetails.mTarget, backendData->mTexture.GetTextureID());
-
-    if (!gl()->AttachSharedHandle(data->mShareType, data->mHandle)) {
-      NS_ERROR("Failed to bind shared texture handle");
-      return;
-    }
-
-    gl()->ApplyFilterToBoundTexture(handleDetails.mTarget, mFilter);
-    program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), data->mSize));
-    mOGLManager->BindAndDrawQuad(program, data->mInverted);
-    gl()->fBindTexture(handleDetails.mTarget, 0);
-    gl()->DetachSharedHandle(data->mShareType, data->mHandle);
-  }
-  GetContainer()->NotifyPaintedImage(image);
-}
-
-static void
-SetClamping(GLContext* aGL, GLuint aTexture)
-{
-  aGL->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-}
-
-static void
-UploadYUVToTexture(GLContext* gl, const PlanarYCbCrData& aData, 
-                   GLTexture* aYTexture,
-                   GLTexture* aUTexture,
-                   GLTexture* aVTexture)
-{
-  nsIntRect size(0, 0, aData.mYSize.width, aData.mYSize.height);
-  GLuint texture = aYTexture->GetTextureID();
-  nsRefPtr<gfxASurface> surf = new gfxImageSurface(aData.mYChannel,
-                                                   aData.mYSize,
-                                                   aData.mYStride,
-                                                   gfxImageFormatA8);
-  gl->UploadSurfaceToTexture(surf, size, texture, true);
-  
-  size = nsIntRect(0, 0, aData.mCbCrSize.width, aData.mCbCrSize.height);
-  texture = aUTexture->GetTextureID();
-  surf = new gfxImageSurface(aData.mCbChannel,
-                             aData.mCbCrSize,
-                             aData.mCbCrStride,
-                             gfxImageFormatA8);
-  gl->UploadSurfaceToTexture(surf, size, texture, true);
-
-  texture = aVTexture->GetTextureID();
-  surf = new gfxImageSurface(aData.mCrChannel,
-                             aData.mCbCrSize,
-                             aData.mCbCrStride,
-                             gfxImageFormatA8);
-  gl->UploadSurfaceToTexture(surf, size, texture, true);
-}
-
-ImageLayerOGL::ImageLayerOGL(LayerManagerOGL *aManager)
-  : ImageLayer(aManager, nullptr)
-  , LayerOGL(aManager)
-  , mTextureRecycleBin(new TextureRecycleBin())
-{ 
-  mImplData = static_cast<LayerOGL*>(this);
-}
-
-void
-ImageLayerOGL::AllocateTexturesYCbCr(PlanarYCbCrImage *aImage)
-{
-  if (!aImage->IsValid())
-    return;
-
-  nsAutoPtr<PlanarYCbCrOGLBackendData> backendData(
-    new PlanarYCbCrOGLBackendData);
-
-  const PlanarYCbCrData *data = aImage->GetData();
-
-  gl()->MakeCurrent();
-
-  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_Y, data->mYSize, gl(), &backendData->mTextures[0]);
-  SetClamping(gl(), backendData->mTextures[0].GetTextureID());
-
-  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data->mCbCrSize, gl(), &backendData->mTextures[1]);
-  SetClamping(gl(), backendData->mTextures[1].GetTextureID());
-
-  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data->mCbCrSize, gl(), &backendData->mTextures[2]);
-  SetClamping(gl(), backendData->mTextures[2].GetTextureID());
-
-  UploadYUVToTexture(gl(), *data,
-                     &backendData->mTextures[0],
-                     &backendData->mTextures[1],
-                     &backendData->mTextures[2]);
-
-  backendData->mYSize = data->mYSize;
-  backendData->mCbCrSize = data->mCbCrSize;
-  backendData->mTextureRecycleBin = mTextureRecycleBin;
-
-  aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
-}
-
-void
-ImageLayerOGL::AllocateTexturesCairo(CairoImage *aImage)
-{
-  nsAutoPtr<CairoOGLBackendData> backendData(
-    new CairoOGLBackendData);
-
-  GLTexture &texture = backendData->mTexture;
-
-  texture.Allocate(gl());
-
-  if (!texture.IsAllocated()) {
-    return;
-  }
-
-  mozilla::gl::GLContext *gl = texture.GetGLContext();
-  gl->MakeCurrent();
-
-  GLuint tex = texture.GetTextureID();
-  gl->fActiveTexture(LOCAL_GL_TEXTURE0);
-
-  SetClamping(gl, tex);
-
-#if defined(GL_PROVIDER_GLX)
-  if (aImage->mSurface->GetType() == gfxSurfaceTypeXlib) {
-    gfxXlibSurface *xsurf =
-      static_cast<gfxXlibSurface*>(aImage->mSurface.get());
-    GLXPixmap pixmap = xsurf->GetGLXPixmap();
-    if (pixmap) {
-      backendData->mLayerProgram = ShaderProgramFromContentType(aImage->mSurface->GetContentType());
-
-      aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
-
-      sDefGLXLib.BindTexImage(pixmap);
-
-      return;
-    }
-  }
-#endif
-  gfx::SurfaceFormat format =
-    gl->UploadSurfaceToTexture(aImage->mSurface,
-                               nsIntRect(0,0, aImage->mSize.width, aImage->mSize.height),
-                               tex, true);
-  backendData->mLayerProgram = ShaderProgramFromSurfaceFormat(format);
-
-  aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
-}
-
-/*
- * Returns a size that is larger than and closest to aSize where both
- * width and height are powers of two.
- * If the OpenGL setup is capable of using non-POT textures, then it
- * will just return aSize.
- */
-static gfxIntSize
-CalculatePOTSize(const gfxIntSize& aSize, GLContext* gl)
-{
-  if (gl->CanUploadNonPowerOfTwo())
-    return aSize;
-
-  return gfxIntSize(NextPowerOfTwo(aSize.width), NextPowerOfTwo(aSize.height));
-}
-
-bool
-ImageLayerOGL::LoadAsTexture(GLuint aTextureUnit, gfxIntSize* aSize)
-{
-  // this method shares a lot of code with RenderLayer, but it doesn't seem
-  // to be possible to factor it out into a helper method
-
-  if (!GetContainer()) {
-    return false;
-  }
-
-  AutoLockImage autoLock(GetContainer());
-
-  Image *image = autoLock.GetImage();
-  if (!image) {
-    return false;
-  }
-
-  if (image->GetFormat() != CAIRO_SURFACE) {
-    return false;
-  }
-
-  CairoImage* cairoImage = static_cast<CairoImage*>(image);
-
-  if (!cairoImage->mSurface) {
-    return false;
-  }
-
-  CairoOGLBackendData *data = static_cast<CairoOGLBackendData*>(
-    cairoImage->GetBackendData(LAYERS_OPENGL));
-
-  if (!data) {
-    NS_ASSERTION(cairoImage->mSurface->GetContentType() == GFX_CONTENT_ALPHA,
-                 "OpenGL mask layers must be backed by alpha surfaces");
-
-    // allocate a new texture and save the details in the backend data
-    data = new CairoOGLBackendData;
-    data->mTextureSize = CalculatePOTSize(cairoImage->mSize, gl());
-
-    GLTexture &texture = data->mTexture;
-    texture.Allocate(mOGLManager->gl());
-
-    if (!texture.IsAllocated()) {
-      return false;
-    }
-
-    mozilla::gl::GLContext *texGL = texture.GetGLContext();
-    texGL->MakeCurrent();
-
-    GLuint texID = texture.GetTextureID();
-
-    gfx::SurfaceFormat format =
-      texGL->UploadSurfaceToTexture(cairoImage->mSurface,
-                                    nsIntRect(0,0,
-                                              data->mTextureSize.width,
-                                              data->mTextureSize.height),
-                                    texID, true, nsIntPoint(0,0), false,
-                                    aTextureUnit);
-    data->mLayerProgram = ShaderProgramFromSurfaceFormat(format);
-
-    cairoImage->SetBackendData(LAYERS_OPENGL, data);
-
-    gl()->MakeCurrent();
-    gl()->fActiveTexture(aTextureUnit);
-    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, texID);
-    gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER,
-                         LOCAL_GL_LINEAR);
-    gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER,
-                         LOCAL_GL_LINEAR);
-    gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S,
-                         LOCAL_GL_CLAMP_TO_EDGE);
-    gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T,
-                         LOCAL_GL_CLAMP_TO_EDGE);
-  } else {
-    gl()->fActiveTexture(aTextureUnit);
-    gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTexture.GetTextureID());
-  }
-
-  *aSize = data->mTextureSize;
-  return true;
-}
-
-} /* layers */
-} /* mozilla */
deleted file mode 100644
--- a/gfx/layers/opengl/ImageLayerOGL.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* -*- 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 GFX_IMAGELAYEROGL_H
-#define GFX_IMAGELAYEROGL_H
-
-#include "GLContextTypes.h"             // for GLContext, GLuint
-#include "ImageContainer.h"             // for ImageBackendData, etc
-#include "ImageLayers.h"                // for ImageLayer
-#include "LayerManagerOGL.h"            // for LayerOGL
-#include "gfxPoint.h"                   // for gfxIntSize
-#include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
-#include "mozilla/Mutex.h"              // for Mutex
-#include "mozilla/mozalloc.h"           // for operator delete
-#include "nsAutoPtr.h"                  // for nsRefPtr
-#include "nsISupportsImpl.h"            // for TextureRecycleBin::Release, etc
-#include "nsTArray.h"                   // for nsTArray
-#include "opengl/LayerManagerOGLProgram.h"  // for ShaderProgramType, etc
-
-struct nsIntPoint;
-
-namespace mozilla {
-namespace layers {
-
-class BlobYCbCrSurface;
-class Layer;
-
-/**
- * This class wraps a GL texture. It includes a GLContext reference
- * so we can use to free the texture when destroyed. The implementation
- * makes sure to always free the texture on the main thread, even if the
- * destructor runs on another thread.
- *
- * We ensure that the GLContext reference is only addrefed and released
- * on the main thread, although it uses threadsafe recounting so we don't
- * really have to.
- *
- * Initially the texture is not allocated --- it's in a "null" state.
- */
-class GLTexture
-{
-  typedef mozilla::gl::GLContext GLContext;
-
-public:
-  GLTexture();
-  ~GLTexture();
-
-  /**
-   * Allocate the texture. This can only be called on the main thread.
-   */
-  void Allocate(GLContext *aContext);
-  /**
-   * Move the state of aOther to this GLTexture. If this GLTexture currently
-   * has a texture, it is released. This can be called on any thread.
-   */
-  void TakeFrom(GLTexture *aOther);
-
-  bool IsAllocated() { return mTexture != 0; }
-  GLuint GetTextureID() { return mTexture; }
-  GLContext *GetGLContext() { return mContext; }
-
-  void Release();
-private:
-
-  nsRefPtr<GLContext> mContext;
-  GLuint mTexture;
-};
-
-/**
- * A RecycleBin is owned by an ImageLayer. We store textures in it that we
- * want to recycle from one image to the next. It's a separate object from 
- * ImageContainer because images need to store a strong ref to their RecycleBin
- * and we must avoid creating a reference loop between an ImageContainer and
- * its active image.
- */
-class TextureRecycleBin {
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureRecycleBin)
-
-  typedef mozilla::gl::GLContext GLContext;
-
-public:
-  TextureRecycleBin();
-
-  enum TextureType {
-    TEXTURE_Y,
-    TEXTURE_C
-  };
-
-  void RecycleTexture(GLTexture *aTexture, TextureType aType,
-                      const gfxIntSize& aSize);
-  void GetTexture(TextureType aType, const gfxIntSize& aSize,
-                  GLContext *aContext, GLTexture *aOutTexture);
-
-private:
-  typedef mozilla::Mutex Mutex;
-
-  // This protects mRecycledBuffers, mRecycledBufferSize, mRecycledTextures
-  // and mRecycledTextureSizes
-  Mutex mLock;
-
-  nsTArray<GLTexture> mRecycledTextures[2];
-  gfxIntSize mRecycledTextureSizes[2];
-};
-
-class ImageLayerOGL : public ImageLayer,
-                      public LayerOGL
-{
-public:
-  ImageLayerOGL(LayerManagerOGL *aManager);
-  ~ImageLayerOGL() { Destroy(); }
-
-  // LayerOGL Implementation
-  virtual void Destroy() { mDestroyed = true; }
-  virtual Layer* GetLayer();
-  virtual bool LoadAsTexture(GLuint aTextureUnit, gfxIntSize* aSize);
-
-  virtual void RenderLayer(int aPreviousFrameBuffer,
-                           const nsIntPoint& aOffset);
-  virtual void CleanupResources() {}
-
-
-  void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage);
-  void AllocateTexturesCairo(CairoImage *aImage);
-
-protected:
-  nsRefPtr<TextureRecycleBin> mTextureRecycleBin;
-};
-
-struct PlanarYCbCrOGLBackendData : public ImageBackendData
-{
-  ~PlanarYCbCrOGLBackendData()
-  {
-    if (HasTextures()) {
-      mTextureRecycleBin->RecycleTexture(&mTextures[0], TextureRecycleBin::TEXTURE_Y, mYSize);
-      mTextureRecycleBin->RecycleTexture(&mTextures[1], TextureRecycleBin::TEXTURE_C, mCbCrSize);
-      mTextureRecycleBin->RecycleTexture(&mTextures[2], TextureRecycleBin::TEXTURE_C, mCbCrSize);
-    }
-  }
-
-  bool HasTextures()
-  {
-    return mTextures[0].IsAllocated() && mTextures[1].IsAllocated() &&
-           mTextures[2].IsAllocated();
-  }
-
-  GLTexture mTextures[3];
-  gfxIntSize mYSize, mCbCrSize;
-  nsRefPtr<TextureRecycleBin> mTextureRecycleBin;
-};
-
-
-struct CairoOGLBackendData : public ImageBackendData
-{
-  CairoOGLBackendData() : mLayerProgram(RGBALayerProgramType) {}
-  GLTexture mTexture;
-  ShaderProgramType mLayerProgram;
-  gfxIntSize mTextureSize;
-};
-
-} /* layers */
-} /* mozilla */
-#endif /* GFX_IMAGELAYEROGL_H */
deleted file mode 100644
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ /dev/null
@@ -1,1319 +0,0 @@
-/* -*- 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 "LayerManagerOGL.h"
-#include <stddef.h>                     // for size_t
-#include <stdint.h>                     // for uint32_t, uint8_t, etc
-#include "CanvasLayerOGL.h"             // for CanvasLayerOGL
-#include "ColorLayerOGL.h"              // for ColorLayerOGL
-#include "Composer2D.h"                 // for Composer2D
-#include "ContainerLayerOGL.h"          // for ContainerLayerOGL
-#include "FPSCounter.h"                 // for FPSState, FPSCounter
-#include "GLContext.h"                  // for GLContext, etc
-#include "GLContextProvider.h"          // for GLContextProvider
-#include "GeckoProfiler.h"              // for PROFILER_LABEL
-#include "ImageLayerOGL.h"              // for ImageLayerOGL
-#include "ImageLayers.h"                // for ImageLayer
-#include "ThebesLayerOGL.h"             // for ThebesLayerOGL
-#include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxASurface.h"                // for gfxASurface, etc
-#include "gfxContext.h"                 // for gfxContext, etc
-#include "gfxCrashReporterUtils.h"      // for ScopedGfxFeatureReporter
-#include "gfxImageSurface.h"            // for gfxImageSurface
-#include "gfxPlatform.h"                // for gfxPlatform
-#include "gfxRect.h"                    // for gfxRect
-#include "gfxUtils.h"                   // for NextPowerOfTwo, gfxUtils, etc
-#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
-#include "mozilla/Preferences.h"        // for Preferences
-#include "mozilla/TimeStamp.h"          // for TimeStamp
-#include "mozilla/Util.h"               // for ArrayLength
-#include "mozilla/gfx/2D.h"             // for DrawTarget
-#include "mozilla/gfx/BasePoint.h"      // for BasePoint
-#include "mozilla/mozalloc.h"           // for operator delete, etc
-#include "nsIConsoleService.h"          // for nsIConsoleService, etc
-#include "nsIWidget.h"                  // for nsIWidget
-#include "nsLiteralString.h"            // for NS_LITERAL_STRING
-#include "nsPoint.h"                    // for nsIntPoint
-#include "nsServiceManagerUtils.h"      // for do_GetService
-#include "nsString.h"                   // for nsAutoCString, nsString, etc
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL, etc
-#ifdef XP_WIN
-#include "prenv.h"                      // for PR_GetEnv
-#endif
-#ifdef MOZ_WIDGET_ANDROID
-#include <android/log.h>
-#include "TexturePoolOGL.h"
-#endif
-#ifdef XP_MACOSX
-#include "gfxPlatformMac.h"
-#endif
-
-namespace mozilla {
-namespace layers {
-
-using namespace mozilla::gfx;
-using namespace mozilla::gl;
-
-int32_t
-LayerManagerOGL::GetMaxTextureSize() const
-{
-  int32_t maxSize;
-  mGLContext->MakeCurrent();
-  mGLContext->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxSize);
-  return maxSize;
-}
-
-void
-LayerManagerOGL::MakeCurrent(bool aForce)
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return;
-  }
-  mGLContext->MakeCurrent(aForce);
-}
-
-void*
-LayerManagerOGL::GetNSOpenGLContext() const
-{
-  return gl()->GetNativeData(GLContext::NativeGLContext);
-}
-
-
-void
-LayerManagerOGL::BindQuadVBO() {
-  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
-}
-
-void
-LayerManagerOGL::QuadVBOVerticesAttrib(GLuint aAttribIndex) {
-  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
-                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                   (GLvoid*) QuadVBOVertexOffset());
-}
-
-void
-LayerManagerOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) {
-  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
-                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                   (GLvoid*) QuadVBOTexCoordOffset());
-}
-
-void
-LayerManagerOGL::QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) {
-  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
-                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                   (GLvoid*) QuadVBOFlippedTexCoordOffset());
-}
-
-// Super common
-
-void
-LayerManagerOGL::BindAndDrawQuad(GLuint aVertAttribIndex,
-                     GLuint aTexCoordAttribIndex,
-                     bool aFlipped)
-{
-  BindQuadVBO();
-  QuadVBOVerticesAttrib(aVertAttribIndex);
-
-  if (aTexCoordAttribIndex != GLuint(-1)) {
-    if (aFlipped)
-      QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex);
-    else
-      QuadVBOTexCoordsAttrib(aTexCoordAttribIndex);
-
-    mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex);
-  }
-
-  mGLContext->fEnableVertexAttribArray(aVertAttribIndex);
-
-  mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
-
-  mGLContext->fDisableVertexAttribArray(aVertAttribIndex);
-
-  if (aTexCoordAttribIndex != GLuint(-1)) {
-    mGLContext->fDisableVertexAttribArray(aTexCoordAttribIndex);
-  }
-}
-
-/**
- * LayerManagerOGL
- */
-LayerManagerOGL::LayerManagerOGL(nsIWidget *aWidget, int aSurfaceWidth, int aSurfaceHeight,
-                                 bool aIsRenderingToEGLSurface)
-  : mWidget(aWidget)
-  , mWidgetSize(-1, -1)
-  , mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
-  , mBackBufferFBO(0)
-  , mBackBufferTexture(0)
-  , mBackBufferSize(-1, -1)
-  , mHasBGRA(0)
-  , mIsRenderingToEGLSurface(aIsRenderingToEGLSurface)
-#ifdef DEBUG
-  , mMaybeInvalidTree(false)
-#endif
-{
-}
-
-LayerManagerOGL::~LayerManagerOGL()
-{
-  Destroy();
-}
-
-void
-LayerManagerOGL::Destroy()
-{
-  if (mDestroyed)
-    return;
-
-  if (mRoot) {
-    RootLayer()->Destroy();
-    mRoot = nullptr;
-  }
-
-  mWidget->CleanupWindowEffects();
-
-  if (!mGLContext)
-    return;
-
-  nsRefPtr<GLContext> ctx = mGLContext->GetSharedContext();
-  if (!ctx) {
-    ctx = mGLContext;
-  }
-
-  ctx->MakeCurrent();
-
-  for (uint32_t i = 0; i < mPrograms.Length(); ++i) {
-    for (uint32_t type = MaskNone; type < NumMaskTypes; ++type) {
-      delete mPrograms[i].mVariations[type];
-    }
-  }
-  mPrograms.Clear();
-
-  ctx->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-
-  if (mBackBufferFBO) {
-    ctx->fDeleteFramebuffers(1, &mBackBufferFBO);
-    mBackBufferFBO = 0;
-  }
-
-  if (mBackBufferTexture) {
-    ctx->fDeleteTextures(1, &mBackBufferTexture);
-    mBackBufferTexture = 0;
-  }
-
-  if (mQuadVBO) {
-    ctx->fDeleteBuffers(1, &mQuadVBO);
-    mQuadVBO = 0;
-  }
-
-  mGLContext = nullptr;
-
-  mDestroyed = true;
-}
-
-already_AddRefed<mozilla::gl::GLContext>
-LayerManagerOGL::CreateContext()
-{
-  nsRefPtr<GLContext> context;
-
-#ifdef XP_WIN
-  if (PR_GetEnv("MOZ_LAYERS_PREFER_EGL")) {
-    printf_stderr("Trying GL layers...\n");
-    context = gl::GLContextProviderEGL::CreateForWindow(mWidget);
-  }
-#endif
-
-  if (!context)
-    context = gl::GLContextProvider::CreateForWindow(mWidget);
-
-  if (!context) {
-    NS_WARNING("Failed to create LayerManagerOGL context");
-  }
-  return context.forget();
-}
-
-void
-LayerManagerOGL::AddPrograms(ShaderProgramType aType)
-{
-  for (uint32_t maskType = MaskNone; maskType < NumMaskTypes; ++maskType) {
-    if (ProgramProfileOGL::ProgramExists(aType, static_cast<MaskType>(maskType))) {
-      mPrograms[aType].mVariations[maskType] = new ShaderProgramOGL(this->gl(),
-        ProgramProfileOGL::GetProfileFor(aType, static_cast<MaskType>(maskType)));
-    } else {
-      mPrograms[aType].mVariations[maskType] = nullptr;
-    }
-  }
-}
-
-// Impl of a a helper-runnable's "Run" method, used in Initialize()
-NS_IMETHODIMP
-LayerManagerOGL::ReadDrawFPSPref::Run()
-{
-  // NOTE: This must match the code in Initialize()'s NS_IsMainThread check.
-  Preferences::AddBoolVarCache(&sDrawFPS, "layers.acceleration.draw-fps");
-  return NS_OK;
-}
-
-bool
-LayerManagerOGL::Initialize(bool force)
-{
-  ScopedGfxFeatureReporter reporter("GL Layers", force);
-
-  // Do not allow double initialization
-  NS_ABORT_IF_FALSE(mGLContext == nullptr, "Don't reinitialize layer managers");
-
-  nsRefPtr<GLContext> ctx = CreateContext();
-
-#ifdef MOZ_WIDGET_ANDROID
-  if (!ctx) {
-    NS_RUNTIMEABORT("We need a context on Android");
-  }
-#endif
-
-  if (!ctx) {
-    return false;
-  }
-
-  mGLContext = ctx;
-  mGLContext->SetFlipped(true);
-
-  MakeCurrent();
-
-  mHasBGRA =
-    mGLContext->IsExtensionSupported(gl::GLContext::EXT_texture_format_BGRA8888) ||
-    mGLContext->IsExtensionSupported(gl::GLContext::EXT_bgra);
-
-  mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
-                                 LOCAL_GL_ONE, LOCAL_GL_ONE);
-  mGLContext->fEnable(LOCAL_GL_BLEND);
-
-  mPrograms.AppendElements(NumProgramTypes);
-  for (int type = 0; type < NumProgramTypes; ++type) {
-    AddPrograms(static_cast<ShaderProgramType>(type));
-  }
-
-  // initialise a common shader to check that we can actually compile a shader
-  if (!mPrograms[RGBALayerProgramType].mVariations[MaskNone]->Initialize()) {
-#ifdef MOZ_WIDGET_ANDROID
-    NS_RUNTIMEABORT("Shader initialization failed");
-#endif
-    return false;
-  }
-
-
-  mGLContext->fGenFramebuffers(1, &mBackBufferFBO);
-
-  if (mGLContext->WorkAroundDriverBugs()) {
-
-    /**
-    * We'll test the ability here to bind NPOT textures to a framebuffer, if
-    * this fails we'll try ARB_texture_rectangle.
-    */
-
-    GLenum textureTargets[] = {
-      LOCAL_GL_TEXTURE_2D,
-      LOCAL_GL_NONE
-    };
-
-    if (mGLContext->IsGLES2()) {
-        textureTargets[1] = LOCAL_GL_TEXTURE_RECTANGLE_ARB;
-    }
-
-    mFBOTextureTarget = LOCAL_GL_NONE;
-
-    for (uint32_t i = 0; i < ArrayLength(textureTargets); i++) {
-      GLenum target = textureTargets[i];
-      if (!target)
-          continue;
-
-      mGLContext->fGenTextures(1, &mBackBufferTexture);
-      mGLContext->fBindTexture(target, mBackBufferTexture);
-      mGLContext->fTexParameteri(target,
-                                LOCAL_GL_TEXTURE_MIN_FILTER,
-                                LOCAL_GL_NEAREST);
-      mGLContext->fTexParameteri(target,
-                                LOCAL_GL_TEXTURE_MAG_FILTER,
-                                LOCAL_GL_NEAREST);
-      mGLContext->fTexImage2D(target,
-                              0,
-                              LOCAL_GL_RGBA,
-                              5, 3, /* sufficiently NPOT */
-                              0,
-                              LOCAL_GL_RGBA,
-                              LOCAL_GL_UNSIGNED_BYTE,
-                              nullptr);
-
-      // unbind this texture, in preparation for binding it to the FBO
-      mGLContext->fBindTexture(target, 0);
-
-      mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackBufferFBO);
-      mGLContext->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
-                                        LOCAL_GL_COLOR_ATTACHMENT0,
-                                        target,
-                                        mBackBufferTexture,
-                                        0);
-
-      if (mGLContext->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) ==
-          LOCAL_GL_FRAMEBUFFER_COMPLETE)
-      {
-        mFBOTextureTarget = target;
-        break;
-      }
-
-      // We weren't succesful with this texture, so we don't need it
-      // any more.
-      mGLContext->fDeleteTextures(1, &mBackBufferTexture);
-    }
-
-    if (mFBOTextureTarget == LOCAL_GL_NONE) {
-      /* Unable to find a texture target that works with FBOs and NPOT textures */
-#ifdef MOZ_WIDGET_ANDROID
-      NS_RUNTIMEABORT("No texture target");
-#endif
-      return false;
-    }
-  } else {
-    // not trying to work around driver bugs, so TEXTURE_2D should just work
-    mFBOTextureTarget = LOCAL_GL_TEXTURE_2D;
-  }
-
-  // back to default framebuffer, to avoid confusion
-  mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-
-  if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) {
-    /* If we're using TEXTURE_RECTANGLE, then we must have the ARB
-     * extension -- the EXT variant does not provide support for
-     * texture rectangle access inside GLSL (sampler2DRect,
-     * texture2DRect).
-     */
-    if (!mGLContext->IsExtensionSupported(gl::GLContext::ARB_texture_rectangle))
-#ifdef MOZ_WIDGET_ANDROID
-      NS_RUNTIMEABORT("No texture rectangle");
-#endif
-      return false;
-  }
-
-  // If we're double-buffered, we don't need this fbo anymore.
-  if (mGLContext->IsDoubleBuffered()) {
-    mGLContext->fDeleteFramebuffers(1, &mBackBufferFBO);
-    mBackBufferFBO = 0;
-  }
-
-  /* Create a simple quad VBO */
-
-  mGLContext->fGenBuffers(1, &mQuadVBO);
-  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
-
-  GLfloat vertices[] = {
-    /* First quad vertices */
-    0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-    /* Then quad texcoords */
-    0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-    /* Then flipped quad texcoords */
-    0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-  };
-  mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER, sizeof(vertices), vertices, LOCAL_GL_STATIC_DRAW);
-  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-
-  nsCOMPtr<nsIConsoleService>
-    console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
-
-  if (console) {
-    nsString msg;
-    msg +=
-      NS_LITERAL_STRING("OpenGL LayerManager Initialized Succesfully.\nVersion: ");
-    msg += NS_ConvertUTF8toUTF16(
-      nsDependentCString((const char*)mGLContext->fGetString(LOCAL_GL_VERSION)));
-    msg += NS_LITERAL_STRING("\nVendor: ");
-    msg += NS_ConvertUTF8toUTF16(
-      nsDependentCString((const char*)mGLContext->fGetString(LOCAL_GL_VENDOR)));
-    msg += NS_LITERAL_STRING("\nRenderer: ");
-    msg += NS_ConvertUTF8toUTF16(
-      nsDependentCString((const char*)mGLContext->fGetString(LOCAL_GL_RENDERER)));
-    msg += NS_LITERAL_STRING("\nFBO Texture Target: ");
-    if (mFBOTextureTarget == LOCAL_GL_TEXTURE_2D)
-      msg += NS_LITERAL_STRING("TEXTURE_2D");
-    else
-      msg += NS_LITERAL_STRING("TEXTURE_RECTANGLE");
-    console->LogStringMessage(msg.get());
-  }
-
-  if (NS_IsMainThread()) {
-    // NOTE: This must match the code in ReadDrawFPSPref::Run().
-    Preferences::AddBoolVarCache(&sDrawFPS, "layers.acceleration.draw-fps");
-  } else {
-    // We have to dispatch an event to the main thread to read the pref.
-    NS_DispatchToMainThread(new ReadDrawFPSPref());
-  }
-
-  mComposer2D = mWidget->GetComposer2D();
-
-  reporter.SetSuccessful();
-  return true;
-}
-
-void
-LayerManagerOGL::SetClippingRegion(const nsIntRegion& aClippingRegion)
-{
-  mClippingRegion = aClippingRegion;
-}
-
-void
-LayerManagerOGL::BeginTransaction()
-{
-  mInTransaction = true;
-#ifdef DEBUG
-  mMaybeInvalidTree = false;
-#endif
-}
-
-void
-LayerManagerOGL::BeginTransactionWithTarget(gfxContext *aTarget)
-{
-  mInTransaction = true;
-#ifdef DEBUG
-  mMaybeInvalidTree = false;
-#endif
-
-#ifdef MOZ_LAYERS_HAVE_LOG
-  MOZ_LAYERS_LOG(("[----- BeginTransaction"));
-  Log();
-#endif
-
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return;
-  }
-
-  mTarget = aTarget;
-}
-
-bool
-LayerManagerOGL::EndEmptyTransaction(EndTransactionFlags aFlags)
-{
-  // NB: this makes the somewhat bogus assumption that pure
-  // compositing txns don't call BeginTransaction(), because that's
-  // the behavior of CompositorParent.
-  MOZ_ASSERT(!mMaybeInvalidTree);
-  mInTransaction = false;
-
-  if (!mRoot)
-    return false;
-
-  EndTransaction(nullptr, nullptr, aFlags);
-  return true;
-}
-
-void
-LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
-                                void* aCallbackData,
-                                EndTransactionFlags aFlags)
-{
-  mInTransaction = false;
-
-#ifdef MOZ_LAYERS_HAVE_LOG
-  MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
-  Log();
-#endif
-
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return;
-  }
-
-  if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
-    if (aFlags & END_NO_COMPOSITE) {
-      // Apply pending tree updates before recomputing effective
-      // properties.
-      mRoot->ApplyPendingUpdatesToSubtree();
-    }
-
-    // The results of our drawing always go directly into a pixel buffer,
-    // so we don't need to pass any global transform here.
-    mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
-
-    mThebesLayerCallback = aCallback;
-    mThebesLayerCallbackData = aCallbackData;
-    SetCompositingDisabled(aFlags & END_NO_COMPOSITE);
-
-    bool needGLRender = true;
-    if (mComposer2D && mComposer2D->TryRender(mRoot, mWorldMatrix)) {
-      needGLRender = false;
-
-      if (sDrawFPS) {
-        if (!mFPS) {
-          mFPS = new FPSState();
-        }
-        double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());
-        printf_stderr("HWComposer: FPS is %g\n", fps);
-      }
-
-      // This lets us reftest and screenshot content rendered by the
-      // 2d composer.
-      if (mTarget) {
-        MakeCurrent();
-        CopyToTarget(mTarget);
-        mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-      }
-
-      MOZ_ASSERT(!needGLRender);
-    }
-    if (needGLRender) {
-      Render();
-    }
-
-    mThebesLayerCallback = nullptr;
-    mThebesLayerCallbackData = nullptr;
-  }
-
-  mTarget = nullptr;
-
-#ifdef MOZ_LAYERS_HAVE_LOG
-  Log();
-  MOZ_LAYERS_LOG(("]----- EndTransaction"));
-#endif
-}
-
-already_AddRefed<gfxASurface>
-LayerManagerOGL::CreateOptimalMaskSurface(const gfxIntSize &aSize)
-{
-  return gfxPlatform::GetPlatform()->
-    CreateOffscreenImageSurface(aSize, GFX_CONTENT_ALPHA);
-}
-
-already_AddRefed<ThebesLayer>
-LayerManagerOGL::CreateThebesLayer()
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-
-  nsRefPtr<ThebesLayer> layer = new ThebesLayerOGL(this);
-  return layer.forget();
-}
-
-already_AddRefed<ContainerLayer>
-LayerManagerOGL::CreateContainerLayer()
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-
-  nsRefPtr<ContainerLayer> layer = new ContainerLayerOGL(this);
-  return layer.forget();
-}
-
-already_AddRefed<ImageLayer>
-LayerManagerOGL::CreateImageLayer()
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-
-  nsRefPtr<ImageLayer> layer = new ImageLayerOGL(this);
-  return layer.forget();
-}
-
-already_AddRefed<ColorLayer>
-LayerManagerOGL::CreateColorLayer()
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-
-  nsRefPtr<ColorLayer> layer = new ColorLayerOGL(this);
-  return layer.forget();
-}
-
-already_AddRefed<CanvasLayer>
-LayerManagerOGL::CreateCanvasLayer()
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-
-  nsRefPtr<CanvasLayer> layer = new CanvasLayerOGL(this);
-  return layer.forget();
-}
-
-static LayerOGL*
-ToLayerOGL(Layer* aLayer)
-{
-  return static_cast<LayerOGL*>(aLayer->ImplData());
-}
-
-static void ClearSubtree(Layer* aLayer)
-{
-  ToLayerOGL(aLayer)->CleanupResources();
-  for (Layer* child = aLayer->GetFirstChild(); child;
-       child = child->GetNextSibling()) {
-    ClearSubtree(child);
-  }
-}
-
-void
-LayerManagerOGL::ClearCachedResources(Layer* aSubtree)
-{
-  MOZ_ASSERT(!aSubtree || aSubtree->Manager() == this);
-  Layer* subtree = aSubtree ? aSubtree : mRoot.get();
-  if (!subtree) {
-    return;
-  }
-
-  ClearSubtree(subtree);
-#ifdef DEBUG
-  // If this subtree is reachable from the root layer, then it's
-  // possibly onscreen, and the resource clear means that composites
-  // until the next received transaction may draw garbage to the
-  // framebuffer.
-  for(; subtree && subtree != mRoot; subtree = subtree->GetParent());
-  mMaybeInvalidTree = (subtree == mRoot);
-#endif  // DEBUG
-}
-
-LayerOGL*
-LayerManagerOGL::RootLayer() const
-{
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-
-  return ToLayerOGL(mRoot);
-}
-
-bool LayerManagerOGL::sDrawFPS = false;
-
-// |aTexCoordRect| is the rectangle from the texture that we want to
-// draw using the given program.  The program already has a necessary
-// offset and scale, so the geometry that needs to be drawn is a unit
-// square from 0,0 to 1,1.
-//
-// |aTexSize| is the actual size of the texture, as it can be larger
-// than the rectangle given by |aTexCoordRect|.
-void 
-LayerManagerOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
-                                                const nsIntRect& aTexCoordRect,
-                                                const nsIntSize& aTexSize,
-                                                GLenum aWrapMode /* = LOCAL_GL_REPEAT */,
-                                                bool aFlipped /* = false */)
-{
-  NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
-  GLuint vertAttribIndex =
-    aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
-  GLuint texCoordAttribIndex =
-    aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
-  NS_ASSERTION(texCoordAttribIndex != GLuint(-1), "no texture coords?");
-
-  // clear any bound VBO so that glVertexAttribPointer() goes back to
-  // "pointer mode"
-  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-
-  // Given what we know about these textures and coordinates, we can
-  // compute fmod(t, 1.0f) to get the same texture coordinate out.  If
-  // the texCoordRect dimension is < 0 or > width/height, then we have
-  // wraparound that we need to deal with by drawing multiple quads,
-  // because we can't rely on full non-power-of-two texture support
-  // (which is required for the REPEAT wrap mode).
-
-  GLContext::RectTriangles rects;
-
-  nsIntSize realTexSize = aTexSize;
-  if (!mGLContext->CanUploadNonPowerOfTwo()) {
-    realTexSize = nsIntSize(NextPowerOfTwo(aTexSize.width),
-                            NextPowerOfTwo(aTexSize.height));
-  }
-
-  if (aWrapMode == LOCAL_GL_REPEAT) {
-    rects.addRect(/* dest rectangle */
-                  0.0f, 0.0f, 1.0f, 1.0f,
-                  /* tex coords */
-                  aTexCoordRect.x / GLfloat(realTexSize.width),
-                  aTexCoordRect.y / GLfloat(realTexSize.height),
-                  aTexCoordRect.XMost() / GLfloat(realTexSize.width),
-                  aTexCoordRect.YMost() / GLfloat(realTexSize.height),
-                  aFlipped);
-  } else {
-    GLContext::DecomposeIntoNoRepeatTriangles(aTexCoordRect, realTexSize,
-                                              rects, aFlipped);
-  }
-
-  mGLContext->fVertexAttribPointer(vertAttribIndex, 2,
-                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                   rects.vertexPointer());
-
-  mGLContext->fVertexAttribPointer(texCoordAttribIndex, 2,
-                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                   rects.texCoordPointer());
-
-  {
-    mGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
-    {
-      mGLContext->fEnableVertexAttribArray(vertAttribIndex);
-
-      mGLContext->fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
-
-      mGLContext->fDisableVertexAttribArray(vertAttribIndex);
-    }
-    mGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
-  }
-}
-
-void
-LayerManagerOGL::Render()
-{
-  PROFILER_LABEL("LayerManagerOGL", "Render");
-  if (mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return;
-  }
-
-  nsIntRect rect;
-  if (mIsRenderingToEGLSurface) {
-    rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
-  } else {
-    rect = mRenderBounds;
-    // If render bounds is not updated explicitly, try to infer it from widget
-    if (rect.width == 0 || rect.height == 0) {
-      // FIXME/bug XXXXXX this races with rotation changes on the main
-      // thread, and undoes all the care we take with layers txns being
-      // sent atomically with rotation changes
-      mWidget->GetClientBounds(rect);
-      rect.x = rect.y = 0;
-    }
-  }
-  WorldTransformRect(rect);
-
-  GLint width = rect.width;
-  GLint height = rect.height;
-
-  // We can't draw anything to something with no area
-  // so just return
-  if (width == 0 || height == 0)
-    return;
-
-  // If the widget size changed, we have to force a MakeCurrent
-  // to make sure that GL sees the updated widget size.
-  if (mWidgetSize.width != width ||
-      mWidgetSize.height != height)
-  {
-    MakeCurrent(true);
-
-    mWidgetSize.width = width;
-    mWidgetSize.height = height;
-  } else {
-    MakeCurrent();
-  }
-
-#if MOZ_WIDGET_ANDROID
-  TexturePoolOGL::Fill(gl());
-#endif
-
-  SetupBackBuffer(width, height);
-  SetupPipeline(width, height, ApplyWorldTransform);
-
-  // Default blend function implements "OVER"
-  mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
-                                 LOCAL_GL_ONE, LOCAL_GL_ONE);
-  mGLContext->fEnable(LOCAL_GL_BLEND);
-
-  const nsIntRect *clipRect = mRoot->GetClipRect();
-
-  if (clipRect) {
-    nsIntRect r = *clipRect;
-    WorldTransformRect(r);
-    mGLContext->fScissor(r.x, r.y, r.width, r.height);
-  } else {
-    mGLContext->fScissor(0, 0, width, height);
-  }
-
-  if (CompositingDisabled()) {
-    RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
-                             nsIntPoint(0, 0));
-    mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-    return;
-  }
-
-  mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
-
-  // If the Android compositor is being used, this clear will be done in
-  // DrawWindowUnderlay. Make sure the bits used here match up with those used
-  // in mobile/android/base/gfx/LayerRenderer.java
-#ifndef MOZ_ANDROID_OMTC
-  mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
-  mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
-#endif
-
-  // Allow widget to render a custom background.
-  mWidget->PrepareWindowEffects();
-  mWidget->DrawWindowUnderlay(this, rect);
-
-  // Reset some state that might of been clobbered by the underlay.
-  mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
-                                 LOCAL_GL_ONE, LOCAL_GL_ONE);
-
-  // Render our layers.
-  RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
-                           nsIntPoint(0, 0));
-
-  // Allow widget to render a custom foreground too.
-  mWidget->DrawWindowOverlay(this, rect);
-
-#ifdef MOZ_DUMP_PAINTING
-  if (gfxUtils::sDumpPainting) {
-    nsIntRect rect;
-    if (mIsRenderingToEGLSurface) {
-      rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
-    } else {
-      mWidget->GetClientBounds(rect);
-    }
-    nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(rect.Size(), GFX_CONTENT_COLOR_ALPHA);
-    nsRefPtr<gfxContext> ctx = new gfxContext(surf);
-    CopyToTarget(ctx);
-
-    WriteSnapshotToDumpFile(this, surf);
-  }
-#endif
-
-  if (mTarget) {
-    CopyToTarget(mTarget);
-    mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-    return;
-  }
-
-  if (sDrawFPS && !mFPS) {
-    mFPS = new FPSState();
-  } else if (!sDrawFPS && mFPS) {
-    mFPS = nullptr;
-  }
-
-  if (mFPS) {
-    mFPS->DrawFPS(TimeStamp::Now(), 0, mGLContext, GetProgram(Copy2DProgramType));
-  }
-
-  if (mGLContext->IsDoubleBuffered()) {
-    mGLContext->SwapBuffers();
-    LayerManager::PostPresent();
-    mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-    return;
-  }
-
-  mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-
-  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
-
-  ShaderProgramOGL *copyprog = GetProgram(Copy2DProgramType);
-
-  if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) {
-    copyprog = GetProgram(Copy2DRectProgramType);
-  }
-
-  mGLContext->fBindTexture(mFBOTextureTarget, mBackBufferTexture);
-
-  copyprog->Activate();
-  copyprog->SetTextureUnit(0);
-
-  if (copyprog->GetTexCoordMultiplierUniformLocation() != -1) {
-    copyprog->SetTexCoordMultiplier(width, height);
-  }
-
-  // we're going to use client-side vertex arrays for this.
-  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-
-  // "COPY"
-  mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ZERO,
-                                 LOCAL_GL_ONE, LOCAL_GL_ZERO);
-
-  // enable our vertex attribs; we'll call glVertexPointer below
-  // to fill with the correct data.
-  GLint vcattr = copyprog->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
-  GLint tcattr = copyprog->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
-
-  mGLContext->fEnableVertexAttribArray(vcattr);
-  mGLContext->fEnableVertexAttribArray(tcattr);
-
-  const nsIntRect *r;
-  nsIntRegionRectIterator iter(mClippingRegion);
-
-  while ((r = iter.Next()) != nullptr) {
-    nsIntRect cRect = *r; r = &cRect;
-    WorldTransformRect(cRect);
-    float left = (GLfloat)r->x / width;
-    float right = (GLfloat)r->XMost() / width;
-    float top = (GLfloat)r->y / height;
-    float bottom = (GLfloat)r->YMost() / height;
-
-    float vertices[] = { left * 2.0f - 1.0f,
-                         -(top * 2.0f - 1.0f),
-                         right * 2.0f - 1.0f,
-                         -(top * 2.0f - 1.0f),
-                         left * 2.0f - 1.0f,
-                         -(bottom * 2.0f - 1.0f),
-                         right * 2.0f - 1.0f,
-                         -(bottom * 2.0f - 1.0f) };
-
-    // Use inverted texture coordinates since our projection matrix also has a
-    // flip and we need to cancel that out.
-    float coords[] = { left, 1 - top,
-                       right, 1 - top,
-                       left, 1 - bottom,
-                       right, 1 - bottom };
-
-    mGLContext->fVertexAttribPointer(vcattr,
-                                     2, LOCAL_GL_FLOAT,
-                                     LOCAL_GL_FALSE,
-                                     0, vertices);
-
-    mGLContext->fVertexAttribPointer(tcattr,
-                                     2, LOCAL_GL_FLOAT,
-                                     LOCAL_GL_FALSE,
-                                     0, coords);
-
-    mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
-  }
-
-  mGLContext->fDisableVertexAttribArray(vcattr);
-  mGLContext->fDisableVertexAttribArray(tcattr);
-
-  mGLContext->fFlush();
-  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-}
-
-void
-LayerManagerOGL::SetWorldTransform(const gfxMatrix& aMatrix)
-{
-  NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
-               "SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
-  NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
-               "SetWorldTransform only accepts matrices with integer scale");
-
-  mWorldMatrix = aMatrix;
-}
-
-gfxMatrix&
-LayerManagerOGL::GetWorldTransform(void)
-{
-  return mWorldMatrix;
-}
-
-void
-LayerManagerOGL::WorldTransformRect(nsIntRect& aRect)
-{
-  gfxRect grect(aRect.x, aRect.y, aRect.width, aRect.height);
-  grect = mWorldMatrix.TransformBounds(grect);
-  aRect.SetRect(grect.X(), grect.Y(), grect.Width(), grect.Height());
-}
-
-void
-LayerManagerOGL::UpdateRenderBounds(const nsIntRect& aRect)
-{
-  mRenderBounds = aRect;
-}
-
-void
-LayerManagerOGL::SetSurfaceSize(int width, int height)
-{
-  mSurfaceSize.width = width;
-  mSurfaceSize.height = height;
-}
-
-void
-LayerManagerOGL::SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy)
-{
-  // Set the viewport correctly. 
-  mGLContext->fViewport(0, 0, aWidth, aHeight);
-
-  // We flip the view matrix around so that everything is right-side up; we're
-  // drawing directly into the window's back buffer, so this keeps things
-  // looking correct.
-  //
-  // XXX: We keep track of whether the window size changed, so we could skip
-  // this update if it hadn't changed since the last call. We will need to
-  // track changes to aTransformPolicy and mWorldMatrix for this to work
-  // though.
-
-  // Matrix to transform (0, 0, aWidth, aHeight) to viewport space (-1.0, 1.0,
-  // 2, 2) and flip the contents.
-  gfxMatrix viewMatrix; 
-  viewMatrix.Translate(-gfxPoint(1.0, -1.0));
-  viewMatrix.Scale(2.0f / float(aWidth), 2.0f / float(aHeight));
-  viewMatrix.Scale(1.0f, -1.0f);
-
-  if (aTransformPolicy == ApplyWorldTransform) {
-    viewMatrix = mWorldMatrix * viewMatrix;
-  }
-
-  gfx3DMatrix matrix3d = gfx3DMatrix::From2D(viewMatrix);
-  matrix3d._33 = 0.0f;
-
-  SetLayerProgramProjectionMatrix(matrix3d);
-}
-
-void
-LayerManagerOGL::SetupBackBuffer(int aWidth, int aHeight)
-{
-  if (mGLContext->IsDoubleBuffered()) {
-    mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-    return;
-  }
-
-  // Do we have a FBO of the right size already?
-  if (mBackBufferSize.width == aWidth &&
-      mBackBufferSize.height == aHeight)
-  {
-    mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackBufferFBO);
-    return;
-  }
-
-  // we already have a FBO, but we need to resize its texture.
-  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
-  mGLContext->fBindTexture(mFBOTextureTarget, mBackBufferTexture);
-  mGLContext->fTexImage2D(mFBOTextureTarget,
-                          0,
-                          LOCAL_GL_RGBA,
-                          aWidth, aHeight,
-                          0,
-                          LOCAL_GL_RGBA,
-                          LOCAL_GL_UNSIGNED_BYTE,
-                          nullptr);
-  mGLContext->fBindTexture(mFBOTextureTarget, 0);
-
-  mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackBufferFBO);
-  mGLContext->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
-                                    LOCAL_GL_COLOR_ATTACHMENT0,
-                                    mFBOTextureTarget,
-                                    mBackBufferTexture,
-                                    0);
-
-  GLenum result = mGLContext->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-  if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
-    nsAutoCString msg;
-    msg.Append("Framebuffer not complete -- error 0x");
-    msg.AppendInt(result, 16);
-    NS_RUNTIMEABORT(msg.get());
-  }
-
-  mBackBufferSize.width = aWidth;
-  mBackBufferSize.height = aHeight;
-}
-
-void
-LayerManagerOGL::CopyToTarget(gfxContext *aTarget)
-{
-  nsIntRect rect;
-  if (mIsRenderingToEGLSurface) {
-    rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
-  } else {
-    rect = nsIntRect(0, 0, mWidgetSize.width, mWidgetSize.height);
-  }
-  GLint width = rect.width;
-  GLint height = rect.height;
-
-  if ((int64_t(width) * int64_t(height) * int64_t(4)) > INT32_MAX) {
-    NS_ERROR("Widget size too big - integer overflow!");
-    return;
-  }
-
-  nsRefPtr<gfxImageSurface> imageSurface =
-    new gfxImageSurface(gfxIntSize(width, height),
-                        gfxImageFormatARGB32);
-
-  mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER,
-                               mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO);
-
-  if (!mGLContext->IsGLES2()) {
-    // GLES2 promises that binding to any custom FBO will attach
-    // to GL_COLOR_ATTACHMENT0 attachment point.
-    if (mGLContext->IsDoubleBuffered()) {
-      mGLContext->fReadBuffer(LOCAL_GL_BACK);
-    }
-    else {
-      mGLContext->fReadBuffer(LOCAL_GL_COLOR_ATTACHMENT0);
-    }
-  }
-
-  NS_ASSERTION(imageSurface->Stride() == width * 4,
-               "Image Surfaces being created with weird stride!");
-
-  mGLContext->ReadPixelsIntoImageSurface(imageSurface);
-
-  // Map from GL space to Cairo space and reverse the world transform.
-  gfxMatrix glToCairoTransform = mWorldMatrix;
-  glToCairoTransform.Invert();
-  glToCairoTransform.Scale(1.0, -1.0);
-  glToCairoTransform.Translate(-gfxPoint(0.0, height));
-
-  gfxContextAutoSaveRestore restore(aTarget);
-  aTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
-  aTarget->SetMatrix(glToCairoTransform);
-  aTarget->SetSource(imageSurface);
-  aTarget->Paint();
-}
-
-void
-LayerManagerOGL::SetLayerProgramProjectionMatrix(const gfx3DMatrix& aMatrix)
-{
-  for (unsigned int i = 0; i < mPrograms.Length(); ++i) {
-    for (uint32_t mask = MaskNone; mask < NumMaskTypes; ++mask) {
-      if (mPrograms[i].mVariations[mask]) {
-        mPrograms[i].mVariations[mask]->CheckAndSetProjectionMatrix(aMatrix);
-      }
-    }
-  }
-}
-
-static GLenum
-LayerManagerOGL_GetFrameBufferInternalFormat(GLContext* gl,
-                             GLuint aCurrentFrameBuffer,
-                             nsIWidget* aWidget)
-{
-  if (aCurrentFrameBuffer == 0) { // default framebuffer
-    return aWidget->GetGLFrameBufferFormat();
-  }
-  return LOCAL_GL_RGBA;
-}
-
-bool
-LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
-                                      GLuint aCurrentFrameBuffer,
-                                      GLuint *aFBO, GLuint *aTexture)
-{
-  GLuint tex, fbo;
-
-  mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
-  mGLContext->fGenTextures(1, &tex);
-  mGLContext->fBindTexture(mFBOTextureTarget, tex);
-
-  if (aInit == InitModeCopy) {
-    // We're going to create an RGBA temporary fbo.  But to
-    // CopyTexImage() from the current framebuffer, the framebuffer's
-    // format has to be compatible with the new texture's.  So we
-    // check the format of the framebuffer here and take a slow path
-    // if it's incompatible.
-    GLenum format =
-      LayerManagerOGL_GetFrameBufferInternalFormat(gl(), aCurrentFrameBuffer, mWidget);
- 
-    bool isFormatCompatibleWithRGBA
-        = gl()->IsGLES2() ? (format == LOCAL_GL_RGBA)
-                          : true;
-
-    if (isFormatCompatibleWithRGBA) {
-      mGLContext->fCopyTexImage2D(mFBOTextureTarget,
-                                  0,
-                                  LOCAL_GL_RGBA,
-                                  aRect.x, aRect.y,
-                                  aRect.width, aRect.height,
-                                  0);
-    } else {
-      // Curses, incompatible formats.  Take a slow path.
-
-      // RGBA
-      size_t bufferSize = aRect.width * aRect.height * 4;
-      nsAutoArrayPtr<uint8_t> buf(new uint8_t[bufferSize]);
-
-      mGLContext->fReadPixels(aRect.x, aRect.y,
-                              aRect.width, aRect.height,
-                              LOCAL_GL_RGBA,
-                              LOCAL_GL_UNSIGNED_BYTE,
-                              buf);
-      mGLContext->fTexImage2D(mFBOTextureTarget,
-                              0,
-                              LOCAL_GL_RGBA,
-                              aRect.width, aRect.height,
-                              0,
-                              LOCAL_GL_RGBA,
-                              LOCAL_GL_UNSIGNED_BYTE,
-                              buf);
-    }
-  } else {
-    mGLContext->fTexImage2D(mFBOTextureTarget,
-                            0,
-                            LOCAL_GL_RGBA,
-                            aRect.width, aRect.height,
-                            0,
-                            LOCAL_GL_RGBA,
-                            LOCAL_GL_UNSIGNED_BYTE,
-                            nullptr);
-  }
-  mGLContext->fTexParameteri(mFBOTextureTarget, LOCAL_GL_TEXTURE_MIN_FILTER,
-                             LOCAL_GL_LINEAR);
-  mGLContext->fTexParameteri(mFBOTextureTarget, LOCAL_GL_TEXTURE_MAG_FILTER,
-                             LOCAL_GL_LINEAR);
-  mGLContext->fTexParameteri(mFBOTextureTarget, LOCAL_GL_TEXTURE_WRAP_S, 
-                             LOCAL_GL_CLAMP_TO_EDGE);
-  mGLContext->fTexParameteri(mFBOTextureTarget, LOCAL_GL_TEXTURE_WRAP_T, 
-                             LOCAL_GL_CLAMP_TO_EDGE);
-  mGLContext->fBindTexture(mFBOTextureTarget, 0);
-
-  mGLContext->fGenFramebuffers(1, &fbo);
-  mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fbo);
-  mGLContext->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
-                                    LOCAL_GL_COLOR_ATTACHMENT0,
-                                    mFBOTextureTarget,
-                                    tex,
-                                    0);
-
-  // Making this call to fCheckFramebufferStatus prevents a crash on
-  // PowerVR. See bug 695246.
-  GLenum result = mGLContext->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-  if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
-    nsAutoCString msg;
-    msg.Append("Framebuffer not complete -- error 0x");
-    msg.AppendInt(result, 16);
-    msg.Append(", mFBOTextureTarget 0x");
-    msg.AppendInt(mFBOTextureTarget, 16);
-    msg.Append(", aRect.width ");
-    msg.AppendInt(aRect.width);
-    msg.Append(", aRect.height ");
-    msg.AppendInt(aRect.height);
-    NS_WARNING(msg.get());
-
-    mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-    mGLContext->fDeleteFramebuffers(1, &fbo);
-    mGLContext->fDeleteTextures(1, &tex);
-    return false;
-  }
-
-  SetupPipeline(aRect.width, aRect.height, DontApplyWorldTransform);
-  mGLContext->fScissor(0, 0, aRect.width, aRect.height);
-
-  if (aInit == InitModeClear) {
-    mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
-    mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
-  }
-
-  *aFBO = fbo;
-  *aTexture = tex;
-  return true;
-}
-
-TemporaryRef<DrawTarget>
-LayerManagerOGL::CreateDrawTarget(const IntSize &aSize,
-                                  SurfaceFormat aFormat)
-{
-#ifdef XP_MACOSX
-  // We don't want to accelerate if the surface is too small which indicates
-  // that it's likely used for an icon/static image. We also don't want to
-  // accelerate anything that is above the maximum texture size of weakest gpu.
-  // Safari uses 5000 area as the minimum for acceleration, we decided 64^2 is more logical.
-  bool useAcceleration = aSize.width <= 4096 && aSize.height <= 4096 &&
-                         aSize.width > 64 && aSize.height > 64 &&
-                         gfxPlatformMac::GetPlatform()->UseAcceleratedCanvas();
-  if (useAcceleration) {
-    return Factory::CreateDrawTarget(BACKEND_COREGRAPHICS_ACCELERATED,
-                                     aSize, aFormat);
-  }
-#endif
-  return LayerManager::CreateDrawTarget(aSize, aFormat);
-}
-
-} /* layers */
-} /* mozilla */
deleted file mode 100644
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ /dev/null
@@ -1,494 +0,0 @@
-/* -*- 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 GFX_LAYERMANAGEROGL_H
-#define GFX_LAYERMANAGEROGL_H
-
-#include <sys/types.h>                  // for int32_t
-#include "GLDefs.h"                     // for GLuint, GLenum, GLintptr, etc
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL, etc
-#include "Layers.h"
-#include "gfxMatrix.h"                  // for gfxMatrix
-#include "gfxPoint.h"                   // for gfxIntSize
-#include "mozilla/Attributes.h"         // for MOZ_OVERRIDE, MOZ_FINAL
-#include "mozilla/RefPtr.h"             // for TemporaryRef
-#include "mozilla/gfx/BaseSize.h"       // for BaseSize
-#include "mozilla/gfx/Point.h"          // for IntSize
-#include "mozilla/gfx/Types.h"          // for SurfaceFormat, etc
-#include "mozilla/layers/CompositorTypes.h"  // for MaskType::MaskNone, etc
-#include "mozilla/layers/LayersTypes.h"  // for LayersBackend, etc
-#include "nsAString.h"
-#include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoPtr
-#include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING
-#include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
-#include "nsRegion.h"                   // for nsIntRegion
-#include "nsSize.h"                     // for nsIntSize
-#include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
-#include "nsThreadUtils.h"              // for nsRunnable
-#include "nscore.h"                     // for NS_IMETHOD, nsAString, etc
-#ifdef XP_WIN
-#include <windows.h>
-#endif
-
-#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
-
-class gfx3DMatrix;
-class gfxASurface;
-class gfxContext;
-class nsIWidget;
-struct nsIntPoint;
-
-namespace mozilla {
-namespace gl {
-class GLContext;
-}
-namespace gfx {
-class DrawTarget;
-}
-namespace layers {
-
-class Composer2D;
-class ImageLayer;
-class LayerOGL;
-class ThebesLayerComposite;
-class ContainerLayerComposite;
-class ImageLayerComposite;
-class CanvasLayerComposite;
-class ColorLayerComposite;
-struct FPSState;
-
-/**
- * This is the LayerManager used for OpenGL 2.1 and OpenGL ES 2.0.
- * This should be used only on the main thread.
- */
-class LayerManagerOGL : public LayerManager
-{
-  typedef mozilla::gl::GLContext GLContext;
-
-public:
-  LayerManagerOGL(nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1,
-                  bool aIsRenderingToEGLSurface = false);
-  virtual ~LayerManagerOGL();
-
-  void Destroy();
-
-  /**
-   * Initializes the layer manager with a given GLContext. If aContext is null
-   * then the layer manager will try to create one for the associated widget.
-   *
-   * \return True is initialization was succesful, false when it was not.
-   */
-  bool Initialize(bool force = false);
-
-  /**
-   * Sets the clipping region for this layer manager. This is important on 
-   * windows because using OGL we no longer have GDI's native clipping. Therefor
-   * widget must tell us what part of the screen is being invalidated,
-   * and we should clip to this.
-   *
-   * \param aClippingRegion Region to clip to. Setting an empty region
-   * will disable clipping.
-   */
-  void SetClippingRegion(const nsIntRegion& aClippingRegion);
-
-  /**
-   * LayerManager implementation.
-   */
-  void BeginTransaction();
-
-  void BeginTransactionWithTarget(gfxContext* aTarget);
-
-  void EndConstruction();
-
-  virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
-  virtual void EndTransaction(DrawThebesLayerCallback aCallback,
-                              void* aCallbackData,
-                              EndTransactionFlags aFlags = END_DEFAULT);
-
-  virtual void SetRoot(Layer* aLayer) { mRoot = aLayer; }
-
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) {
-    if (!mGLContext)
-      return false;
-    int32_t maxSize = GetMaxTextureSize();
-    return aSize <= gfxIntSize(maxSize, maxSize);
-  }
-
-  virtual int32_t GetMaxTextureSize() const;
-
-  virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
-
-  virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
-
-  virtual already_AddRefed<ImageLayer> CreateImageLayer();
-
-  virtual already_AddRefed<ColorLayer> CreateColorLayer();
-
-  virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
-
-  virtual LayersBackend GetBackendType() { return LAYERS_OPENGL; }
-  virtual void GetBackendName(nsAString& name) { name.AssignLiteral("OpenGL"); }
-
-  virtual already_AddRefed<gfxASurface>
-    CreateOptimalMaskSurface(const gfxIntSize &aSize);
-
-  virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
-
-  /**
-   * Helper methods.
-   */
-  void MakeCurrent(bool aForce = false);
-
-  ShaderProgramOGL* GetBasicLayerProgram(bool aOpaque, bool aIsRGB,
-                                         MaskType aMask = MaskNone)
-  {
-    ShaderProgramType format = BGRALayerProgramType;
-    if (aIsRGB) {
-      if (aOpaque) {
-        format = RGBXLayerProgramType;
-      } else {
-        format = RGBALayerProgramType;
-      }
-    } else {
-      if (aOpaque) {
-        format = BGRXLayerProgramType;
-      }
-    }
-    return GetProgram(format, aMask);
-  }
-
-  ShaderProgramOGL* GetProgram(ShaderProgramType aType,
-                               Layer* aMaskLayer) {
-    if (aMaskLayer)
-      return GetProgram(aType, Mask2d);
-    return GetProgram(aType, MaskNone);
-  }
-
-  ShaderProgramOGL* GetProgram(ShaderProgramType aType,
-                               MaskType aMask = MaskNone) {
-    NS_ASSERTION(ProgramProfileOGL::ProgramExists(aType, aMask),
-                 "Invalid program type.");
-    return mPrograms[aType].mVariations[aMask];
-  }
-
-  ShaderProgramOGL* GetFBOLayerProgram(MaskType aMask = MaskNone) {
-    return GetProgram(GetFBOLayerProgramType(), aMask);
-  }
-
-  ShaderProgramType GetFBOLayerProgramType() {
-    if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB)
-      return RGBARectLayerProgramType;
-    return RGBALayerProgramType;
-  }
-
-  gfx::SurfaceFormat GetFBOTextureFormat() {
-    return gfx::FORMAT_R8G8B8A8;
-  }
-
-  GLContext* gl() const { return mGLContext; }
-
-  // |NSOpenGLContext*|:
-  void* GetNSOpenGLContext() const;
-
-  DrawThebesLayerCallback GetThebesLayerCallback() const
-  { return mThebesLayerCallback; }
-
-  void* GetThebesLayerCallbackData() const
-  { return mThebesLayerCallbackData; }
-
-  GLenum FBOTextureTarget() { return mFBOTextureTarget; }
-
-  /**
-   * Controls how to initialize the texture / FBO created by
-   * CreateFBOWithTexture.
-   *  - InitModeNone: No initialization, contents are undefined.
-   *  - InitModeClear: Clears the FBO.
-   *  - InitModeCopy: Copies the contents of the current glReadBuffer into the
-   *    texture.
-   */
-  enum InitMode {
-    InitModeNone,
-    InitModeClear,
-    InitModeCopy
-  };
-
-  /* Create a FBO backed by a texture; will leave the FBO
-   * bound.  Note that the texture target type will be
-   * of the type returned by FBOTextureTarget; different
-   * shaders are required to sample from the different
-   * texture types.
-   */
-  bool CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
-                            GLuint aCurrentFrameBuffer,
-                            GLuint *aFBO, GLuint *aTexture);
-
-  GLuint QuadVBO() { return mQuadVBO; }
-  GLintptr QuadVBOVertexOffset() { return 0; }
-  GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; }
-  GLintptr QuadVBOFlippedTexCoordOffset() { return sizeof(float)*8*2; }
-
-  void BindQuadVBO();
-  void QuadVBOVerticesAttrib(GLuint aAttribIndex);
-  void QuadVBOTexCoordsAttrib(GLuint aAttribIndex);
-  void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex);
-
-  // Super common
-
-  void BindAndDrawQuad(GLuint aVertAttribIndex,
-                       GLuint aTexCoordAttribIndex,
-                       bool aFlipped = false);
-
-  void BindAndDrawQuad(ShaderProgramOGL *aProg,
-                       bool aFlipped = false)
-  {
-    NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
-    BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib),
-                    aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib),
-                    aFlipped);
-  }
-
-  // |aTexCoordRect| is the rectangle from the texture that we want to
-  // draw using the given program.  The program already has a necessary
-  // offset and scale, so the geometry that needs to be drawn is a unit
-  // square from 0,0 to 1,1.
-  //
-  // |aTexSize| is the actual size of the texture, as it can be larger
-  // than the rectangle given by |aTexCoordRect|.
-  void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
-                                      const nsIntRect& aTexCoordRect,
-                                      const nsIntSize& aTexSize,
-                                      GLenum aWrapMode = LOCAL_GL_REPEAT,
-                                      bool aFlipped = false);
-
-  virtual const char* Name() const { return "OGL"; }
-
-  const nsIntSize& GetWidgetSize() {
-    return mWidgetSize;
-  }
-
-  enum WorldTransforPolicy {
-    ApplyWorldTransform,
-    DontApplyWorldTransform
-  };
-
-  /**
-   * Setup the viewport and projection matrix for rendering
-   * to a window of the given dimensions.
-   */
-  void SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy);
-
-  /**
-   * Setup World transform matrix.
-   * Transform will be ignored if it is not PreservesAxisAlignedRectangles
-   * or has non integer scale
-   */
-  void SetWorldTransform(const gfxMatrix& aMatrix);
-  gfxMatrix& GetWorldTransform(void);
-  void WorldTransformRect(nsIntRect& aRect);
-
-  void UpdateRenderBounds(const nsIntRect& aRect);
-
-  /**
-   * Set the size of the surface we're rendering to.
-   */
-  void SetSurfaceSize(int width, int height);
- 
-  bool CompositingDisabled() { return mCompositingDisabled; }
-  void SetCompositingDisabled(bool aCompositingDisabled) { mCompositingDisabled = aCompositingDisabled; }
-
-  /**
-   * Creates a DrawTarget which is optimized for inter-operating with this
-   * layermanager.
-   */
-  virtual TemporaryRef<mozilla::gfx::DrawTarget>
-    CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
-                     mozilla::gfx::SurfaceFormat aFormat);
-
-  /**
-   * Calculates the 'completeness' of the rendering that intersected with the
-   * screen on the last render. This is only useful when progressive tile
-   * drawing is enabled, otherwise this will always return 1.0.
-   * This function's expense scales with the size of the layer tree and the
-   * complexity of individual layers' valid regions.
-   */
-  float ComputeRenderIntegrity();
-
-private:
-  /** Widget associated with this layer manager */
-  nsIWidget *mWidget;
-  nsIntSize mWidgetSize;
-
-  /** The size of the surface we are rendering to */
-  nsIntSize mSurfaceSize;
-
-  /** 
-   * Context target, nullptr when drawing directly to our swap chain.
-   */
-  nsRefPtr<gfxContext> mTarget;
-
-  nsRefPtr<GLContext> mGLContext;
-
-  /** Our more efficient but less powerful alter ego, if one is available. */
-  nsRefPtr<Composer2D> mComposer2D;
-
-  already_AddRefed<mozilla::gl::GLContext> CreateContext();
-
-  /** Backbuffer */
-  GLuint mBackBufferFBO;
-  GLuint mBackBufferTexture;
-  nsIntSize mBackBufferSize;
-
-  /** Shader Programs */
-  struct ShaderProgramVariations {
-    ShaderProgramOGL* mVariations[NumMaskTypes];
-  };
-  nsTArray<ShaderProgramVariations> mPrograms;
-
-  /** Texture target to use for FBOs */
-  GLenum mFBOTextureTarget;
-
-  /** VBO that has some basics in it for a textured quad,
-   *  including vertex coords and texcoords for both
-   *  flipped and unflipped textures */
-  GLuint mQuadVBO;
-  
-  /** Region we're clipping our current drawing to. */
-  nsIntRegion mClippingRegion;
-
-  /** Misc */
-  bool mHasBGRA;
-  bool mCompositingDisabled;
-
-  /**
-   * When rendering to an EGL surface (e.g. on Android), we rely on being told
-   * about size changes (via SetSurfaceSize) rather than pulling this information
-   * from the widget, since the widget's information can lag behind.
-   */
-  bool mIsRenderingToEGLSurface;
-
-  /** Helper-class used by Initialize **/
-  class ReadDrawFPSPref MOZ_FINAL : public nsRunnable {
-  public:
-    NS_IMETHOD Run() MOZ_OVERRIDE;
-  };
-
-  /** Current root layer. */
-  LayerOGL *RootLayer() const;
-
-  /**
-   * Render the current layer tree to the active target.
-   */
-  void Render();
-
-  /**
-   * Setup a backbuffer of the given dimensions.
-   */
-  void SetupBackBuffer(int aWidth, int aHeight);
-
-  /**
-   * Copies the content of our backbuffer to the set transaction target.
-   */
-  void CopyToTarget(gfxContext *aTarget);
-
-  /**
-   * Updates all layer programs with a new projection matrix.
-   */
-  void SetLayerProgramProjectionMatrix(const gfx3DMatrix& aMatrix);
-
-  /**
-   * Helper method for Initialize, creates all valid variations of a program
-   * and adds them to mPrograms
-   */
-  void AddPrograms(ShaderProgramType aType);
-
-  /**
-   * Recursive helper method for use by ComputeRenderIntegrity. Subtracts
-   * any incomplete rendering on aLayer from aScreenRegion. Any low-precision
-   * rendering is included in aLowPrecisionScreenRegion. aTransform is the
-   * accumulated transform of intermediate surfaces beneath aLayer.
-   */
-  static void ComputeRenderIntegrityInternal(Layer* aLayer,
-                                             nsIntRegion& aScreenRegion,
-                                             nsIntRegion& aLowPrecisionScreenRegion,
-                                             const gfx3DMatrix& aTransform);
-
-  /* Thebes layer callbacks; valid at the end of a transaciton,
-   * while rendering */
-  DrawThebesLayerCallback mThebesLayerCallback;
-  void *mThebesLayerCallbackData;
-  gfxMatrix mWorldMatrix;
-  nsAutoPtr<FPSState> mFPS;
-  nsIntRect mRenderBounds;
-#ifdef DEBUG
-  // NB: only interesting when this is a purely compositing layer
-  // manager.  True after possibly onscreen layers have had their
-  // cached resources cleared outside of a transaction, and before the
-  // next forwarded transaction that re-validates their buffers.
-  bool mMaybeInvalidTree;
-#endif
-
-  static bool sDrawFPS;
-};
-
-/**
- * General information and tree management for OGL layers.
- */
-class LayerOGL
-{
-public:
-  LayerOGL(LayerManagerOGL *aManager)
-    : mOGLManager(aManager), mDestroyed(false)
-  { }
-
-  virtual ~LayerOGL() { }
-
-  virtual LayerOGL *GetFirstChildOGL() {
-    return nullptr;
-  }
-
-  /* Do NOT call this from the generic LayerOGL destructor.  Only from the
-   * concrete class destructor
-   */
-  virtual void Destroy() = 0;
-
-  virtual Layer* GetLayer() = 0;
-
-  virtual void RenderLayer(int aPreviousFrameBuffer,
-                           const nsIntPoint& aOffset) = 0;
-
-  typedef mozilla::gl::GLContext GLContext;
-
-  LayerManagerOGL* OGLManager() const { return mOGLManager; }
-  GLContext *gl() const { return mOGLManager->gl(); }
-  virtual void CleanupResources() = 0;
-
-  /**
-   * Loads the result of rendering the layer as an OpenGL texture in aTextureUnit.
-   * Will try to use an existing texture if possible, or a temporary
-   * one if not. It is the callee's responsibility to release the texture.
-   * Will return true if a texture could be constructed and loaded, false otherwise.
-   * The texture will not be transformed, i.e., it will be in the same coord
-   * space as this.
-   * Any layer that can be used as a mask layer should override this method.
-   * aSize will contain the size of the image.
-   */
-  virtual bool LoadAsTexture(GLuint aTextureUnit, gfxIntSize* aSize)
-  {
-    NS_WARNING("LoadAsTexture called without being overriden");
-    return false;
-  }
-
-protected:
-  LayerManagerOGL *mOGLManager;
-  bool mDestroyed;
-};
-
-
-} /* layers */
-} /* mozilla */
-
-#endif /* GFX_LAYERMANAGEROGL_H */
rename from gfx/layers/opengl/LayerManagerOGLProgram.cpp
rename to gfx/layers/opengl/OGLShaderProgram.cpp
--- a/gfx/layers/opengl/LayerManagerOGLProgram.cpp
+++ b/gfx/layers/opengl/OGLShaderProgram.cpp
@@ -1,24 +1,23 @@
 /* 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 "LayerManagerOGLProgram.h"
+#include "OGLShaderProgram.h"
 #include <stdint.h>                     // for uint32_t
 #include "gfxMatrix.h"                  // for gfxMatrix
 #include "gfxPoint.h"                   // for gfxIntSize, gfxPoint, etc
 #include "gfxRect.h"                    // for gfxRect
 #include "mozilla/DebugOnly.h"          // for DebugOnly
 #include "nsAString.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsString.h"                   // for nsAutoCString
 #include "prenv.h"                      // for PR_GetEnv
-#include "LayerManagerOGL.h"
-#include "LayerManagerOGLShaders.h"
+#include "OGLShaders.h"
 #include "Layers.h"
 #include "GLContext.h"
 
 struct gfxRGBA;
 
 namespace mozilla {
 namespace layers {
 
@@ -434,50 +433,16 @@ ShaderProgramOGL::CreateProgram(const ch
     mGL->fDeleteProgram(result);
     return false;
   }
 
   mProgram = result;
   return true;
 }
 
-bool
-ShaderProgramOGL::LoadMask(Layer* aMaskLayer)
-{
-  if (!aMaskLayer) {
-    return false;
-  }
-
-  gfxIntSize size;
-  if (!static_cast<LayerOGL*>(aMaskLayer->ImplData())
-        ->LoadAsTexture(LOCAL_GL_TEXTURE0 + mProfile.mTextureCount - 1, &size)){
-    return false;
-  }
-
-  SetUniform(mProfile.LookupUniformLocation("uMaskTexture"),
-              (GLint)(mProfile.mTextureCount - 1));
-
-  gfxMatrix maskTransform;
-  mozilla::DebugOnly<bool> isMask2D =
-    aMaskLayer->GetEffectiveTransform().CanDraw2D(&maskTransform);
-  NS_ASSERTION(isMask2D, "How did we end up with a 3D transform here?!");
-  gfxRect bounds = gfxRect(gfxPoint(), size);
-  bounds = maskTransform.TransformBounds(bounds);
-
-  gfx3DMatrix m;
-  m._11 = 1.0f/bounds.width;
-  m._22 = 1.0f/bounds.height;
-  m._41 = float(-bounds.x)/bounds.width;
-  m._42 = float(-bounds.y)/bounds.height;
-
-  SetMatrixUniform(mProfile.LookupUniformLocation("uMaskQuadTransform"), m);
-
-  return true;
-}
-
 void
 ShaderProgramOGL::Activate()
 {
   if (mProgramState == STATE_NEW) {
     if (!Initialize()) {
       NS_WARNING("Shader could not be initialised");
       return;
     }
rename from gfx/layers/opengl/LayerManagerOGLProgram.h
rename to gfx/layers/opengl/OGLShaderProgram.h
--- a/gfx/layers/opengl/LayerManagerOGLProgram.h
+++ b/gfx/layers/opengl/OGLShaderProgram.h
@@ -1,15 +1,15 @@
 /* -*- 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 GFX_LAYERMANAGEROGLPROGRAM_H
-#define GFX_LAYERMANAGEROGLPROGRAM_H
+#ifndef GFX_OGLSHADERPROGRAM_H
+#define GFX_OGLSHADERPROGRAM_H
 
 #include "GLDefs.h"                     // for GLint, GLenum, GLuint, etc
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
 #include "gfxTypes.h"
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
 #include "mozilla/gfx/Rect.h"           // for Rect
@@ -243,30 +243,16 @@ public:
     return mProfile.LookupAttributeLocation(aName);
   }
 
   GLint GetTexCoordMultiplierUniformLocation() {
     return mTexCoordMultiplierUniformLocation;
   }
 
   /**
-   * aLayer is the mask layer to use for rendering, or null, if there is no
-   * mask layer.
-   * If aLayer is non-null, then the result of rendering aLayer is stored as
-   * as a texture to be used by the shader. It is stored in the next available
-   * texture unit, as determined by the texture unit requirements for the
-   * shader.
-   * Any other features of the mask layer required by the shader are also
-   * loaded to graphics memory. In particular the transform used to move from
-   * the layer's coordinates to the mask's coordinates is loaded; this must be
-   * a 2D transform.
-   */
-  bool LoadMask(Layer* aLayer);
-
-  /**
    * The following set of methods set a uniform argument to the shader program.
    * Not all uniforms may be set for all programs, and such uses will throw
    * an assertion.
    */
   void SetLayerTransform(const gfx3DMatrix& aMatrix) {
     SetMatrixUniform(mProfile.LookupUniformLocation("uLayerTransform"), aMatrix);
   }
 
@@ -415,9 +401,9 @@ protected:
     SetMatrixUniform(aLocation, &aMatrix._11);
   }
 };
 
 
 } /* layers */
 } /* mozilla */
 
-#endif /* GFX_LAYERMANAGEROGLPROGRAM_H */
+#endif /* GFX_OGLSHADERPROGRAM_H */
rename from gfx/layers/opengl/LayerManagerOGLShaders.h
rename to gfx/layers/opengl/OGLShaders.h
rename from gfx/layers/opengl/LayerManagerOGLShaders.txt
rename to gfx/layers/opengl/OGLShaders.txt
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -24,17 +24,17 @@
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/TextureHost.h"  // for DeprecatedTextureHost, etc
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_WARNING
 #include "nsISupportsImpl.h"            // for TextureImage::Release, etc
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramType, etc
+#include "OGLShaderProgram.h"           // for ShaderProgramType, etc
 #ifdef MOZ_WIDGET_GONK
 #include <ui/GraphicBuffer.h>
 #endif
 
 class gfxImageSurface;
 class gfxReusableSurfaceWrapper;
 class nsIntRegion;
 struct nsIntPoint;
deleted file mode 100644
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ /dev/null
@@ -1,955 +0,0 @@
-/* -*- 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 "ThebesLayerOGL.h"
-#include <stdint.h>                     // for uint32_t
-#include <sys/types.h>                  // for int32_t
-#include "GLContext.h"                  // for GLContext, etc
-#include "GLContextTypes.h"             // for GLenum
-#include "GLDefs.h"                     // for LOCAL_GL_ONE, LOCAL_GL_BGRA, etc
-#include "GLTextureImage.h"             // for TextureImage, etc
-#include "ThebesLayerBuffer.h"          // for ThebesLayerBuffer, etc
-#include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxASurface.h"                // for gfxASurface, etc
-#include "gfxColor.h"                   // for gfxRGBA
-#include "gfxContext.h"                 // for gfxContext, etc
-#include "gfxImageSurface.h"            // for gfxImageSurface
-#include "gfxPlatform.h"
-#include "gfxPoint.h"                   // for gfxPoint
-#include "gfxTeeSurface.h"              // for gfxTeeSurface
-#include "gfxUtils.h"                   // for gfxUtils, etc
-#include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
-#include "mozilla/Util.h"               // for ArrayLength
-#include "mozilla/gfx/BasePoint.h"      // for BasePoint
-#include "mozilla/gfx/BaseRect.h"       // for BaseRect
-#include "mozilla/gfx/BaseSize.h"       // for BaseSize
-#include "mozilla/gfx/2D.h"             // for DrawTarget, etc
-#include "mozilla/mozalloc.h"           // for operator new
-#include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsDebug.h"                    // for NS_ASSERTION, etc
-#include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
-#include "nsSize.h"                     // for nsIntSize
-#include "LayerManagerOGL.h"            // for LayerManagerOGL, etc
-#include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL, etc
-#include "gfx2DGlue.h"
-
-using namespace mozilla;
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace layers {
-
-using gl::GLContext;
-using gl::TextureImage;
-
-static const int ALLOW_REPEAT = ThebesLayerBuffer::ALLOW_REPEAT;
-
-GLenum
-WrapMode(GLContext *aGl, uint32_t aFlags)
-{
-  if ((aFlags & ALLOW_REPEAT) &&
-      (aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) ||
-       aGl->IsExtensionSupported(GLContext::OES_texture_npot))) {
-    return LOCAL_GL_REPEAT;
-  }
-  return LOCAL_GL_CLAMP_TO_EDGE;
-}
-
-// BindAndDrawQuadWithTextureRect can work with either GL_REPEAT (preferred)
-// or GL_CLAMP_TO_EDGE textures. If ALLOW_REPEAT is set in aFlags, we
-// select based on whether REPEAT is valid for non-power-of-two textures --
-// if we have NPOT support we use it, otherwise we stick with CLAMP_TO_EDGE and
-// decompose.
-// If ALLOW_REPEAT is not set, we always use GL_CLAMP_TO_EDGE.
-static already_AddRefed<TextureImage>
-CreateClampOrRepeatTextureImage(GLContext *aGl,
-                                const nsIntSize& aSize,
-                                TextureImage::ContentType aContentType,
-                                uint32_t aFlags)
-{
-
-  return aGl->CreateTextureImage(aSize, aContentType, WrapMode(aGl, aFlags));
-}
-
-class ThebesLayerBufferOGL
-{
-  NS_INLINE_DECL_REFCOUNTING(ThebesLayerBufferOGL)
-public:
-  typedef TextureImage::ContentType ContentType;
-  typedef ThebesLayerBuffer::PaintState PaintState;
-
-  ThebesLayerBufferOGL(ThebesLayer* aLayer, LayerOGL* aOGLLayer)
-    : mLayer(aLayer)
-    , mOGLLayer(aOGLLayer)
-    , mInitialised(true)
-  {}
-  virtual ~ThebesLayerBufferOGL() {}
-
-  enum { PAINT_WILL_RESAMPLE = ThebesLayerBuffer::PAINT_WILL_RESAMPLE };
-  virtual PaintState BeginPaint(ContentType aContentType,
-                                uint32_t aFlags) = 0;
-
-  void RenderTo(const nsIntPoint& aOffset, LayerManagerOGL* aManager,
-                uint32_t aFlags);
-
-  void EndUpdate();
-
-  nsIntSize GetSize() {
-    if (mTexImage)
-      return ThebesIntSize(mTexImage->GetSize());
-    return nsIntSize(0, 0);
-  }
-
-  bool Initialised() { return mInitialised; }
-
-  virtual nsIntPoint GetOriginOffset() = 0;
-protected:
-
-  GLContext* gl() const { return mOGLLayer->gl(); }
-
-  ThebesLayer* mLayer;
-  LayerOGL* mOGLLayer;
-  nsRefPtr<TextureImage> mTexImage;
-  nsRefPtr<TextureImage> mTexImageOnWhite;
-  bool mInitialised;
-};
-
-void ThebesLayerBufferOGL::EndUpdate()
-{
-  if (mTexImage && mTexImage->InUpdate()) {
-    mTexImage->EndUpdate();
-  }
-
-  if (mTexImageOnWhite && mTexImageOnWhite->InUpdate()) {
-    mTexImageOnWhite->EndUpdate();
-  }
-}
-
-void
-ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
-                               LayerManagerOGL* aManager,
-                               uint32_t aFlags)
-{
-  NS_ASSERTION(Initialised(), "RenderTo with uninitialised buffer!");
-
-  if (!mTexImage || !Initialised())
-    return;
-
-  EndUpdate();
-
-#ifdef MOZ_DUMP_PAINTING
-  if (gfxUtils::sDumpPainting) {
-    nsRefPtr<gfxImageSurface> surf = 
-      gl()->GetTexImage(mTexImage->GetTextureID(), false, mTexImage->GetTextureFormat());
-    
-    WriteSnapshotToDumpFile(mLayer, surf);
-  }
-#endif
-
-  int32_t passes = mTexImageOnWhite ? 2 : 1;
-  for (int32_t pass = 1; pass <= passes; ++pass) {
-    ShaderProgramOGL *program;
-
-    if (passes == 2) {
-      ShaderProgramOGL* alphaProgram;
-      if (pass == 1) {
-        ShaderProgramType type = gl()->GetPreferredARGB32Format() == LOCAL_GL_BGRA ?
-                                 ComponentAlphaPass1RGBProgramType :
-                                 ComponentAlphaPass1ProgramType;
-
-