Merge mozilla-central to b2g-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 08 Jan 2014 13:41:15 +0100
changeset 162533 5073cf98190b237842a09387f6345c8b43b0e5e8
parent 162532 fb01b2a309e49afd5bff09c2e287ba66890e647c (current diff)
parent 162508 d852bcf897cafaf88343d2a69544ab5ec7b16d99 (diff)
child 162534 73a8bf6d93e98a622dccc6bf309fcecedb8faab3
push id25958
push userryanvm@gmail.com
push dateWed, 08 Jan 2014 20:22:21 +0000
treeherdermozilla-central@8988416e489d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to b2g-inbound
--- a/.lldbinit
+++ b/.lldbinit
@@ -1,7 +1,9 @@
 # .lldbinit file for debugging Mozilla
 
 # Mozilla's use of UNIFIED_SOURCES to include multiple source files into a
 # single compiled file breaks lldb breakpoint setting. This works around that.
 # See http://lldb.llvm.org/troubleshooting.html for more info.
 settings set target.inline-breakpoint-strategy always
 
+# Deduce the concrete types of objects and pointers when printing them.
+settings set target.prefer-dynamic-value run-target
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -970,17 +970,18 @@
       <vbox id="social-sidebar-box"
             class="chromeclass-extrachrome"
             observes="socialSidebarBroadcaster"
             persist="width">
 
         <sidebarheader id="social-sidebar-header" class="sidebar-header" align="center">
           <image id="social-sidebar-favico"/>
           <label id="social-sidebar-title" class="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
-          <button id="social-sidebar-button"
+          <toolbarbutton id="social-sidebar-button"
+                         class="toolbarbutton-1"
                          type="menu">
             <menupopup id="social-statusarea-popup" position="after_end">
               <menuitem class="social-toggle-sidebar-menuitem"
                         type="checkbox"
                         autocheck="false"
                         command="Social:ToggleSidebar"
                         label="&social.toggleSidebar.label;"
                         accesskey="&social.toggleSidebar.accesskey;"/>
@@ -994,25 +995,25 @@
               <menuseparator/>
               <menuseparator class="social-provider-menu" hidden="true"/>
               <menuitem class="social-addons-menuitem" command="Social:Addons"
                         label="&social.addons.label;"/>
               <menuitem label="&social.learnMore.label;"
                         accesskey="&social.learnMore.accesskey;"
                         oncommand="SocialUI.showLearnMore();"/>
             </menupopup>
-          </button>
+          </toolbarbutton>
         </sidebarheader>
 
         <browser id="social-sidebar-browser"
                  type="content"
                  context="contentAreaContextMenu"
                  disableglobalhistory="true"
                  tooltip="aHTMLTooltip"
-               popupnotificationanchor="social-notification-icon"
+                 popupnotificationanchor="social-sidebar-favico"
                  flex="1"
                  style="min-width: 14em; width: 18em; max-width: 36em;"/>
       </vbox>
       <vbox id="browser-border-end" hidden="true" layer="true"/>
     </hbox>
 #include ../../components/customizableui/content/customizeMode.inc.xul
   </deck>
 
--- a/browser/devtools/debugger/debugger-panes.js
+++ b/browser/devtools/debugger/debugger-panes.js
@@ -2787,17 +2787,25 @@ GlobalSearchView.prototype = Heritage.ex
     this._currentlyFocusedMatch = LineResults.indexOfElement(target);
     this._scrollMatchIntoViewIfNeeded(target);
     this._bounceMatch(target);
 
     let url = sourceResultsItem.instance.url;
     let line = lineResultsItem.instance.line;
 
     DebuggerView.setEditorLocation(url, line + 1, { noDebug: true });
-    DebuggerView.editor.extendSelection(lineResultsItem.lineData.range);
+
+    let range = lineResultsItem.lineData.range;
+    let cursor = DebuggerView.editor.getOffset({ line: line, ch: 0 });
+    let [ anchor, head ] = DebuggerView.editor.getPosition(
+      cursor + range.start,
+      cursor + range.start + range.length
+    );
+
+    DebuggerView.editor.setSelection(anchor, head);
   },
 
   /**
    * Scrolls a match into view if not already visible.
    *
    * @param nsIDOMNode aMatch
    *        The match to scroll into view.
    */
--- a/browser/devtools/sourceeditor/codemirror/mozilla.css
+++ b/browser/devtools/sourceeditor/codemirror/mozilla.css
@@ -68,8 +68,16 @@ selector in floating-scrollbar-light.css
   color: hsl(210,30%,85%);
   background-image: url("chrome://browser/skin/devtools/background-noise-toolbar.png"),
     linear-gradient(#3e4750, #3e4750);
 }
 
 .CodeMirror-dialog input {
   font: message-box;
 }
+
+.CodeMirror-code > div > div:first-child {
+  top: 50%;
+}
+
+.CodeMirror-gutter-elt {
+  transform: translate(0,-50%);
+}
\ No newline at end of file
--- a/browser/devtools/sourceeditor/editor.js
+++ b/browser/devtools/sourceeditor/editor.js
@@ -68,16 +68,17 @@ const CM_MAPPING = [
   "focus",
   "hasFocus",
   "lineCount",
   "somethingSelected",
   "getCursor",
   "setSelection",
   "getSelection",
   "replaceSelection",
+  "extendSelection",
   "undo",
   "redo",
   "clearHistory",
   "openDialog",
   "refresh",
   "getOption",
   "setOption"
 ];
@@ -362,28 +363,16 @@ Editor.prototype = {
   dropSelection: function () {
     if (!this.somethingSelected())
       return;
 
     this.setCursor(this.getCursor());
   },
 
   /**
-   * Extends the current selection to the position specified
-   * by the provided {line, ch} object.
-   */
-  extendSelection: function (pos) {
-    let cm = editors.get(this);
-    let cursor = cm.indexFromPos(cm.getCursor());
-    let anchor = cm.posFromIndex(cursor + pos.start);
-    let head   = cm.posFromIndex(cursor + pos.start + pos.length);
-    cm.setSelection(anchor, head);
-  },
-
-  /**
    * Gets the first visible line number in the editor.
    */
   getFirstVisibleLine: function () {
     let cm = editors.get(this);
     return cm.lineAtHeight(0, "local");
   },
 
   /**
--- a/browser/devtools/sourceeditor/test/browser_editor_cursor.js
+++ b/browser/devtools/sourceeditor/test/browser_editor_cursor.js
@@ -20,19 +20,16 @@ function test() {
     ch(ed.getOffset({ line: 1, ch: 0 }), 7, "getOffset(num)");
     ch(ed.getOffset({ line: 1, ch: 0 }, { line: 0, ch: 1 })[0], 7, "getOffset(num, num)[0]");
     ch(ed.getOffset({ line: 1, ch: 0 }, { line: 0, ch: 1 })[0], 2, "getOffset(num, num)[1]");
 
     is(ed.getSelection(), "", "nothing is selected");
     ed.setSelection({ line: 0, ch: 0 }, { line: 0, ch: 5 });
     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);
--- a/browser/themes/shared/social/chat.inc.css
+++ b/browser/themes/shared/social/chat.inc.css
@@ -6,20 +6,24 @@
 
 #social-sidebar-header {
   padding: 3px;
 }
 
 #social-sidebar-button {
   -moz-appearance: none;
   list-style-image: url(chrome://browser/skin/social/gear_default.png);
-  min-width: 16px;
+  border: none;
   padding: 0;
   margin: 2px;
 }
+#social-sidebar-button > .toolbarbutton-icon {
+  min-height: 16px;
+  min-width: 16px;
+}
 #social-sidebar-button:hover,
 #social-sidebar-button:hover:active {
   list-style-image: url(chrome://browser/skin/social/gear_clicked.png);
 }
 #social-sidebar-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -392,16 +392,19 @@ nsFrameMessageManager::RemoveWeakMessage
 
 // nsIFrameScriptLoader
 
 NS_IMETHODIMP
 nsFrameMessageManager::LoadFrameScript(const nsAString& aURL,
                                        bool aAllowDelayedLoad,
                                        bool aRunInGlobalScope)
 {
+  // FIXME: Bug 673569 is currently disabled.
+  aRunInGlobalScope = true;
+
   if (aAllowDelayedLoad) {
     if (IsGlobal() || IsWindowLevel()) {
       // Cache for future windows or frames
       mPendingScripts.AppendElement(aURL);
       mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
     } else if (!mCallback) {
       // We're frame message manager, which isn't connected yet.
       mPendingScripts.AppendElement(aURL);
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -146,25 +146,29 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Exception)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Exception)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Exception)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Exception)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mThrownJSVal);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mInner)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   tmp->mThrownJSVal.setNull();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CI_INTERFACE_GETTER1(Exception, nsIXPCException)
 
 Exception::Exception(const char *aMessage,
                      nsresult aResult,
@@ -341,26 +345,38 @@ Exception::GetName(char** aName)
   return NS_OK;
 }
 
 /* readonly attribute string filename; */
 NS_IMETHODIMP
 Exception::GetFilename(char** aFilename)
 {
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
-    XPC_STRING_GETTER_BODY(aFilename, mFilename);
+
+  if (mLocation) {
+    return mLocation->GetFilename(aFilename);
+  }
+
+  XPC_STRING_GETTER_BODY(aFilename, mFilename);
 }
 
 /* readonly attribute uint32_t lineNumber; */
 NS_IMETHODIMP
 Exception::GetLineNumber(uint32_t *aLineNumber)
 {
   NS_ENSURE_ARG_POINTER(aLineNumber);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
+  if (mLocation) {
+    int32_t lineno;
+    nsresult rv = mLocation->GetLineNumber(&lineno);
+    *aLineNumber = lineno;
+    return rv;
+  }
+
   *aLineNumber = mLineNumber;
   return NS_OK;
 }
 
 /* readonly attribute uint32_t columnNumber; */
 NS_IMETHODIMP
 Exception::GetColumnNumber(uint32_t* aColumnNumber)
 {
@@ -470,25 +486,16 @@ Exception::Initialize(const char *aMessa
   if (aName) {
     mName = (char*) nsMemory::Clone(aName, sizeof(char)*(strlen(aName)+1));
   }
 
   mResult = aResult;
 
   if (aLocation) {
     mLocation = aLocation;
-    // For now, fill in our location details from our stack frame.
-    // Later we may allow other locations?
-    nsresult rc;
-    if (NS_FAILED(rc = aLocation->GetFilename(&mFilename))) {
-      return rc;
-    }
-    if (NS_FAILED(rc = aLocation->GetLineNumber(&mLineNumber))) {
-      return rc;
-    }
   } else {
     nsresult rv;
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     rv = xpc->GetCurrentJSStack(getter_AddRefs(mLocation));
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
@@ -549,16 +556,24 @@ Exception::GetFilename(nsString& retval)
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   CopyUTF8toUTF16(str, retval);
   nsMemory::Free(str);
 }
 
 uint32_t
 Exception::LineNumber() const
 {
+  if (mLocation) {
+    int32_t lineno;
+    if (NS_SUCCEEDED(mLocation->GetLineNumber(&lineno))) {
+      return lineno;
+    }
+    return 0;
+  }
+
   return mLineNumber;
 }
 
 uint32_t
 Exception::ColumnNumber() const
 {
   return 0;
 }
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1998,26 +1998,28 @@ struct CycleCollectorStats
   {
     mBeginSliceTime = TimeStamp();
     mBeginTime = TimeStamp();
     mMaxGCDuration = 0;
     mRanSyncForgetSkippable = false;
     mSuspected = 0;
     mMaxSkippableDuration = 0;
     mMaxSliceTime = 0;
+    mTotalSliceTime = 0;
     mAnyLockedOut = false;
     mExtraForgetSkippableCalls = 0;
   }
 
   void PrepareForCycleCollectionSlice(int32_t aExtraForgetSkippableCalls = 0);
 
   void FinishCycleCollectionSlice()
   {
     uint32_t sliceTime = TimeUntilNow(mBeginSliceTime);
     mMaxSliceTime = std::max(mMaxSliceTime, sliceTime);
+    mTotalSliceTime += sliceTime;
     MOZ_ASSERT(mExtraForgetSkippableCalls == 0, "Forget to reset extra forget skippable calls?");
   }
 
   void RunForgetSkippable();
 
   // Time the current slice began, including any GC finishing.
   TimeStamp mBeginSliceTime;
 
@@ -2035,16 +2037,19 @@ struct CycleCollectorStats
 
   // The longest duration spent on sync forget skippable in any slice of the
   // current CC.
   uint32_t mMaxSkippableDuration;
 
   // The longest pause of any slice in the current CC.
   uint32_t mMaxSliceTime;
 
+  // The total amount of time spent actually running the current CC.
+  uint32_t mTotalSliceTime;
+
   // True if we were locked out by the GC in any slice of the current CC.
   bool mAnyLockedOut;
 
   int32_t mExtraForgetSkippableCalls;
 };
 
 CycleCollectorStats gCCStats;
 
@@ -2252,17 +2257,18 @@ nsJSContext::EndCycleCollectionCallback(
       gcMsg.AssignLiteral(", forced a GC");
     }
 
     NS_NAMED_MULTILINE_LITERAL_STRING(kFmt,
       MOZ_UTF16("CC(T+%.1f) max pause: %lums, total time: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n")
       MOZ_UTF16("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, max sync: %lu ms, removed: %lu"));
     nsString msg;
     msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC,
-                                        gCCStats.mMaxSliceTime, ccNowDuration, gCCStats.mSuspected,
+                                        gCCStats.mMaxSliceTime, gCCStats.mTotalSliceTime,
+                                        gCCStats.mSuspected,
                                         aResults.mVisitedRefCounted, aResults.mVisitedGCed, mergeMsg.get(),
                                         aResults.mFreedRefCounted, aResults.mFreedGCed,
                                         sCCollectedWaitingForGC, sLikelyShortLivingObjectsNeedingGC,
                                         gcMsg.get(),
                                         sForgetSkippableBeforeCC,
                                         minForgetSkippableTime / PR_USEC_PER_MSEC,
                                         sMaxForgetSkippableTime / PR_USEC_PER_MSEC,
                                         (sTotalForgetSkippableTime / cleanups) /
@@ -2276,16 +2282,17 @@ nsJSContext::EndCycleCollectionCallback(
     }
   }
 
   if (sPostGCEventsToObserver) {
     NS_NAMED_MULTILINE_LITERAL_STRING(kJSONFmt,
        MOZ_UTF16("{ \"timestamp\": %llu, ")
          MOZ_UTF16("\"duration\": %llu, ")
          MOZ_UTF16("\"max_slice_pause\": %llu, ")
+         MOZ_UTF16("\"total_slice_pause\": %llu, ")
          MOZ_UTF16("\"max_finish_gc_duration\": %llu, ")
          MOZ_UTF16("\"max_sync_skippable_duration\": %llu, ")
          MOZ_UTF16("\"suspected\": %lu, ")
          MOZ_UTF16("\"visited\": { ")
              MOZ_UTF16("\"RCed\": %lu, ")
              MOZ_UTF16("\"GCed\": %lu }, ")
          MOZ_UTF16("\"collected\": { ")
              MOZ_UTF16("\"RCed\": %lu, ")
@@ -2298,17 +2305,19 @@ nsJSContext::EndCycleCollectionCallback(
              MOZ_UTF16("\"min\": %lu, ")
              MOZ_UTF16("\"max\": %lu, ")
              MOZ_UTF16("\"avg\": %lu, ")
              MOZ_UTF16("\"total\": %lu, ")
              MOZ_UTF16("\"removed\": %lu } ")
        MOZ_UTF16("}"));
     nsString json;
     json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(), endCCTime, ccNowDuration,
-                                         gCCStats.mMaxSliceTime, gCCStats.mMaxGCDuration,
+                                         gCCStats.mMaxSliceTime,
+                                         gCCStats.mTotalSliceTime,
+                                         gCCStats.mMaxGCDuration,
                                          gCCStats.mMaxSkippableDuration,
                                          gCCStats.mSuspected,
                                          aResults.mVisitedRefCounted, aResults.mVisitedGCed,
                                          aResults.mFreedRefCounted, aResults.mFreedGCed,
                                          sCCollectedWaitingForGC,
                                          sLikelyShortLivingObjectsNeedingGC,
                                          aResults.mForcedGC,
                                          sForgetSkippableBeforeCC,
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -198,65 +198,170 @@ GetCurrentJSStack()
          caller) {
     stack = caller;
   }
   return stack.forget();
 }
 
 namespace exceptions {
 
+class StackDescriptionOwner {
+public:
+  StackDescriptionOwner(JS::StackDescription* aDescription)
+    : mDescription(aDescription)
+  {
+    mozilla::HoldJSObjects(this);
+  }
+
+  ~StackDescriptionOwner()
+  {
+    // Make sure to set mDescription to null before calling DropJSObjects, since
+    // in debug builds DropJSObjects try to trace us and we don't want to trace
+    // a dead StackDescription.
+    if (mDescription) {
+      JS::FreeStackDescription(nullptr, mDescription);
+      mDescription = nullptr;
+    }
+    mozilla::DropJSObjects(this);
+  }
+
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(StackDescriptionOwner)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(StackDescriptionOwner)
+
+  JS::FrameDescription& FrameAt(size_t aIndex)
+  {
+    MOZ_ASSERT(aIndex < mDescription->nframes);
+    return mDescription->frames[aIndex];
+  }
+
+  unsigned NumFrames()
+  {
+    return mDescription->nframes;
+  }
+
+private:
+  JS::StackDescription* mDescription;
+};
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(StackDescriptionOwner, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(StackDescriptionOwner, Release)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(StackDescriptionOwner)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(StackDescriptionOwner)
+  if (tmp->mDescription) {
+    JS::FreeStackDescription(nullptr, tmp->mDescription);
+    tmp->mDescription = nullptr;
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(StackDescriptionOwner)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(StackDescriptionOwner)
+  JS::StackDescription* desc = tmp->mDescription;
+  if (tmp->mDescription) {
+    for (size_t i = 0; i < desc->nframes; ++i) {
+      NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].script());
+      NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].fun());
+    }
+  }
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 class JSStackFrame : public nsIStackFrame
 {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(JSStackFrame)
   NS_DECL_NSISTACKFRAME
 
-  JSStackFrame();
+  // A null aStackDescription or an aIndex that's out of range for the
+  // number of frames aStackDescription has will mean that the
+  // JSStackFrame will never look at the stack description.  Instead,
+  // it is expected to be initialized by the caller as needed.
+  JSStackFrame(StackDescriptionOwner* aStackDescription, size_t aIndex);
   virtual ~JSStackFrame();
 
   static already_AddRefed<nsIStackFrame>
   CreateStack(JSContext* cx);
   static already_AddRefed<nsIStackFrame>
   CreateStackFrameLocation(uint32_t aLanguage,
                            const char* aFilename,
                            const char* aFunctionName,
                            int32_t aLineNumber,
                            nsIStackFrame* aCaller);
 
 private:
   bool IsJSFrame() const {
     return mLanguage == nsIProgrammingLanguage::JAVASCRIPT;
   }
 
+  const char* GetFilename();
+  const char* GetFunname();
+  int32_t GetLineno();
+
+  nsRefPtr<StackDescriptionOwner> mStackDescription;
   nsCOMPtr<nsIStackFrame> mCaller;
 
+  // Cached values
   char* mFilename;
   char* mFunname;
   int32_t mLineno;
   uint32_t mLanguage;
+
+  size_t mIndex;
+
+  bool mFilenameInitialized;
+  bool mFunnameInitialized;
+  bool mLinenoInitialized;
+  bool mCallerInitialized;
 };
 
-JSStackFrame::JSStackFrame()
+JSStackFrame::JSStackFrame(StackDescriptionOwner* aStackDescription,
+                           size_t aIndex)
   : mFilename(nullptr),
     mFunname(nullptr),
-    mLineno(0),
-    mLanguage(nsIProgrammingLanguage::UNKNOWN)
-{}
+    mLineno(0)
+{
+  if (aStackDescription && aIndex < aStackDescription->NumFrames()) {
+    mStackDescription = aStackDescription;
+    mIndex = aIndex;
+    mFilenameInitialized = false;
+    mFunnameInitialized = false;
+    mLinenoInitialized = false;
+    mCallerInitialized = false;
+    mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
+  } else {
+    MOZ_ASSERT(!mStackDescription);
+    mIndex = 0;
+    mFilenameInitialized = true;
+    mFunnameInitialized = true;
+    mLinenoInitialized = true;
+    mCallerInitialized = true;
+    mLanguage = nsIProgrammingLanguage::UNKNOWN;
+  }
+}
 
 JSStackFrame::~JSStackFrame()
 {
   if (mFilename) {
     nsMemory::Free(mFilename);
   }
   if (mFunname) {
     nsMemory::Free(mFunname);
   }
 }
 
-NS_IMPL_ISUPPORTS1(JSStackFrame, nsIStackFrame)
+NS_IMPL_CYCLE_COLLECTION_2(JSStackFrame, mStackDescription, mCaller)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(JSStackFrame)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(JSStackFrame)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSStackFrame)
+  NS_INTERFACE_MAP_ENTRY(nsIStackFrame)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
 
 /* readonly attribute uint32_t language; */
 NS_IMETHODIMP JSStackFrame::GetLanguage(uint32_t* aLanguage)
 {
   *aLanguage = mLanguage;
   return NS_OK;
 }
 
@@ -270,142 +375,183 @@ NS_IMETHODIMP JSStackFrame::GetLanguageN
     *aLanguageName = (char*) nsMemory::Clone(js, sizeof(js));
   } else {
     *aLanguageName = (char*) nsMemory::Clone(cpp, sizeof(cpp));
   }
 
   return NS_OK;
 }
 
+const char*
+JSStackFrame::GetFilename()
+{
+  if (!mFilenameInitialized) {
+    JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
+    if (desc.script()) {
+      // This cx dance is silly, since JS_GetScriptFilename ignores
+      // its cx argument.
+      JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
+      JSAutoRequest ar(cx);
+      JSAutoCompartment ac(cx, desc.script());
+      const char* filename = JS_GetScriptFilename(cx, desc.script());
+      if (filename) {
+        mFilename =
+          (char*)nsMemory::Clone(filename, sizeof(char)*(strlen(filename)+1));
+      }
+    }
+    mFilenameInitialized = true;
+  }
+
+  return mFilename;
+}
+
 /* readonly attribute string filename; */
 NS_IMETHODIMP JSStackFrame::GetFilename(char** aFilename)
 {
   NS_ENSURE_ARG_POINTER(aFilename);
 
-  if (mFilename) {
-    *aFilename = (char*) nsMemory::Clone(mFilename,
-                                         sizeof(char)*(strlen(mFilename)+1));
+  const char* filename = GetFilename();
+  if (filename) {
+    *aFilename = (char*) nsMemory::Clone(filename,
+                                         sizeof(char)*(strlen(filename)+1));
   } else {
     *aFilename = nullptr;
   }
 
   return NS_OK;
 }
 
+const char*
+JSStackFrame::GetFunname()
+{
+  if (!mFunnameInitialized) {
+    JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
+    if (desc.fun() && desc.script()) {
+      JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
+      JSAutoRequest ar(cx);
+      JSAutoCompartment ac(cx, desc.script());
+      JS::Rooted<JSFunction*> fun(cx, desc.fun());
+      JS::Rooted<JSString*> funid(cx, JS_GetFunctionDisplayId(fun));
+      if (funid) {
+        size_t length = JS_GetStringEncodingLength(cx, funid);
+        if (length != size_t(-1)) {
+          mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
+          if (mFunname) {
+            JS_EncodeStringToBuffer(cx, funid, mFunname, length);
+            mFunname[length] = '\0';
+          }
+        }
+      }
+    }
+    mFunnameInitialized = true;
+  }
+
+  return mFunname;
+}
+
 /* readonly attribute string name; */
 NS_IMETHODIMP JSStackFrame::GetName(char** aFunction)
 {
   NS_ENSURE_ARG_POINTER(aFunction);
 
-  if (mFunname) {
-    *aFunction = (char*) nsMemory::Clone(mFunname,
-                                         sizeof(char)*(strlen(mFunname)+1));
+  const char* funname = GetFunname();
+  if (funname) {
+    *aFunction = (char*) nsMemory::Clone(funname,
+                                         sizeof(char)*(strlen(funname)+1));
   } else {
     *aFunction = nullptr;
   }
 
   return NS_OK;
 }
 
+int32_t
+JSStackFrame::GetLineno()
+{
+  if (!mLinenoInitialized) {
+    JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
+    mLineno = desc.lineno();
+    mLinenoInitialized = true;
+  }
+
+  return mLineno;
+}
+
 /* readonly attribute int32_t lineNumber; */
 NS_IMETHODIMP JSStackFrame::GetLineNumber(int32_t* aLineNumber)
 {
-  *aLineNumber = mLineno;
+  *aLineNumber = GetLineno();
   return NS_OK;
 }
 
 /* readonly attribute string sourceLine; */
 NS_IMETHODIMP JSStackFrame::GetSourceLine(char** aSourceLine)
 {
   *aSourceLine = nullptr;
   return NS_OK;
 }
 
 /* readonly attribute nsIStackFrame caller; */
 NS_IMETHODIMP JSStackFrame::GetCaller(nsIStackFrame** aCaller)
 {
+  if (!mCallerInitialized) {
+    mCaller = new JSStackFrame(mStackDescription, mIndex+1);
+    mCallerInitialized = true;
+  }
   NS_IF_ADDREF(*aCaller = mCaller);
   return NS_OK;
 }
 
 /* string toString (); */
 NS_IMETHODIMP JSStackFrame::ToString(char** _retval)
 {
   const char* frametype = IsJSFrame() ? "JS" : "native";
-  const char* filename = mFilename ? mFilename : "<unknown filename>";
-  const char* funname = mFunname ? mFunname : "<TOP_LEVEL>";
+  const char* filename = GetFilename();
+  if (!filename) {
+    filename = "<unknown filename>";
+  }
+  const char* funname = GetFunname();
+  if (!funname) {
+    funname = "<TOP_LEVEL>";
+  }
   static const char format[] = "%s frame :: %s :: %s :: line %d";
   int len = sizeof(char)*
               (strlen(frametype) + strlen(filename) + strlen(funname)) +
             sizeof(format) + 3 * sizeof(mLineno);
 
   char* buf = (char*) nsMemory::Alloc(len);
-  JS_snprintf(buf, len, format, frametype, filename, funname, mLineno);
+  JS_snprintf(buf, len, format, frametype, filename, funname, GetLineno());
   *_retval = buf;
   return NS_OK;
 }
 
 /* static */ already_AddRefed<nsIStackFrame>
 JSStackFrame::CreateStack(JSContext* cx)
 {
   static const unsigned MAX_FRAMES = 100;
 
-  nsRefPtr<JSStackFrame> first = new JSStackFrame();
-  nsRefPtr<JSStackFrame> self = first;
-
   JS::StackDescription* desc = JS::DescribeStack(cx, MAX_FRAMES);
   if (!desc) {
     return nullptr;
   }
 
-  for (size_t i = 0; i < desc->nframes && self; i++) {
-    self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
-
-    JSAutoCompartment ac(cx, desc->frames[i].script);
-    const char* filename = JS_GetScriptFilename(cx, desc->frames[i].script);
-    if (filename) {
-      self->mFilename =
-        (char*)nsMemory::Clone(filename, sizeof(char)*(strlen(filename)+1));
-    }
-
-    self->mLineno = desc->frames[i].lineno;
+  nsRefPtr<StackDescriptionOwner> descOwner = new StackDescriptionOwner(desc);
 
-    JSFunction* fun = desc->frames[i].fun;
-    if (fun) {
-      JS::Rooted<JSString*> funid(cx, JS_GetFunctionDisplayId(fun));
-      if (funid) {
-        size_t length = JS_GetStringEncodingLength(cx, funid);
-        if (length != size_t(-1)) {
-          self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
-          if (self->mFunname) {
-            JS_EncodeStringToBuffer(cx, funid, self->mFunname, length);
-            self->mFunname[length] = '\0';
-          }
-        }
-      }
-    }
-
-    nsRefPtr<JSStackFrame> frame = new JSStackFrame();
-    self->mCaller = frame;
-    self.swap(frame);
-  }
-
-  JS::FreeStackDescription(cx, desc);
-
+  nsRefPtr<JSStackFrame> first = new JSStackFrame(descOwner, 0);
   return first.forget();
 }
 
 /* static */ already_AddRefed<nsIStackFrame>
 JSStackFrame::CreateStackFrameLocation(uint32_t aLanguage,
                                        const char* aFilename,
                                        const char* aFunctionName,
                                        int32_t aLineNumber,
                                        nsIStackFrame* aCaller)
 {
-  nsRefPtr<JSStackFrame> self = new JSStackFrame();
+  nsRefPtr<JSStackFrame> self = new JSStackFrame(nullptr, 0);
 
   self->mLanguage = aLanguage;
   self->mLineno = aLineNumber;
 
   if (aFilename) {
     self->mFilename =
       (char*)nsMemory::Clone(aFilename, sizeof(char)*(strlen(aFilename)+1));
   }
--- a/dom/plugins/base/android/ANPOpenGL.cpp
+++ b/dom/plugins/base/android/ANPOpenGL.cpp
@@ -5,17 +5,17 @@
 #include <dlfcn.h>
 #include <android/log.h>
 #include "AndroidBridge.h"
 #include "ANPBase.h"
 #include "GLContextProvider.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsPluginInstanceOwner.h"
 #include "GLContextProvider.h"
-#include "GLContext.h"
+#include "GLContextEGL.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
 #define ASSIGN(obj, name)   (obj)->name = anp_opengl_##name
 
 using namespace mozilla;
 using namespace mozilla::gl;
 
 typedef nsNPAPIPluginInstance::TextureInfo TextureInfo;
@@ -23,17 +23,17 @@ typedef nsNPAPIPluginInstance::TextureIn
 static ANPEGLContext anp_opengl_acquireContext(NPP instance) {
     nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
 
     GLContext* context = pinst->GLContext();
     if (!context)
         return nullptr;
 
     context->MakeCurrent();
-    return context->GetNativeData(GLContext::NativeGLContext);
+    return GLContextEGL::Cast(context)->GetEGLContext();
 }
 
 static ANPTextureInfo anp_opengl_lockTexture(NPP instance) {
     nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
 
     TextureInfo pluginInfo = pinst->LockContentTexture();
 
     ANPTextureInfo info;
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -151,16 +151,35 @@ public:
       return true;
     } else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
       return true;
     }
 
     return false;
   }
 
+  /**
+   * Returns true if the matrix is anything other than a straight
+   * translation by integers.
+  */
+  bool HasNonIntegerTranslation() const {
+    return HasNonTranslation() ||
+      !FuzzyEqual(_31, floor(_31 + 0.5)) ||
+      !FuzzyEqual(_32, floor(_32 + 0.5));
+  }
+
+  /**
+   * Returns true if the matrix has any transform other
+   * than a straight translation.
+   */
+  bool HasNonTranslation() const {
+    return !FuzzyEqual(_11, 1.0) || !FuzzyEqual(_22, 1.0) ||
+           !FuzzyEqual(_12, 0.0) || !FuzzyEqual(_21, 0.0);
+  }
+
   /* Returns true if the matrix is an identity matrix.
    */
   bool IsIdentity() const
   {
     return _11 == 1.0f && _12 == 0.0f &&
            _21 == 0.0f && _22 == 1.0f &&
            _31 == 0.0f && _32 == 0.0f;
   }
--- a/gfx/gl/GLBlitTextureImageHelper.cpp
+++ b/gfx/gl/GLBlitTextureImageHelper.cpp
@@ -108,17 +108,17 @@ GLBlitTextureImageHelper::BlitTextureIma
             nsIntSize dstSize = dstTextureRect.Size();
             srcSubRect.MoveBy(-srcTextureRect.x, -srcTextureRect.y);
             srcSubInDstRect.MoveBy(-dstTextureRect.x, -dstTextureRect.y);
 
             float dx0 = 2.0f * float(srcSubInDstRect.x) / float(dstSize.width) - 1.0f;
             float dy0 = 2.0f * float(srcSubInDstRect.y) / float(dstSize.height) - 1.0f;
             float dx1 = 2.0f * float(srcSubInDstRect.x + srcSubInDstRect.width) / float(dstSize.width) - 1.0f;
             float dy1 = 2.0f * float(srcSubInDstRect.y + srcSubInDstRect.height) / float(dstSize.height) - 1.0f;
-            mGL->PushViewportRect(nsIntRect(0, 0, dstSize.width, dstSize.height));
+            ScopedViewportRect autoViewportRect(mGL, 0, 0, dstSize.width, dstSize.height);
 
             RectTriangles rects;
 
             nsIntSize realTexSize = srcSize;
             if (!CanUploadNonPowerOfTwo(mGL)) {
                 realTexSize = nsIntSize(gfx::NextPowerOfTwo(srcSize.width),
                                         gfx::NextPowerOfTwo(srcSize.height));
             }
@@ -155,17 +155,16 @@ GLBlitTextureImageHelper::BlitTextureIma
             mGL->fEnableVertexAttribArray(0);
             mGL->fEnableVertexAttribArray(1);
 
             mGL->fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
 
             mGL->fDisableVertexAttribArray(0);
             mGL->fDisableVertexAttribArray(1);
 
-            mGL->PopViewportRect();
         } while (aSrc->NextTile());
     } while (aDst->NextTile());
 
     mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, nullptr);
     mGL->fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, nullptr);
 
     // unbind the previous texture from the framebuffer
     SetBlitFramebufferForDestTexture(0);
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -259,17 +259,16 @@ GLContext::GLContext(const SurfaceCaps& 
     mProfile(ContextProfile::Unknown),
     mVendor(-1),
     mRenderer(-1),
     mHasRobustness(false),
 #ifdef DEBUG
     mGLError(LOCAL_GL_NO_ERROR),
 #endif
     mSharedContext(sharedContext),
-    mFlipped(false),
     mCaps(caps),
     mScreen(nullptr),
     mLockedSurface(nullptr),
     mMaxTextureSize(0),
     mMaxCubeMapTextureSize(0),
     mMaxTextureImageSize(0),
     mMaxRenderbufferSize(0),
     mNeedsTextureSizeChecks(false),
@@ -1019,24 +1018,18 @@ GLContext::InitWithPrefix(const char *pr
                 { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } },
                 { nullptr, { nullptr } },
         };
         bool warnOnFailures = DebugMode();
         LoadSymbols(&auxSymbols[0], trygl, prefix, warnOnFailures);
     }
 
     if (mInitialized) {
-        GLint v[4];
-
-        fGetIntegerv(LOCAL_GL_SCISSOR_BOX, v);
-        mScissorStack.AppendElement(nsIntRect(v[0], v[1], v[2], v[3]));
-
-        fGetIntegerv(LOCAL_GL_VIEWPORT, v);
-        mViewportStack.AppendElement(nsIntRect(v[0], v[1], v[2], v[3]));
-
+        raw_fGetIntegerv(LOCAL_GL_VIEWPORT, mViewportRect);
+        raw_fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mScissorRect);
         raw_fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
         raw_fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxCubeMapTextureSize);
         raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize);
 
 #ifdef XP_MACOSX
         if (mWorkAroundDriverBugs) {
             if (mVendor == VendorIntel) {
                 // see bug 737182 for 2D textures, bug 684882 for cube map textures.
@@ -1538,17 +1531,16 @@ GLContext::ClearSafely()
     fGetIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &stencilWriteMaskBack);
     fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
     fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
     fGetIntegerv(LOCAL_GL_STENCIL_CLEAR_VALUE, &stencilClearValue);
 
     // prepare GL state for clearing
     fDisable(LOCAL_GL_SCISSOR_TEST);
     fDisable(LOCAL_GL_DITHER);
-    PushViewportRect(nsIntRect(0, 0, OffscreenSize().width, OffscreenSize().height));
 
     fColorMask(1, 1, 1, 1);
     fClearColor(0.f, 0.f, 0.f, 0.f);
 
     fDepthMask(1);
     fClearDepth(1.0f);
 
     fStencilMask(0xffffffff);
@@ -1571,18 +1563,16 @@ GLContext::ClearSafely()
 
     fDepthMask(depthWriteMask);
     fClearDepth(depthClearValue);
 
     fStencilMaskSeparate(LOCAL_GL_FRONT, stencilWriteMaskFront);
     fStencilMaskSeparate(LOCAL_GL_BACK, stencilWriteMaskBack);
     fClearStencil(stencilClearValue);
 
-    PopViewportRect();
-
     if (ditherEnabled)
         fEnable(LOCAL_GL_DITHER);
     else
         fDisable(LOCAL_GL_DITHER);
 
     if (scissorTestEnabled)
         fEnable(LOCAL_GL_SCISSOR_TEST);
     else
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -873,36 +873,32 @@ public:
 
     void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *pixels) {
         BEFORE_GL_CALL;
         mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
         AFTER_GL_CALL;
     }
 
     void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
-        y = FixYValue(y, height);
-
         if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
             // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
             // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
             level = -1;
             width = -1;
             height = -1;
             border = -1;
         }
 
         BeforeGLReadCall();
         raw_fCopyTexImage2D(target, level, internalformat,
                             x, y, width, height, border);
         AfterGLReadCall();
     }
 
     void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
-        y = FixYValue(y, height);
-
         BeforeGLReadCall();
         raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
                                x, y, width, height);
         AfterGLReadCall();
     }
 
     void fCullFace(GLenum mode) {
         BEFORE_GL_CALL;
@@ -1096,16 +1092,28 @@ public:
                 *params = mMaxCubeMapTextureSize;
                 break;
 
             case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
                 MOZ_ASSERT(mMaxRenderbufferSize>0);
                 *params = mMaxRenderbufferSize;
                 break;
 
+            case LOCAL_GL_VIEWPORT:
+                for (size_t i = 0; i < 4; i++) {
+                    params[i] = mViewportRect[i];
+                }
+                break;
+
+            case LOCAL_GL_SCISSOR_BOX:
+                for (size_t i = 0; i < 4; i++) {
+                    params[i] = mScissorRect[i];
+                }
+                break;
+
             default:
                 raw_fGetIntegerv(pname, params);
                 break;
         }
     }
 
     void GetUIntegerv(GLenum pname, GLuint *params) {
         fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
@@ -1368,24 +1376,22 @@ public:
         BEFORE_GL_CALL;
         mSymbols.fReadBuffer(mode);
         AFTER_GL_CALL;
     }
 
 private:
     void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
         BEFORE_GL_CALL;
-        mSymbols.fReadPixels(x, FixYValue(y, height), width, height, format, type, pixels);
+        mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
         AFTER_GL_CALL;
     }
 
 public:
     void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
-        y = FixYValue(y, height);
-
         BeforeGLReadCall();
 
         bool didReadPixels = false;
         if (mScreen) {
             didReadPixels = mScreen->ReadPixels(x, y, width, height, format, type, pixels);
         }
 
         if (!didReadPixels) {
@@ -1397,24 +1403,33 @@ public:
 
 public:
     void fSampleCoverage(GLclampf value, realGLboolean invert) {
         BEFORE_GL_CALL;
         mSymbols.fSampleCoverage(value, invert);
         AFTER_GL_CALL;
     }
 
-private:
-    void raw_fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
+    void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
+        if (mScissorRect[0] == x &&
+            mScissorRect[1] == y &&
+            mScissorRect[2] == width &&
+            mScissorRect[3] == height)
+        {
+            return;
+        }
+        mScissorRect[0] = x;
+        mScissorRect[1] = y;
+        mScissorRect[2] = width;
+        mScissorRect[3] = height;
         BEFORE_GL_CALL;
         mSymbols.fScissor(x, y, width, height);
         AFTER_GL_CALL;
     }
 
-public:
     void fStencilFunc(GLenum func, GLint ref, GLuint mask) {
         BEFORE_GL_CALL;
         mSymbols.fStencilFunc(func, ref, mask);
         AFTER_GL_CALL;
     }
 
     void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {
         BEFORE_GL_CALL;
@@ -2420,25 +2435,16 @@ public:
     // the GL function pointers!
     void MarkDestroyed();
 
     bool IsDestroyed() {
         // MarkDestroyed will mark all these as null.
         return mSymbols.fUseProgram == nullptr;
     }
 
-    enum NativeDataType {
-      NativeGLContext,
-      NativeImageSurface,
-      NativeThebesSurface,
-      NativeCGLContext,
-      NativeDataTypeMax
-    };
-
-    virtual void *GetNativeData(NativeDataType aType) { return nullptr; }
     GLContext *GetSharedContext() { return mSharedContext; }
 
     /**
      * Returns true if the thread on which this context was created is the currently
      * executing thread.
      */
     bool IsOwningThreadCurrent();
     void DispatchToOwningThread(nsIRunnable *event);
@@ -2564,18 +2570,16 @@ public:
 
     virtual bool RenewSurface() { return false; }
 
     // Shared code for GL extensions and GLX extensions.
     static bool ListHasExtension(const GLubyte *extensions,
                                  const char *extension);
 
     GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
-    void SetFlipped(bool aFlipped) { mFlipped = aFlipped; }
-
 
 public:
     /**
      * Context reset constants.
      * These are used to determine who is guilty when a context reset
      * happens.
      */
     enum ContextResetARB {
@@ -2615,17 +2619,16 @@ protected:
 #ifdef DEBUG
     // GLDebugMode will check that we don't send call
     // to a GLContext that isn't current on the current
     // thread.
     // Store the current context when binding to thread local
     // storage to support DebugMode on an arbitrary thread.
     static unsigned sCurrentGLContextTLS;
 #endif
-    bool mFlipped;
 
     ScopedDeletePtr<GLBlitHelper> mBlitHelper;
     ScopedDeletePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
     ScopedDeletePtr<GLReadTexImageHelper> mReadTexImageHelper;
 
 public:
 
     GLBlitHelper* BlitHelper();
@@ -2797,18 +2800,18 @@ public:
 
     bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
 
 protected:
     bool InitWithPrefix(const char *prefix, bool trygl);
 
     void InitExtensions();
 
-    nsTArray<nsIntRect> mViewportStack;
-    nsTArray<nsIntRect> mScissorStack;
+    GLint mViewportRect[4];
+    GLint mScissorRect[4];
 
     GLint mMaxTextureSize;
     GLint mMaxCubeMapTextureSize;
     GLint mMaxTextureImageSize;
     GLint mMaxRenderbufferSize;
     GLsizei mMaxSamples;
     bool mNeedsTextureSizeChecks;
     bool mWorkAroundDriverBugs;
@@ -2827,113 +2830,35 @@ protected:
                               ? mMaxCubeMapTextureSize
                               : mMaxTextureSize;
             return width <= maxSize && height <= maxSize;
         }
         return true;
     }
 
 
-    /*** Scissor functions ***/
-
-protected:
-    GLint FixYValue(GLint y, GLint height)
-    {
-        MOZ_ASSERT( !(mIsOffscreen && mFlipped) );
-        return mFlipped ? ViewportRect().height - (height + y) : y;
-    }
-
 public:
-    void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
-        ScissorRect().SetRect(x, y, width, height);
-
-        // GL's coordinate system is flipped compared to the one we use in
-        // OGL Layers (in the Y axis), so we may need to flip our rectangle.
-        y = FixYValue(y, height);
-        raw_fScissor(x, y, width, height);
-    }
-
-    nsIntRect& ScissorRect() {
-        return mScissorStack[mScissorStack.Length()-1];
-    }
-
-    void PushScissorRect() {
-        nsIntRect copy(ScissorRect());
-        mScissorStack.AppendElement(copy);
-    }
-
-    void PushScissorRect(const nsIntRect& aRect) {
-        mScissorStack.AppendElement(aRect);
-        fScissor(aRect.x, aRect.y, aRect.width, aRect.height);
-    }
-
-    void PopScissorRect() {
-        if (mScissorStack.Length() < 2) {
-            NS_WARNING("PopScissorRect with Length < 2!");
+
+    void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+        if (mViewportRect[0] == x &&
+            mViewportRect[1] == y &&
+            mViewportRect[2] == width &&
+            mViewportRect[3] == height)
+        {
             return;
         }
-
-        nsIntRect thisRect = ScissorRect();
-        mScissorStack.TruncateLength(mScissorStack.Length() - 1);
-        if (!thisRect.IsEqualInterior(ScissorRect())) {
-            fScissor(ScissorRect().x, ScissorRect().y,
-                     ScissorRect().width, ScissorRect().height);
-        }
-    }
-
-    /*** Viewport functions ***/
-
-private:
-    // only does the glViewport call, no ViewportRect business
-    void raw_fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+        mViewportRect[0] = x;
+        mViewportRect[1] = y;
+        mViewportRect[2] = width;
+        mViewportRect[3] = height;
         BEFORE_GL_CALL;
-        // XXX: Flipping should really happen using the destination height, but
-        // we use viewport instead and assume viewport size matches the
-        // destination. If we ever try use partial viewports for layers we need
-        // to fix this, and remove the assertion.
-        NS_ASSERTION(!mFlipped || (x == 0 && y == 0), "TODO: Need to flip the viewport rect");
         mSymbols.fViewport(x, y, width, height);
         AFTER_GL_CALL;
     }
 
-public:
-    void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
-        ViewportRect().SetRect(x, y, width, height);
-        raw_fViewport(x, y, width, height);
-    }
-
-    nsIntRect& ViewportRect() {
-        return mViewportStack[mViewportStack.Length()-1];
-    }
-
-    void PushViewportRect() {
-        nsIntRect copy(ViewportRect());
-        mViewportStack.AppendElement(copy);
-    }
-
-    void PushViewportRect(const nsIntRect& aRect) {
-        mViewportStack.AppendElement(aRect);
-        raw_fViewport(aRect.x, aRect.y, aRect.width, aRect.height);
-    }
-
-    void PopViewportRect() {
-        if (mViewportStack.Length() < 2) {
-            NS_WARNING("PopViewportRect with Length < 2!");
-            return;
-        }
-
-        nsIntRect thisRect = ViewportRect();
-        mViewportStack.TruncateLength(mViewportStack.Length() - 1);
-        if (!thisRect.IsEqualInterior(ViewportRect())) {
-            raw_fViewport(ViewportRect().x, ViewportRect().y,
-                          ViewportRect().width, ViewportRect().height);
-        }
-    }
-
-
 #undef ASSERT_SYMBOL_PRESENT
 
 #ifdef MOZ_ENABLE_GL_TRACKING
     void CreatedProgram(GLContext *aOrigin, GLuint aName);
     void CreatedShader(GLContext *aOrigin, GLuint aName);
     void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLContextCGL.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 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 GLCONTEXTCGL_H_
+#define GLCONTEXTCGL_H_
+
+#include "GLContext.h"
+
+#include "OpenGL/OpenGL.h"
+
+#ifdef __OBJC__
+#include <AppKit/NSOpenGL.h>
+#else
+typedef void NSOpenGLContext;
+#endif
+
+namespace mozilla {
+namespace gl {
+
+class GLContextCGL : public GLContext
+{
+    friend class GLContextProviderCGL;
+
+    NSOpenGLContext *mContext;
+
+public:
+    GLContextCGL(const SurfaceCaps& caps,
+                 GLContext *shareContext,
+                 NSOpenGLContext *context,
+                 bool isOffscreen = false);
+
+    ~GLContextCGL();
+
+    virtual GLContextType GetContextType() MOZ_OVERRIDE { return ContextTypeCGL; }
+
+    static GLContextCGL* Cast(GLContext* gl) {
+        MOZ_ASSERT(gl->GetContextType() == ContextTypeCGL);
+        return static_cast<GLContextCGL*>(gl);
+    }
+
+    bool Init();
+
+    NSOpenGLContext* GetNSOpenGLContext() const { return mContext; }
+    CGLContextObj GetCGLContext() const;
+
+    bool MakeCurrentImpl(bool aForce = false);
+
+    virtual bool IsCurrent();
+
+    virtual GLenum GetPreferredARGB32Format() MOZ_OVERRIDE;
+
+    bool SetupLookupFunction();
+
+    bool IsDoubleBuffered();
+
+    bool SupportsRobustness();
+
+    bool SwapBuffers();
+
+    bool ResizeOffscreen(const gfx::IntSize& aNewSize);
+};
+
+}
+}
+
+#endif // GLCONTEXTCGL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLContextEGL.h
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 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 GLCONTEXTEGL_H_
+#define GLCONTEXTEGL_H_
+
+#include "GLContext.h"
+#include "GLLibraryEGL.h"
+
+#ifdef MOZ_WIDGET_GONK
+#include "HwcComposer2D.h"
+#endif
+
+namespace mozilla {
+namespace gl {
+
+class GLContextEGL : public GLContext
+{
+    friend class TextureImageEGL;
+
+    static already_AddRefed<GLContextEGL>
+    CreateGLContext(const SurfaceCaps& caps,
+                    GLContextEGL *shareContext,
+                    bool isOffscreen,
+                    EGLConfig config,
+                    EGLSurface surface);
+
+public:
+    GLContextEGL(const SurfaceCaps& caps,
+                 GLContext* shareContext,
+                 bool isOffscreen,
+                 EGLConfig config,
+                 EGLSurface surface,
+                 EGLContext context);
+
+    ~GLContextEGL();
+
+    virtual GLContextType GetContextType() MOZ_OVERRIDE { return ContextTypeEGL; }
+
+    static GLContextEGL* Cast(GLContext* gl) {
+        MOZ_ASSERT(gl->GetContextType() == ContextTypeEGL);
+        return static_cast<GLContextEGL*>(gl);
+    }
+
+    bool Init();
+
+    bool IsDoubleBuffered() {
+        return mIsDoubleBuffered;
+    }
+
+    void SetIsDoubleBuffered(bool aIsDB) {
+        mIsDoubleBuffered = aIsDB;
+    }
+
+    bool SupportsRobustness()
+    {
+        return sEGLLibrary.HasRobustness();
+    }
+
+    virtual bool IsANGLE()
+    {
+        return sEGLLibrary.IsANGLE();
+    }
+
+    bool BindTexImage();
+
+    bool ReleaseTexImage();
+
+    void SetEGLSurfaceOverride(EGLSurface surf);
+
+    bool MakeCurrentImpl(bool aForce = false);
+
+    virtual bool IsCurrent();
+
+    virtual bool
+    RenewSurface();
+
+    virtual void
+    ReleaseSurface();
+
+    bool SetupLookupFunction();
+
+    bool SwapBuffers();
+
+    // hold a reference to the given surface
+    // for the lifetime of this context.
+    void HoldSurface(gfxASurface *aSurf);
+
+    EGLContext GetEGLContext() {
+        return mContext;
+    }
+
+    bool BindTex2DOffscreen(GLContext *aOffscreen);
+    void UnbindTex2DOffscreen(GLContext *aOffscreen);
+    bool ResizeOffscreen(const gfx::IntSize& aNewSize);
+    void BindOffscreenFramebuffer();
+
+    static already_AddRefed<GLContextEGL>
+    CreateEGLPixmapOffscreenContext(const gfxIntSize& size);
+
+    static already_AddRefed<GLContextEGL>
+    CreateEGLPBufferOffscreenContext(const gfxIntSize& size);
+
+protected:
+    friend class GLContextProviderEGL;
+
+    EGLConfig  mConfig;
+    EGLSurface mSurface;
+    EGLSurface mSurfaceOverride;
+    EGLContext mContext;
+    nsRefPtr<gfxASurface> mThebesSurface;
+    bool mBound;
+
+    bool mIsPBuffer;
+    bool mIsDoubleBuffered;
+    bool mCanBindToTexture;
+    bool mShareWithEGLImage;
+#ifdef MOZ_WIDGET_GONK
+    nsRefPtr<HwcComposer2D> mHwc;
+#endif
+
+    static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
+                                                           EGLenum bindToTextureFormat,
+                                                           gfxIntSize& pbsize);
+};
+
+}
+}
+
+#endif // GLCONTEXTEGL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLContextGLX.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 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 GLCONTEXTGLX_H_
+#define GLCONTEXTGLX_H_
+
+#include "GLContext.h"
+#include "GLXLibrary.h"
+
+namespace mozilla {
+namespace gl {
+
+typedef GLXLibrary::LibraryType LibType;
+
+class GLContextGLX : public GLContext
+{
+public:
+    static already_AddRefed<GLContextGLX>
+    CreateGLContext(const SurfaceCaps& caps,
+                    GLContextGLX* shareContext,
+                    bool isOffscreen,
+                    Display* display,
+                    GLXDrawable drawable,
+                    GLXFBConfig cfg,
+                    bool deleteDrawable,
+                    LibType libType = GLXLibrary::OPENGL_LIB,
+                    gfxXlibSurface* pixmap = nullptr);
+
+    ~GLContextGLX();
+
+    virtual GLContextType GetContextType() MOZ_OVERRIDE { return ContextTypeGLX; }
+
+    static GLContextGLX* Cast(GLContext* gl) {
+        MOZ_ASSERT(gl->GetContextType() == ContextTypeGLX);
+        return static_cast<GLContextGLX*>(gl);
+    }
+
+    bool Init();
+
+    bool MakeCurrentImpl(bool aForce = false);
+
+    virtual bool IsCurrent();
+
+    bool SetupLookupFunction();
+
+    bool IsDoubleBuffered();
+
+    bool SupportsRobustness();
+
+    bool SwapBuffers();
+
+private:
+    friend class GLContextProviderGLX;
+
+    GLContextGLX(const SurfaceCaps& caps,
+                 GLContext* shareContext,
+                 bool isOffscreen,
+                 Display *aDisplay,
+                 GLXDrawable aDrawable,
+                 GLXContext aContext,
+                 bool aDeleteDrawable,
+                 bool aDoubleBuffered,
+                 gfxXlibSurface *aPixmap,
+                 LibType libType);
+
+    GLXContext mContext;
+    Display *mDisplay;
+    GLXDrawable mDrawable;
+    bool mDeleteDrawable;
+    bool mDoubleBuffered;
+
+    GLXLibrary* mGLX;
+
+    nsRefPtr<gfxXlibSurface> mPixmap;
+};
+
+}
+}
+
+#endif // GLCONTEXTGLX_H_
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -1,21 +1,19 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GLContextProvider.h"
-#include "GLContext.h"
+#include "GLContextCGL.h"
 #include "TextureImageCGL.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
-#include "OpenGL/OpenGL.h"
 #include <OpenGL/gl.h>
-#include <AppKit/NSOpenGL.h>
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxQuartzSurface.h"
 #include "gfxPlatform.h"
 #include "gfxFailure.h"
 #include "prenv.h"
 #include "mozilla/Preferences.h"
 #include "GeckoProfiler.h"
@@ -79,125 +77,113 @@ public:
 private:
     bool mInitialized;
     PRLibrary *mOGLLibrary;
     NSOpenGLPixelFormat *mPixelFormat;
 }; 
 
 CGLLibrary sCGLLibrary;
 
-class GLContextCGL : public GLContext
+GLContextCGL::GLContextCGL(
+                  const SurfaceCaps& caps,
+                  GLContext *shareContext,
+                  NSOpenGLContext *context,
+                  bool isOffscreen)
+    : GLContext(caps, shareContext, isOffscreen),
+      mContext(context)
 {
-    friend class GLContextProviderCGL;
+    SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
+}
 
-public:
-    GLContextCGL(const SurfaceCaps& caps,
-                 GLContext *shareContext,
-                 NSOpenGLContext *context,
-                 bool isOffscreen = false)
-        : GLContext(caps, shareContext, isOffscreen),
-          mContext(context),
-          mTempTextureName(0)
-    {
-        SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
+GLContextCGL::~GLContextCGL()
+{
+    MarkDestroyed();
+
+    if (mContext) {
+        if ([NSOpenGLContext currentContext] == mContext) {
+            // Clear the current context before releasing. If we don't do
+            // this, the next time we call [NSOpenGLContext currentContext],
+            // "invalid context" will be printed to the console.
+            [NSOpenGLContext clearCurrentContext];
+        }
+        [mContext release];
     }
 
-    ~GLContextCGL()
-    {
-        MarkDestroyed();
+}
+
+bool
+GLContextCGL::Init()
+{
+    if (!InitWithPrefix("gl", true))
+        return false;
+
+    return true;
+}
 
-        if (mContext) {
-            if ([NSOpenGLContext currentContext] == mContext) {
-                // Clear the current context before releasing. If we don't do
-                // this, the next time we call [NSOpenGLContext currentContext],
-                // "invalid context" will be printed to the console.
-                [NSOpenGLContext clearCurrentContext];
-            }
-            [mContext release];
-        }
+CGLContextObj
+GLContextCGL::GetCGLContext() const
+{
+    return static_cast<CGLContextObj>([mContext CGLContextObj]);
+}
 
-    }
-
-    GLContextType GetContextType() {
-        return ContextTypeCGL;
-    }
-
-    bool Init()
-    {
-        if (!InitWithPrefix("gl", true))
-            return false;
-
+bool
+GLContextCGL::MakeCurrentImpl(bool aForce)
+{
+    if (!aForce && [NSOpenGLContext currentContext] == mContext) {
         return true;
     }
 
-    void *GetNativeData(NativeDataType aType)
-    { 
-        switch (aType) {
-        case NativeGLContext:
-            return mContext;
-        case NativeCGLContext:
-            return [mContext CGLContextObj];
-        default:
-            return nullptr;
-        }
+    if (mContext) {
+        [mContext makeCurrentContext];
+        // Use non-blocking swap in "ASAP mode".
+        // ASAP mode means that rendering is iterated as fast as possible.
+        // ASAP mode is entered when layout.frame_rate=0 (requires restart).
+        // If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
+        // When we're iterating as fast as possible, however, we want a non-blocking
+        // glSwapBuffers, which will happen when swapInt==0.
+        GLint swapInt = gfxPlatform::GetPrefLayoutFrameRate() == 0 ? 0 : 1;
+        [mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
     }
+    return true;
+}
 
-    bool MakeCurrentImpl(bool aForce = false)
-    {
-        if (!aForce && [NSOpenGLContext currentContext] == mContext) {
-            return true;
-        }
+bool
+GLContextCGL::IsCurrent() {
+    return [NSOpenGLContext currentContext] == mContext;
+}
 
-        if (mContext) {
-            [mContext makeCurrentContext];
-            // Use non-blocking swap in "ASAP mode".
-            // ASAP mode means that rendering is iterated as fast as possible.
-            // ASAP mode is entered when layout.frame_rate=0 (requires restart).
-            // If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
-            // When we're iterating as fast as possible, however, we want a non-blocking
-            // glSwapBuffers, which will happen when swapInt==0.
-            GLint swapInt = gfxPlatform::GetPrefLayoutFrameRate() == 0 ? 0 : 1;
-            [mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
-        }
-        return true;
-    }
+GLenum
+GLContextCGL::GetPreferredARGB32Format() { return LOCAL_GL_BGRA; }
 
-    virtual bool IsCurrent() {
-        return [NSOpenGLContext currentContext] == mContext;
-    }
-
-    virtual GLenum GetPreferredARGB32Format() MOZ_OVERRIDE { return LOCAL_GL_BGRA; }
+bool
+GLContextCGL::SetupLookupFunction()
+{
+    return false;
+}
 
-    bool SetupLookupFunction()
-    {
-        return false;
-    }
-
-    bool IsDoubleBuffered() 
-    { 
-      return gUseDoubleBufferedWindows; 
-    }
+bool
+GLContextCGL::IsDoubleBuffered()
+{
+  return gUseDoubleBufferedWindows;
+}
 
-    bool SupportsRobustness()
-    {
-        return false;
-    }
+bool
+GLContextCGL::SupportsRobustness()
+{
+    return false;
+}
 
-    bool SwapBuffers()
-    {
-      PROFILER_LABEL("GLContext", "SwapBuffers");
-      [mContext flushBuffer];
-      return true;
-    }
+bool
+GLContextCGL::SwapBuffers()
+{
+  PROFILER_LABEL("GLContext", "SwapBuffers");
+  [mContext flushBuffer];
+  return true;
+}
 
-    bool ResizeOffscreen(const gfx::IntSize& aNewSize);
-
-    NSOpenGLContext *mContext;
-    GLuint mTempTextureName;
-};
 
 bool
 GLContextCGL::ResizeOffscreen(const gfx::IntSize& aNewSize)
 {
     return ResizeScreenBuffer(aNewSize);
 }
 
 static GLContextCGL *
@@ -247,17 +233,17 @@ CreateOffscreenFBOContext(bool aShare = 
     GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
     if (aShare && !shareContext) {
         // if there is no share context, then we can't use FBOs.
         return nullptr;
     }
 
     NSOpenGLContext *context = [[NSOpenGLContext alloc]
                                 initWithFormat:sCGLLibrary.PixelFormat()
-                                shareContext:shareContext ? shareContext->mContext : NULL];
+                                shareContext:shareContext ? shareContext->GetNSOpenGLContext() : NULL];
     if (!context) {
         return nullptr;
     }
 
     SurfaceCaps dummyCaps = SurfaceCaps::Any();
     nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
 
     return glContext.forget();
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 
-#include "GLContext.h"
+#include "GLContextEGL.h"
 
 #if defined(XP_UNIX)
 
 #ifdef MOZ_WIDGET_GTK
 #include <gdk/gdkx.h>
 // we're using default display for now
 #define GET_NATIVE_WINDOW(aWidget) (EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
 #elif defined(MOZ_WIDGET_GONK)
@@ -209,404 +209,343 @@ CreateSurfaceForWindow(nsIWidget* widget
             gScreenBounds.y = 0;
             sEGLLibrary.fQuerySurface(EGL_DISPLAY(), newSurface, LOCAL_EGL_WIDTH, &gScreenBounds.width);
             sEGLLibrary.fQuerySurface(EGL_DISPLAY(), newSurface, LOCAL_EGL_HEIGHT, &gScreenBounds.height);
         #endif
     #endif
     return newSurface;
 }
 
-class GLContextEGL : public GLContext
+GLContextEGL::GLContextEGL(
+                  const SurfaceCaps& caps,
+                  GLContext* shareContext,
+                  bool isOffscreen,
+                  EGLConfig config,
+                  EGLSurface surface,
+                  EGLContext context)
+    : GLContext(caps, shareContext, isOffscreen)
+    , mConfig(config)
+    , mSurface(surface)
+    , mSurfaceOverride(EGL_NO_SURFACE)
+    , mContext(context)
+    , mThebesSurface(nullptr)
+    , mBound(false)
+    , mIsPBuffer(false)
+    , mIsDoubleBuffered(false)
+    , mCanBindToTexture(false)
+    , mShareWithEGLImage(false)
 {
-    friend class TextureImageEGL;
+    // any EGL contexts will always be GLESv2
+    SetProfileVersion(ContextProfile::OpenGLES, 200);
 
-    static already_AddRefed<GLContextEGL>
-    CreateGLContext(const SurfaceCaps& caps,
-                    GLContextEGL *shareContext,
-                    bool isOffscreen,
-                    EGLConfig config,
-                    EGLSurface surface)
-    {
-        if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
-            NS_WARNING("Failed to bind API to GLES!");
-            return nullptr;
-        }
+#ifdef DEBUG
+    printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
+#endif
+#if defined(MOZ_WIDGET_GONK)
+    if (!mIsOffscreen) {
+        mHwc = HwcComposer2D::GetInstance();
+        MOZ_ASSERT(!mHwc->Initialized());
 
-        EGLContext eglShareContext = shareContext ? shareContext->mContext
-                                                  : EGL_NO_CONTEXT;
-        EGLint* attribs = sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
-                                                      : gContextAttribs;
+        if (mHwc->Init(EGL_DISPLAY(), mSurface)) {
+            NS_WARNING("HWComposer initialization failed!");
+            mHwc = nullptr;
+        }
+    }
+#endif
+}
+
+GLContextEGL::~GLContextEGL()
+{
+    MarkDestroyed();
+
+#ifdef DEBUG
+    printf_stderr("Destroying context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
+#endif
 
-        EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
-                                                        config,
-                                                        eglShareContext,
-                                                        attribs);
-        if (!context && shareContext) {
-            shareContext = nullptr;
-            context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
-                                                 config,
-                                                 EGL_NO_CONTEXT,
-                                                 attribs);
-        }
-        if (!context) {
-            NS_WARNING("Failed to create EGLContext!");
-            return nullptr;
+    sEGLLibrary.fDestroyContext(EGL_DISPLAY(), mContext);
+    mozilla::gl::DestroySurface(mSurface);
+}
+
+bool
+GLContextEGL::Init()
+{
+#if defined(ANDROID)
+    // We can't use LoadApitraceLibrary here because the GLContext
+    // expects its own handle to the GL library
+    if (!OpenLibrary(APITRACE_LIB))
+#endif
+        if (!OpenLibrary(GLES2_LIB)) {
+#if defined(XP_UNIX)
+            if (!OpenLibrary(GLES2_LIB2)) {
+                NS_WARNING("Couldn't load GLES2 LIB.");
+                return false;
+            }
+#endif
         }
 
-        nsRefPtr<GLContextEGL> glContext = new GLContextEGL(caps,
-                                                            shareContext,
-                                                            isOffscreen,
-                                                            config,
-                                                            surface,
-                                                            context);
-
-        if (!glContext->Init())
-            return nullptr;
-
-        return glContext.forget();
-    }
-
-public:
-    GLContextEGL(const SurfaceCaps& caps,
-                 GLContext* shareContext,
-                 bool isOffscreen,
-                 EGLConfig config,
-                 EGLSurface surface,
-                 EGLContext context)
-        : GLContext(caps, shareContext, isOffscreen)
-        , mConfig(config)
-        , mSurface(surface)
-        , mSurfaceOverride(EGL_NO_SURFACE)
-        , mContext(context)
-        , mThebesSurface(nullptr)
-        , mBound(false)
-        , mIsPBuffer(false)
-        , mIsDoubleBuffered(false)
-        , mCanBindToTexture(false)
-        , mShareWithEGLImage(false)
-    {
-        // any EGL contexts will always be GLESv2
-        SetProfileVersion(ContextProfile::OpenGLES, 200);
-
-#ifdef DEBUG
-        printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
-#endif
-#if defined(MOZ_WIDGET_GONK)
-        if (!mIsOffscreen) {
-            mHwc = HwcComposer2D::GetInstance();
-            MOZ_ASSERT(!mHwc->Initialized());
-
-            if (mHwc->Init(EGL_DISPLAY(), mSurface)) {
-                NS_WARNING("HWComposer initialization failed!");
-                mHwc = nullptr;
-            }
-        }
-#endif
-    }
+    SetupLookupFunction();
+    if (!InitWithPrefix("gl", true))
+        return false;
 
-    ~GLContextEGL()
-    {
-        MarkDestroyed();
-
-#ifdef DEBUG
-        printf_stderr("Destroying context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
-#endif
-
-        sEGLLibrary.fDestroyContext(EGL_DISPLAY(), mContext);
-        mozilla::gl::DestroySurface(mSurface);
-    }
-
-    GLContextType GetContextType() {
-        return ContextTypeEGL;
-    }
-
-    bool Init()
-    {
-#if defined(ANDROID)
-        // We can't use LoadApitraceLibrary here because the GLContext
-        // expects its own handle to the GL library
-        if (!OpenLibrary(APITRACE_LIB))
-#endif
-            if (!OpenLibrary(GLES2_LIB)) {
-#if defined(XP_UNIX)
-                if (!OpenLibrary(GLES2_LIB2)) {
-                    NS_WARNING("Couldn't load GLES2 LIB.");
-                    return false;
-                }
-#endif
-            }
-
-        SetupLookupFunction();
-        if (!InitWithPrefix("gl", true))
-            return false;
-
-        bool current = MakeCurrent();
-        if (!current) {
-            gfx::LogFailure(NS_LITERAL_CSTRING(
-                "Couldn't get device attachments for device."));
-            return false;
-        }
-
-        PR_STATIC_ASSERT(sizeof(GLint) >= sizeof(int32_t));
-        mMaxTextureImageSize = INT32_MAX;
-
-        mShareWithEGLImage = sEGLLibrary.HasKHRImageBase() &&
-                             sEGLLibrary.HasKHRImageTexture2D() &&
-                             IsExtensionSupported(OES_EGL_image);
-
-        return true;
+    bool current = MakeCurrent();
+    if (!current) {
+        gfx::LogFailure(NS_LITERAL_CSTRING(
+            "Couldn't get device attachments for device."));
+        return false;
     }
 
-    bool IsDoubleBuffered() {
-        return mIsDoubleBuffered;
-    }
+    PR_STATIC_ASSERT(sizeof(GLint) >= sizeof(int32_t));
+    mMaxTextureImageSize = INT32_MAX;
+
+    mShareWithEGLImage = sEGLLibrary.HasKHRImageBase() &&
+                          sEGLLibrary.HasKHRImageTexture2D() &&
+                          IsExtensionSupported(OES_EGL_image);
 
-    void SetIsDoubleBuffered(bool aIsDB) {
-        mIsDoubleBuffered = aIsDB;
-    }
+    return true;
+}
 
-    bool SupportsRobustness()
-    {
-        return sEGLLibrary.HasRobustness();
-    }
+bool
+GLContextEGL::BindTexImage()
+{
+    if (!mSurface)
+        return false;
 
-    virtual bool IsANGLE()
-    {
-        return sEGLLibrary.IsANGLE();
-    }
+    if (mBound && !ReleaseTexImage())
+        return false;
 
-    bool BindTexImage()
-    {
-        if (!mSurface)
-            return false;
+    EGLBoolean success = sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
+        (EGLSurface)mSurface, LOCAL_EGL_BACK_BUFFER);
+    if (success == LOCAL_EGL_FALSE)
+        return false;
 
-        if (mBound && !ReleaseTexImage())
-            return false;
+    mBound = true;
+    return true;
+}
 
-        EGLBoolean success = sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
-            (EGLSurface)mSurface, LOCAL_EGL_BACK_BUFFER);
-        if (success == LOCAL_EGL_FALSE)
-            return false;
-
-        mBound = true;
+bool
+GLContextEGL::ReleaseTexImage()
+{
+    if (!mBound)
         return true;
-    }
 
-    bool ReleaseTexImage()
-    {
-        if (!mBound)
-            return true;
+    if (!mSurface)
+        return false;
 
-        if (!mSurface)
-            return false;
-
-        EGLBoolean success;
-        success = sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
-                                               (EGLSurface)mSurface,
-                                               LOCAL_EGL_BACK_BUFFER);
-        if (success == LOCAL_EGL_FALSE)
-            return false;
+    EGLBoolean success;
+    success = sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
+                                            (EGLSurface)mSurface,
+                                            LOCAL_EGL_BACK_BUFFER);
+    if (success == LOCAL_EGL_FALSE)
+        return false;
 
-        mBound = false;
-        return true;
-    }
+    mBound = false;
+    return true;
+}
 
-    void SetEGLSurfaceOverride(EGLSurface surf) {
-        if (Screen()) {
-            /* Blit `draw` to `read` if we need to, before we potentially juggle
-             * `read` around. If we don't, we might attach a different `read`,
-             * and *then* hit AssureBlitted, which will blit a dirty `draw` onto
-             * the wrong `read`!
-             */
-            Screen()->AssureBlitted();
-        }
-
-        mSurfaceOverride = surf ? (EGLSurface) surf : mSurface;
-        MakeCurrent(true);
+void
+GLContextEGL::SetEGLSurfaceOverride(EGLSurface surf) {
+    if (Screen()) {
+        /* Blit `draw` to `read` if we need to, before we potentially juggle
+          * `read` around. If we don't, we might attach a different `read`,
+          * and *then* hit AssureBlitted, which will blit a dirty `draw` onto
+          * the wrong `read`!
+          */
+        Screen()->AssureBlitted();
     }
 
-    bool MakeCurrentImpl(bool aForce = false) {
-        bool succeeded = true;
+    mSurfaceOverride = surf ? (EGLSurface) surf : mSurface;
+    MakeCurrent(true);
+}
 
-        // Assume that EGL has the same problem as WGL does,
-        // where MakeCurrent with an already-current context is
-        // still expensive.
-        if (aForce || sEGLLibrary.fGetCurrentContext() != mContext) {
-            EGLSurface surface = mSurfaceOverride != EGL_NO_SURFACE
-                                 ? mSurfaceOverride
-                                 : mSurface;
-            succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
-                                                 surface, surface,
-                                                 mContext);
-            int eglError = sEGLLibrary.fGetError();
-            if (!succeeded) {
-                if (eglError == LOCAL_EGL_CONTEXT_LOST) {
-                    mContextLost = true;
-                    NS_WARNING("EGL context has been lost.");
-                } else {
-                    NS_WARNING("Failed to make GL context current!");
-#ifdef DEBUG
-                    printf_stderr("EGL Error: 0x%04x\n", eglError);
-#endif
-                }
-            }
-        }
-
-        return succeeded;
-    }
-
-    virtual bool IsCurrent() {
-        return sEGLLibrary.fGetCurrentContext() == mContext;
-    }
+bool
+GLContextEGL::MakeCurrentImpl(bool aForce) {
+    bool succeeded = true;
 
-    virtual bool
-    RenewSurface() {
-#ifndef MOZ_WIDGET_ANDROID
-        MOZ_CRASH("unimplemented");
-        // to support this on non-Android platforms, need to keep track of the nsIWidget that
-        // this GLContext was created for (with CreateForWindow) so that we know what to
-        // pass again to CreateSurfaceForWindow below.
-        // The reason why Android doesn't need this is that it delegates EGLSurface creation to
-        // Java code which is the only thing that knows about our actual widget.
+    // Assume that EGL has the same problem as WGL does,
+    // where MakeCurrent with an already-current context is
+    // still expensive.
+    if (aForce || sEGLLibrary.fGetCurrentContext() != mContext) {
+        EGLSurface surface = mSurfaceOverride != EGL_NO_SURFACE
+                              ? mSurfaceOverride
+                              : mSurface;
+        succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
+                                              surface, surface,
+                                              mContext);
+        int eglError = sEGLLibrary.fGetError();
+        if (!succeeded) {
+            if (eglError == LOCAL_EGL_CONTEXT_LOST) {
+                mContextLost = true;
+                NS_WARNING("EGL context has been lost.");
+            } else {
+                NS_WARNING("Failed to make GL context current!");
+#ifdef DEBUG
+                printf_stderr("EGL Error: 0x%04x\n", eglError);
 #endif
-        // unconditionally release the surface and create a new one. Don't try to optimize this away.
-        // If we get here, then by definition we know that we want to get a new surface.
-        ReleaseSurface();
-        mSurface = mozilla::gl::CreateSurfaceForWindow(nullptr, mConfig); // the nullptr here is where we assume Android.
-        if (mSurface == EGL_NO_SURFACE) {
-            return false;
-        }
-        return MakeCurrent(true);
-    }
-
-    virtual void
-    ReleaseSurface() {
-        DestroySurface(mSurface);
-        mSurface = nullptr;
-    }
-
-    bool SetupLookupFunction()
-    {
-        mLookupFunc = (PlatformLookupFunction)sEGLLibrary.mSymbols.fGetProcAddress;
-        return true;
-    }
-
-    void *GetNativeData(NativeDataType aType)
-    {
-        switch (aType) {
-        case NativeGLContext:
-            return mContext;
-
-        default:
-            return nullptr;
+            }
         }
     }
 
-    bool SwapBuffers()
-    {
-        if (mSurface) {
-#ifdef MOZ_WIDGET_GONK
-            if (!mIsOffscreen) {
-                if (mHwc) {
-                    return mHwc->Render(EGL_DISPLAY(), mSurface);
-                } else {
-                    return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), mSurface);
-                }
-            } else
+    return succeeded;
+}
+
+bool
+GLContextEGL::IsCurrent() {
+    return sEGLLibrary.fGetCurrentContext() == mContext;
+}
+
+bool
+GLContextEGL::RenewSurface() {
+#ifndef MOZ_WIDGET_ANDROID
+    MOZ_CRASH("unimplemented");
+    // to support this on non-Android platforms, need to keep track of the nsIWidget that
+    // this GLContext was created for (with CreateForWindow) so that we know what to
+    // pass again to CreateSurfaceForWindow below.
+    // The reason why Android doesn't need this is that it delegates EGLSurface creation to
+    // Java code which is the only thing that knows about our actual widget.
 #endif
-                return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
-        } else {
-            return false;
-        }
+    // unconditionally release the surface and create a new one. Don't try to optimize this away.
+    // If we get here, then by definition we know that we want to get a new surface.
+    ReleaseSurface();
+    mSurface = mozilla::gl::CreateSurfaceForWindow(nullptr, mConfig); // the nullptr here is where we assume Android.
+    if (mSurface == EGL_NO_SURFACE) {
+        return false;
     }
+    return MakeCurrent(true);
+}
+
+void
+GLContextEGL::ReleaseSurface() {
+    DestroySurface(mSurface);
+    mSurface = nullptr;
+}
+
+bool
+GLContextEGL::SetupLookupFunction()
+{
+    mLookupFunc = (PlatformLookupFunction)sEGLLibrary.mSymbols.fGetProcAddress;
+    return true;
+}
 
-    // hold a reference to the given surface
-    // for the lifetime of this context.
-    void HoldSurface(gfxASurface *aSurf) {
-        mThebesSurface = aSurf;
+bool
+GLContextEGL::SwapBuffers()
+{
+    if (mSurface) {
+#ifdef MOZ_WIDGET_GONK
+        if (!mIsOffscreen) {
+            if (mHwc) {
+                return mHwc->Render(EGL_DISPLAY(), mSurface);
+            } else {
+                return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), mSurface);
+            }
+        } else
+#endif
+            return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
+    } else {
+        return false;
     }
+}
 
-    EGLContext Context() {
-        return mContext;
+// hold a reference to the given surface
+// for the lifetime of this context.
+void
+GLContextEGL::HoldSurface(gfxASurface *aSurf) {
+    mThebesSurface = aSurf;
+}
+
+already_AddRefed<GLContextEGL>
+GLContextEGL::CreateGLContext(const SurfaceCaps& caps,
+                GLContextEGL *shareContext,
+                bool isOffscreen,
+                EGLConfig config,
+                EGLSurface surface)
+{
+    if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
+        NS_WARNING("Failed to bind API to GLES!");
+        return nullptr;
     }
 
-    bool BindTex2DOffscreen(GLContext *aOffscreen);
-    void UnbindTex2DOffscreen(GLContext *aOffscreen);
-    bool ResizeOffscreen(const gfx::IntSize& aNewSize);
-    void BindOffscreenFramebuffer();
-
-    static already_AddRefed<GLContextEGL>
-    CreateEGLPixmapOffscreenContext(const gfxIntSize& size);
+    EGLContext eglShareContext = shareContext ? shareContext->mContext
+                                              : EGL_NO_CONTEXT;
+    EGLint* attribs = sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
+                                                  : gContextAttribs;
 
-    static already_AddRefed<GLContextEGL>
-    CreateEGLPBufferOffscreenContext(const gfxIntSize& size);
-
-protected:
-    friend class GLContextProviderEGL;
+    EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
+                                                    config,
+                                                    eglShareContext,
+                                                    attribs);
+    if (!context && shareContext) {
+        shareContext = nullptr;
+        context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
+                                              config,
+                                              EGL_NO_CONTEXT,
+                                              attribs);
+    }
+    if (!context) {
+        NS_WARNING("Failed to create EGLContext!");
+        return nullptr;
+    }
 
-    EGLConfig  mConfig;
-    EGLSurface mSurface;
-    EGLSurface mSurfaceOverride;
-    EGLContext mContext;
-    nsRefPtr<gfxASurface> mThebesSurface;
-    bool mBound;
+    nsRefPtr<GLContextEGL> glContext = new GLContextEGL(caps,
+                                                        shareContext,
+                                                        isOffscreen,
+                                                        config,
+                                                        surface,
+                                                        context);
+
+    if (!glContext->Init())
+        return nullptr;
+
+    return glContext.forget();
+}
 
-    bool mIsPBuffer;
-    bool mIsDoubleBuffered;
-    bool mCanBindToTexture;
-    bool mShareWithEGLImage;
-#ifdef MOZ_WIDGET_GONK
-    nsRefPtr<HwcComposer2D> mHwc;
-#endif
+EGLSurface
+GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
+                                                   EGLenum bindToTextureFormat,
+                                                   gfxIntSize& pbsize)
+{
+    nsTArray<EGLint> pbattrs(16);
+    EGLSurface surface = nullptr;
+
+TRY_AGAIN_POWER_OF_TWO:
+    pbattrs.Clear();
+    pbattrs.AppendElement(LOCAL_EGL_WIDTH); pbattrs.AppendElement(pbsize.width);
+    pbattrs.AppendElement(LOCAL_EGL_HEIGHT); pbattrs.AppendElement(pbsize.height);
+
+    if (bindToTextureFormat != LOCAL_EGL_NONE) {
+        pbattrs.AppendElement(LOCAL_EGL_TEXTURE_TARGET);
+        pbattrs.AppendElement(LOCAL_EGL_TEXTURE_2D);
 
-    static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
-                                                           EGLenum bindToTextureFormat,
-                                                           gfxIntSize& pbsize)
-    {
-        nsTArray<EGLint> pbattrs(16);
-        EGLSurface surface = nullptr;
+        pbattrs.AppendElement(LOCAL_EGL_TEXTURE_FORMAT);
+        pbattrs.AppendElement(bindToTextureFormat);
+    }
+
+    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
+      pbattrs.AppendElement(gTerminationAttribs[i]);
+    }
 
-    TRY_AGAIN_POWER_OF_TWO:
-        pbattrs.Clear();
-        pbattrs.AppendElement(LOCAL_EGL_WIDTH); pbattrs.AppendElement(pbsize.width);
-        pbattrs.AppendElement(LOCAL_EGL_HEIGHT); pbattrs.AppendElement(pbsize.height);
+    surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]);
+    if (!surface) {
+        if (!is_power_of_two(pbsize.width) ||
+            !is_power_of_two(pbsize.height))
+        {
+            if (!is_power_of_two(pbsize.width))
+                pbsize.width = next_power_of_two(pbsize.width);
+            if (!is_power_of_two(pbsize.height))
+                pbsize.height = next_power_of_two(pbsize.height);
 
-        if (bindToTextureFormat != LOCAL_EGL_NONE) {
-            pbattrs.AppendElement(LOCAL_EGL_TEXTURE_TARGET);
-            pbattrs.AppendElement(LOCAL_EGL_TEXTURE_2D);
-
-            pbattrs.AppendElement(LOCAL_EGL_TEXTURE_FORMAT);
-            pbattrs.AppendElement(bindToTextureFormat);
+            NS_WARNING("Failed to create pbuffer, trying power of two dims");
+            goto TRY_AGAIN_POWER_OF_TWO;
         }
 
-        for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
-          pbattrs.AppendElement(gTerminationAttribs[i]);
-        }
+        NS_WARNING("Failed to create pbuffer surface");
+        return nullptr;
+    }
 
-        surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]);
-        if (!surface) {
-            if (!is_power_of_two(pbsize.width) ||
-                !is_power_of_two(pbsize.height))
-            {
-                if (!is_power_of_two(pbsize.width))
-                    pbsize.width = next_power_of_two(pbsize.width);
-                if (!is_power_of_two(pbsize.height))
-                    pbsize.height = next_power_of_two(pbsize.height);
-
-                NS_WARNING("Failed to create pbuffer, trying power of two dims");
-                goto TRY_AGAIN_POWER_OF_TWO;
-            }
-
-            NS_WARNING("Failed to create pbuffer surface");
-            return nullptr;
-        }
-
-        return surface;
-    }
-};
+    return surface;
+}
 
 bool
 GLContextEGL::ResizeOffscreen(const gfx::IntSize& aNewSize)
 {
     return ResizeScreenBuffer(aNewSize);
 }
 
 static const EGLint kEGLConfigAttribsOffscreenPBuffer[] = {
@@ -889,22 +828,12 @@ GLContextProviderEGL::GetGlobalContext(c
     return nullptr;
 }
 
 void
 GLContextProviderEGL::Shutdown()
 {
 }
 
-GLContextEGL* DowncastGLContextEGL(GLContext* context)
-{
-    return static_cast<GLContextEGL*>(context);
-}
-
-void SetEGLSurfaceOverride(GLContextEGL* context, EGLSurface surf)
-{
-    context->SetEGLSurfaceOverride(surf);
-}
-
 } /* namespace gl */
 } /* namespace mozilla */
 
 #undef EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -23,17 +23,17 @@
 #include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "GLXLibrary.h"
 #include "gfxXlibSurface.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
-#include "GLContext.h"
+#include "GLContextGLX.h"
 #include "gfxUtils.h"
 #include "gfx2DGlue.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #ifdef MOZ_WIDGET_GTK
 #include "gfxPlatformGtk.h"
 #endif
@@ -41,18 +41,16 @@
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace gl {
 
 GLXLibrary sGLXLibrary[GLXLibrary::LIBS_MAX];
 GLXLibrary& sDefGLXLib = sGLXLibrary[GLXLibrary::OPENGL_LIB];
 
-typedef GLXLibrary::LibraryType LibType;
-
 static LibType gCurrLib = GLXLibrary::OPENGL_LIB;
 
 LibType
 GLXLibrary::SelectLibrary(const ContextFlags& aFlags)
 {
   return (aFlags & ContextFlagsMesaLLVMPipe)
           ? GLXLibrary::MESA_LLVMPIPE_LIB
           : GLXLibrary::OPENGL_LIB;
@@ -739,243 +737,218 @@ GLXLibrary::xCreateContextAttribs(Displa
                                                       config,
                                                       share_list,
                                                       direct,
                                                       attrib_list);
     AFTER_GLX_CALL;
     return result;
 }
 
-class GLContextGLX : public GLContext
+already_AddRefed<GLContextGLX>
+GLContextGLX::CreateGLContext(
+                  const SurfaceCaps& caps,
+                  GLContextGLX* shareContext,
+                  bool isOffscreen,
+                  Display* display,
+                  GLXDrawable drawable,
+                  GLXFBConfig cfg,
+                  bool deleteDrawable,
+                  LibType libType,
+                  gfxXlibSurface* pixmap)
 {
-public:
-    static already_AddRefed<GLContextGLX>
-    CreateGLContext(const SurfaceCaps& caps,
-                    GLContextGLX* shareContext,
-                    bool isOffscreen,
-                    Display* display,
-                    GLXDrawable drawable,
-                    GLXFBConfig cfg,
-                    bool deleteDrawable,
-                    LibType libType = GLXLibrary::OPENGL_LIB,
-                    gfxXlibSurface* pixmap = nullptr)
-    {
-        GLXLibrary& glx = sGLXLibrary[libType];
+    GLXLibrary& glx = sGLXLibrary[libType];
 
-        int db = 0;
-        int err = glx.xGetFBConfigAttrib(display, cfg,
-                                         LOCAL_GLX_DOUBLEBUFFER, &db);
-        if (LOCAL_GLX_BAD_ATTRIBUTE != err) {
+    int db = 0;
+    int err = glx.xGetFBConfigAttrib(display, cfg,
+                                      LOCAL_GLX_DOUBLEBUFFER, &db);
+    if (LOCAL_GLX_BAD_ATTRIBUTE != err) {
 #ifdef DEBUG
-            if (DebugMode()) {
-                printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
-            }
+        if (DebugMode()) {
+            printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
+        }
 #endif
-        }
+    }
 
-        GLXContext context;
-        nsRefPtr<GLContextGLX> glContext;
-        bool error;
+    GLXContext context;
+    nsRefPtr<GLContextGLX> glContext;
+    bool error;
 
-        ScopedXErrorHandler xErrorHandler;
+    ScopedXErrorHandler xErrorHandler;
 
 TRY_AGAIN_NO_SHARING:
 
-        error = false;
+    error = false;
 
-        GLXContext glxContext = shareContext ? shareContext->mContext : nullptr;
-        if (glx.HasRobustness()) {
-            int attrib_list[] = {
-                LOCAL_GL_CONTEXT_FLAGS_ARB, LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
-                LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB,
-                0,
-            };
+    GLXContext glxContext = shareContext ? shareContext->mContext : nullptr;
+    if (glx.HasRobustness()) {
+        int attrib_list[] = {
+            LOCAL_GL_CONTEXT_FLAGS_ARB, LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+            LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB,
+            0,
+        };
 
-            context = glx.xCreateContextAttribs(
-                display,
-                cfg,
-                glxContext,
-                True,
-                attrib_list);
-        } else {
-            context = glx.xCreateNewContext(
-                display,
-                cfg,
-                LOCAL_GLX_RGBA_TYPE,
-                glxContext,
-                True);
-        }
+        context = glx.xCreateContextAttribs(
+            display,
+            cfg,
+            glxContext,
+            True,
+            attrib_list);
+    } else {
+        context = glx.xCreateNewContext(
+            display,
+            cfg,
+            LOCAL_GLX_RGBA_TYPE,
+            glxContext,
+            True);
+    }
 
-        if (context) {
-            glContext = new GLContextGLX(caps,
-                                         shareContext,
-                                         isOffscreen,
-                                         display,
-                                         drawable,
-                                         context,
-                                         deleteDrawable,
-                                         db,
-                                         pixmap,
-                                         libType);
-            if (!glContext->Init())
-                error = true;
-        } else {
+    if (context) {
+        glContext = new GLContextGLX(caps,
+                                      shareContext,
+                                      isOffscreen,
+                                      display,
+                                      drawable,
+                                      context,
+                                      deleteDrawable,
+                                      db,
+                                      pixmap,
+                                      libType);
+        if (!glContext->Init())
             error = true;
+    } else {
+        error = true;
+    }
+
+    error |= xErrorHandler.SyncAndGetError(display);
+
+    if (error) {
+        if (shareContext) {
+            shareContext = nullptr;
+            goto TRY_AGAIN_NO_SHARING;
         }
 
-        error |= xErrorHandler.SyncAndGetError(display);
-
-        if (error) {
-            if (shareContext) {
-                shareContext = nullptr;
-                goto TRY_AGAIN_NO_SHARING;
-            }
-
-            NS_WARNING("Failed to create GLXContext!");
-            glContext = nullptr; // note: this must be done while the graceful X error handler is set,
-                                // because glxMakeCurrent can give a GLXBadDrawable error
-        }
-
-        return glContext.forget();
+        NS_WARNING("Failed to create GLXContext!");
+        glContext = nullptr; // note: this must be done while the graceful X error handler is set,
+                            // because glxMakeCurrent can give a GLXBadDrawable error
     }
 
-    ~GLContextGLX()
-    {
-        MarkDestroyed();
+    return glContext.forget();
+}
 
-        // see bug 659842 comment 76
-#ifdef DEBUG
-        bool success =
-#endif
-        mGLX->xMakeCurrent(mDisplay, None, nullptr);
-        NS_ABORT_IF_FALSE(success,
-            "glXMakeCurrent failed to release GL context before we call glXDestroyContext!");
-
-        mGLX->xDestroyContext(mDisplay, mContext);
+GLContextGLX::~GLContextGLX()
+{
+    MarkDestroyed();
 
-        if (mDeleteDrawable) {
-            mGLX->xDestroyPixmap(mDisplay, mDrawable);
-        }
-    }
+    // see bug 659842 comment 76
+#ifdef DEBUG
+    bool success =
+#endif
+    mGLX->xMakeCurrent(mDisplay, None, nullptr);
+    NS_ABORT_IF_FALSE(success,
+        "glXMakeCurrent failed to release GL context before we call glXDestroyContext!");
 
-    GLContextType GetContextType() {
-        return ContextTypeGLX;
-    }
+    mGLX->xDestroyContext(mDisplay, mContext);
 
-    bool Init()
-    {
-        SetupLookupFunction();
-        if (!InitWithPrefix("gl", true)) {
-            return false;
-        }
+    if (mDeleteDrawable) {
+        mGLX->xDestroyPixmap(mDisplay, mDrawable);
+    }
+}
 
-        if (!IsExtensionSupported(EXT_framebuffer_object))
-            return false;
-
-        return true;
+bool
+GLContextGLX::Init()
+{
+    SetupLookupFunction();
+    if (!InitWithPrefix("gl", true)) {
+        return false;
     }
 
-    bool MakeCurrentImpl(bool aForce = false)
-    {
-        bool succeeded = true;
+    if (!IsExtensionSupported(EXT_framebuffer_object))
+        return false;
 
-        // With the ATI FGLRX driver, glxMakeCurrent is very slow even when the context doesn't change.
-        // (This is not the case with other drivers such as NVIDIA).
-        // So avoid calling it more than necessary. Since GLX documentation says that:
-        //     "glXGetCurrentContext returns client-side information.
-        //      It does not make a round trip to the server."
-        // I assume that it's not worth using our own TLS slot here.
-        if (aForce || mGLX->xGetCurrentContext() != mContext) {
-            succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
-            NS_ASSERTION(succeeded, "Failed to make GL context current!");
-        }
-
-        return succeeded;
-    }
-
-    virtual bool IsCurrent() {
-        return mGLX->xGetCurrentContext() == mContext;
-    }
+    return true;
+}
 
-    bool SetupLookupFunction()
-    {
-        mLookupFunc = (PlatformLookupFunction)&GLXLibrary::xGetProcAddress;
-        return true;
-    }
-
-    void *GetNativeData(NativeDataType aType)
-    {
-        switch(aType) {
-        case NativeGLContext:
-            return mContext;
+bool
+GLContextGLX::MakeCurrentImpl(bool aForce)
+{
+    bool succeeded = true;
 
-        case NativeThebesSurface:
-            return mPixmap;
-
-        default:
-            return nullptr;
-        }
-    }
-
-    bool IsDoubleBuffered()
-    {
-        return mDoubleBuffered;
+    // With the ATI FGLRX driver, glxMakeCurrent is very slow even when the context doesn't change.
+    // (This is not the case with other drivers such as NVIDIA).
+    // So avoid calling it more than necessary. Since GLX documentation says that:
+    //     "glXGetCurrentContext returns client-side information.
+    //      It does not make a round trip to the server."
+    // I assume that it's not worth using our own TLS slot here.
+    if (aForce || mGLX->xGetCurrentContext() != mContext) {
+        succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
+        NS_ASSERTION(succeeded, "Failed to make GL context current!");
     }
 
-    bool SupportsRobustness()
-    {
-        return mGLX->HasRobustness();
-    }
+    return succeeded;
+}
+
+bool
+GLContextGLX::IsCurrent() {
+    return mGLX->xGetCurrentContext() == mContext;
+}
 
-    bool SwapBuffers()
-    {
-        if (!mDoubleBuffered)
-            return false;
-        mGLX->xSwapBuffers(mDisplay, mDrawable);
-        mGLX->xWaitGL();
-        return true;
-    }
+bool
+GLContextGLX::SetupLookupFunction()
+{
+    mLookupFunc = (PlatformLookupFunction)&GLXLibrary::xGetProcAddress;
+    return true;
+}
 
-private:
-    friend class GLContextProviderGLX;
+bool
+GLContextGLX::IsDoubleBuffered()
+{
+    return mDoubleBuffered;
+}
+
+bool
+GLContextGLX::SupportsRobustness()
+{
+    return mGLX->HasRobustness();
+}
 
-    GLContextGLX(const SurfaceCaps& caps,
-                 GLContext* shareContext,
-                 bool isOffscreen,
-                 Display *aDisplay,
-                 GLXDrawable aDrawable,
-                 GLXContext aContext,
-                 bool aDeleteDrawable,
-                 bool aDoubleBuffered,
-                 gfxXlibSurface *aPixmap,
-                 LibType libType)
-        : GLContext(caps, shareContext, isOffscreen),//aDeleteDrawable ? true : false, aShareContext, ),
-          mContext(aContext),
-          mDisplay(aDisplay),
-          mDrawable(aDrawable),
-          mDeleteDrawable(aDeleteDrawable),
-          mDoubleBuffered(aDoubleBuffered),
-          mGLX(&sGLXLibrary[libType]),
-          mPixmap(aPixmap)
-    {
-        MOZ_ASSERT(mGLX);
-        // See 899855
-        SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
-    }
+bool
+GLContextGLX::SwapBuffers()
+{
+    if (!mDoubleBuffered)
+        return false;
+    mGLX->xSwapBuffers(mDisplay, mDrawable);
+    mGLX->xWaitGL();
+    return true;
+}
 
-    GLXContext mContext;
-    Display *mDisplay;
-    GLXDrawable mDrawable;
-    bool mDeleteDrawable;
-    bool mDoubleBuffered;
+GLContextGLX::GLContextGLX(
+                  const SurfaceCaps& caps,
+                  GLContext* shareContext,
+                  bool isOffscreen,
+                  Display *aDisplay,
+                  GLXDrawable aDrawable,
+                  GLXContext aContext,
+                  bool aDeleteDrawable,
+                  bool aDoubleBuffered,
+                  gfxXlibSurface *aPixmap,
+                  LibType libType)
+    : GLContext(caps, shareContext, isOffscreen),//aDeleteDrawable ? true : false, aShareContext, ),
+      mContext(aContext),
+      mDisplay(aDisplay),
+      mDrawable(aDrawable),
+      mDeleteDrawable(aDeleteDrawable),
+      mDoubleBuffered(aDoubleBuffered),
+      mGLX(&sGLXLibrary[libType]),
+      mPixmap(aPixmap)
+{
+    MOZ_ASSERT(mGLX);
+    // See 899855
+    SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
+}
 
-    GLXLibrary* mGLX;
-
-    nsRefPtr<gfxXlibSurface> mPixmap;
-};
 
 static GLContextGLX *
 GetGlobalContextGLX(const ContextFlags aFlags = ContextFlagsNone)
 {
     return static_cast<GLContextGLX*>(GLContextProviderGLX::GetGlobalContext(aFlags));
 }
 
 static bool
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -1,37 +1,34 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GLContextProvider.h"
-#include "GLContext.h"
+#include "GLContextWGL.h"
 #include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
-#include "WGLLibrary.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "gfxWindowsSurface.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "prenv.h"
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace gl {
 
-typedef WGLLibrary::LibraryType LibType;
-
 WGLLibrary sWGLLib[WGLLibrary::LIBS_MAX];
 
 LibType
 WGLLibrary::SelectLibrary(const ContextFlags& aFlags)
 {
   return (aFlags & ContextFlagsMesaLLVMPipe) 
           ? WGLLibrary::MESA_LLVMPIPE_LIB
           : WGLLibrary::OPENGL_LIB;
@@ -248,172 +245,145 @@ WGLLibrary::EnsureInitialized(bool aUseM
         mInitialized = false;
         return false;
     }
 
     reporter.SetSuccessful();
     return true;
 }
 
-class GLContextWGL : public GLContext
+GLContextWGL::GLContextWGL(
+                  const SurfaceCaps& caps,
+                  GLContext* sharedContext,
+                  bool isOffscreen,
+                  HDC aDC,
+                  HGLRC aContext,
+                  LibType aLibUsed,
+                  HWND aWindow)
+    : GLContext(caps, sharedContext, isOffscreen),
+      mDC(aDC),
+      mContext(aContext),
+      mWnd(aWindow),
+      mPBuffer(nullptr),
+      mPixelFormat(0),
+      mLibType(aLibUsed),
+      mIsDoubleBuffered(false)
 {
-public:
-    // From Window: (possibly for offscreen!)
-    GLContextWGL(const SurfaceCaps& caps,
-                 GLContext* sharedContext,
-                 bool isOffscreen,
-                 HDC aDC,
-                 HGLRC aContext,
-                 LibType aLibUsed,
-                 HWND aWindow = nullptr)
-        : GLContext(caps, sharedContext, isOffscreen),
-          mDC(aDC),
-          mContext(aContext),
-          mWnd(aWindow),
-          mPBuffer(nullptr),
-          mPixelFormat(0),
-          mLibType(aLibUsed),
-          mIsDoubleBuffered(false)
-    {
-        // See 899855
-        SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
-    }
+    // See 899855
+    SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
+}
 
-    // From PBuffer
-    GLContextWGL(const SurfaceCaps& caps,
-                 GLContext* sharedContext,
-                 bool isOffscreen,
-                 HANDLE aPbuffer,
-                 HDC aDC,
-                 HGLRC aContext,
-                 int aPixelFormat,
-                 LibType aLibUsed)
-        : GLContext(caps, sharedContext, isOffscreen),
-          mDC(aDC),
-          mContext(aContext),
-          mWnd(nullptr),
-          mPBuffer(aPbuffer),
-          mPixelFormat(aPixelFormat),
-          mLibType(aLibUsed),
-          mIsDoubleBuffered(false)
-    {
-        // See 899855
-        SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
-    }
+GLContextWGL::GLContextWGL(
+                  const SurfaceCaps& caps,
+                  GLContext* sharedContext,
+                  bool isOffscreen,
+                  HANDLE aPbuffer,
+                  HDC aDC,
+                  HGLRC aContext,
+                  int aPixelFormat,
+                  LibType aLibUsed)
+    : GLContext(caps, sharedContext, isOffscreen),
+      mDC(aDC),
+      mContext(aContext),
+      mWnd(nullptr),
+      mPBuffer(aPbuffer),
+      mPixelFormat(aPixelFormat),
+      mLibType(aLibUsed),
+      mIsDoubleBuffered(false)
+{
+    // See 899855
+    SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
+}
 
-    ~GLContextWGL()
-    {
-        MarkDestroyed();
+GLContextWGL::~GLContextWGL()
+{
+    MarkDestroyed();
+
+    sWGLLib[mLibType].fDeleteContext(mContext);
 
-        sWGLLib[mLibType].fDeleteContext(mContext);
+    if (mPBuffer)
+        sWGLLib[mLibType].fDestroyPbuffer(mPBuffer);
+    if (mWnd)
+        DestroyWindow(mWnd);
+}
 
-        if (mPBuffer)
-            sWGLLib[mLibType].fDestroyPbuffer(mPBuffer);
-        if (mWnd)
-            DestroyWindow(mWnd);
-    }
+bool
+GLContextWGL::Init()
+{
+    if (!mDC || !mContext)
+        return false;
 
-    GLContextType GetContextType() {
-        return ContextTypeWGL;
-    }
+    // see bug 929506 comment 29. wglGetProcAddress requires a current context.
+    if (!sWGLLib[mLibType].fMakeCurrent(mDC, mContext))
+        return false;
 
-    bool Init()
-    {
-        if (!mDC || !mContext)
-            return false;
+    SetupLookupFunction();
+    if (!InitWithPrefix("gl", true))
+        return false;
+
+    return true;
+}
 
-        // see bug 929506 comment 29. wglGetProcAddress requires a current context.
-        if (!sWGLLib[mLibType].fMakeCurrent(mDC, mContext))
-            return false;
+bool
+GLContextWGL::MakeCurrentImpl(bool aForce)
+{
+    BOOL succeeded = true;
 
-        SetupLookupFunction();
-        if (!InitWithPrefix("gl", true))
-            return false;
-
-        return true;
+    // wglGetCurrentContext seems to just pull the HGLRC out
+    // of its TLS slot, so no need to do our own tls slot.
+    // You would think that wglMakeCurrent would avoid doing
+    // work if mContext was already current, but not so much..
+    if (aForce || sWGLLib[mLibType].fGetCurrentContext() != mContext) {
+        succeeded = sWGLLib[mLibType].fMakeCurrent(mDC, mContext);
+        NS_ASSERTION(succeeded, "Failed to make GL context current!");
     }
 
-    bool MakeCurrentImpl(bool aForce = false)
-    {
-        BOOL succeeded = true;
+    return succeeded;
+}
 
-        // wglGetCurrentContext seems to just pull the HGLRC out
-        // of its TLS slot, so no need to do our own tls slot.
-        // You would think that wglMakeCurrent would avoid doing
-        // work if mContext was already current, but not so much..
-        if (aForce || sWGLLib[mLibType].fGetCurrentContext() != mContext) {
-            succeeded = sWGLLib[mLibType].fMakeCurrent(mDC, mContext);
-            NS_ASSERTION(succeeded, "Failed to make GL context current!");
-        }
-
-        return succeeded;
-    }
+bool
+GLContextWGL::IsCurrent() {
+    return sWGLLib[mLibType].fGetCurrentContext() == mContext;
+}
 
-    virtual bool IsCurrent() {
-        return sWGLLib[mLibType].fGetCurrentContext() == mContext;
-    }
-
-    void SetIsDoubleBuffered(bool aIsDB) {
-        mIsDoubleBuffered = aIsDB;
-    }
+void
+GLContextWGL::SetIsDoubleBuffered(bool aIsDB) {
+    mIsDoubleBuffered = aIsDB;
+}
 
-    virtual bool IsDoubleBuffered() {
-        return mIsDoubleBuffered;
-    }
-
-    bool SupportsRobustness()
-    {
-        return sWGLLib[mLibType].HasRobustness();
-    }
-
-    virtual bool SwapBuffers() {
-        if (!mIsDoubleBuffered)
-            return false;
-        return ::SwapBuffers(mDC);
-    }
+bool
+GLContextWGL::IsDoubleBuffered() {
+    return mIsDoubleBuffered;
+}
 
-    bool SetupLookupFunction()
-    {
-        // Make sure that we have a ref to the OGL library;
-        // when run under CodeXL, wglGetProcAddress won't return
-        // the right thing for some core functions.
-        MOZ_ASSERT(mLibrary == nullptr);
+bool
+GLContextWGL::SupportsRobustness()
+{
+    return sWGLLib[mLibType].HasRobustness();
+}
 
-        mLibrary = sWGLLib[mLibType].GetOGLLibrary();
-        mLookupFunc = (PlatformLookupFunction)sWGLLib[mLibType].fGetProcAddress;
-        return true;
-    }
-
-    void *GetNativeData(NativeDataType aType)
-    {
-        switch (aType) {
-        case NativeGLContext:
-            return mContext;
+bool
+GLContextWGL::SwapBuffers() {
+    if (!mIsDoubleBuffered)
+        return false;
+    return ::SwapBuffers(mDC);
+}
 
-        default:
-            return nullptr;
-        }
-    }
-
-    bool ResizeOffscreen(const gfx::IntSize& aNewSize);
-
-    HGLRC Context() { return mContext; }
+bool
+GLContextWGL::SetupLookupFunction()
+{
+    // Make sure that we have a ref to the OGL library;
+    // when run under CodeXL, wglGetProcAddress won't return
+    // the right thing for some core functions.
+    MOZ_ASSERT(mLibrary == nullptr);
 
-protected:
-    friend class GLContextProviderWGL;
-
-    HDC mDC;
-    HGLRC mContext;
-    HWND mWnd;
-    HANDLE mPBuffer;
-    int mPixelFormat;
-    LibType mLibType;
-    bool mIsDoubleBuffered;
-};
-
+    mLibrary = sWGLLib[mLibType].GetOGLLibrary();
+    mLookupFunc = (PlatformLookupFunction)sWGLLib[mLibType].fGetProcAddress;
+    return true;
+}
 
 static bool
 GetMaxSize(HDC hDC, int format, gfxIntSize& size, LibType aLibToUse)
 {
     int query[] = {LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB, LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB};
     int result[2];
 
     // (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues)
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLContextWGL.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 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 GLCONTEXTWGL_H_
+#define GLCONTEXTWGL_H_
+
+#include "GLContext.h"
+#include "WGLLibrary.h"
+
+namespace mozilla {
+namespace gl {
+
+typedef WGLLibrary::LibraryType LibType;
+
+class GLContextWGL : public GLContext
+{
+public:
+    // From Window: (possibly for offscreen!)
+    GLContextWGL(const SurfaceCaps& caps,
+                 GLContext* sharedContext,
+                 bool isOffscreen,
+                 HDC aDC,
+                 HGLRC aContext,
+                 LibType aLibUsed,
+                 HWND aWindow = nullptr);
+
+    // From PBuffer
+    GLContextWGL(const SurfaceCaps& caps,
+                 GLContext* sharedContext,
+                 bool isOffscreen,
+                 HANDLE aPbuffer,
+                 HDC aDC,
+                 HGLRC aContext,
+                 int aPixelFormat,
+                 LibType aLibUsed);
+
+    ~GLContextWGL();
+
+    virtual GLContextType GetContextType() MOZ_OVERRIDE { return ContextTypeWGL; }
+
+    static GLContextWGL* Cast(GLContext* gl) {
+        MOZ_ASSERT(gl->GetContextType() == ContextTypeWGL);
+        return static_cast<GLContextWGL*>(gl);
+    }
+
+    bool Init();
+
+    bool MakeCurrentImpl(bool aForce = false);
+
+    virtual bool IsCurrent();
+
+    void SetIsDoubleBuffered(bool aIsDB);
+
+    virtual bool IsDoubleBuffered();
+
+    bool SupportsRobustness();
+
+    virtual bool SwapBuffers();
+
+    bool SetupLookupFunction();
+
+    bool ResizeOffscreen(const gfx::IntSize& aNewSize);
+
+    HGLRC Context() { return mContext; }
+
+protected:
+    friend class GLContextProviderWGL;
+
+    HDC mDC;
+    HGLRC mContext;
+    HWND mWnd;
+    HANDLE mPBuffer;
+    int mPixelFormat;
+    LibType mLibType;
+    bool mIsDoubleBuffered;
+};
+
+}
+}
+
+#endif // GLCONTEXTWGL_H_
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -524,17 +524,17 @@ GLReadTexImageHelper::ReadTexImage(GLuin
         default: /* Already checked above */
             break;
         }
 
         /* Set required GL state */
         mGL->fDisable(LOCAL_GL_BLEND);
         mGL->fDisable(LOCAL_GL_SCISSOR_TEST);
 
-        mGL->PushViewportRect(nsIntRect(0, 0, aSize.width, aSize.height));
+        ScopedViewportRect(mGL, 0, 0, aSize.width, aSize.height);
 
         /* Setup renderbuffer */
         mGL->fGenRenderbuffers(1, &rb);
         mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, rb);
 
         GLenum rbInternalFormat =
             mGL->IsGLES2()
                 ? (mGL->IsExtensionSupported(GLContext::OES_rgb8_rgba8) ? LOCAL_GL_RGBA8 : LOCAL_GL_RGBA4)
@@ -628,18 +628,16 @@ GLReadTexImageHelper::ReadTexImage(GLuin
         mGL->fEnable(LOCAL_GL_SCISSOR_TEST);
 
     if (aTextureId)
         mGL->fBindTexture(aTextureTarget, oldTex);
 
     if (oldTexUnit != LOCAL_GL_TEXTURE0)
         mGL->fActiveTexture(oldTexUnit);
 
-    mGL->PopViewportRect();
-
     return isurf.forget();
 }
 
 #undef CLEANUP_IF_GLERROR_OCCURRED
 
 
 }
 }
--- a/gfx/gl/GLSharedHandleHelpers.cpp
+++ b/gfx/gl/GLSharedHandleHelpers.cpp
@@ -1,14 +1,13 @@
 /* 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 "GLContext.h"
-#include "GLLibraryEGL.h"
+#include "GLContextEGL.h"
 #include "GLSharedHandleHelpers.h"
 #ifdef MOZ_WIDGET_ANDROID
 #include "nsSurfaceTexture.h"
 #endif
 
 namespace mozilla {
 namespace gl {
 
@@ -70,17 +69,17 @@ public:
     // Args are the active GL context, and a texture in that GL
     // context for which to create an EGLImage.  After the EGLImage
     // is created, the texture is unused by EGLTextureWrapper.
     bool CreateEGLImage(GLContext *ctx, uintptr_t texture) {
         MOZ_ASSERT(!mEGLImage && texture && sEGLLibrary.HasKHRImageBase());
         static const EGLint eglAttributes[] = {
             LOCAL_EGL_NONE
         };
-        EGLContext eglContext = (EGLContext)ctx->GetNativeData(GLContext::NativeGLContext);
+        EGLContext eglContext = GLContextEGL::Cast(ctx)->GetEGLContext();
         mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D,
                                              (EGLClientBuffer)texture, eglAttributes);
         if (!mEGLImage) {
 #ifdef DEBUG
             printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError());
 #endif
             return false;
         }
--- a/gfx/gl/ScopedGLHelpers.cpp
+++ b/gfx/gl/ScopedGLHelpers.cpp
@@ -24,16 +24,23 @@ ScopedGLState::ScopedGLState(GLContext* 
 
     if (aNewState) {
         mGL->fEnable(mCapability);
     } else {
         mGL->fDisable(mCapability);
     }
 }
 
+ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability)
+    : ScopedGLWrapper<ScopedGLState>(aGL)
+    , mCapability(aCapability)
+{
+    mOldState = mGL->fIsEnabled(mCapability);
+}
+
 void
 ScopedGLState::UnwrapImpl()
 {
     if (mOldState) {
         mGL->fEnable(mCapability);
     } else {
         mGL->fDisable(mCapability);
     }
@@ -235,10 +242,54 @@ ScopedFramebufferForRenderbuffer::Unwrap
 {
     if (!mFB)
         return;
 
     mGL->fDeleteFramebuffers(1, &mFB);
     mFB = 0;
 }
 
+/* ScopedViewportRect *********************************************************/
+
+ScopedViewportRect::ScopedViewportRect(GLContext* aGL,
+                                       GLint x, GLint y,
+                                       GLsizei width, GLsizei height)
+  : ScopedGLWrapper<ScopedViewportRect>(aGL)
+{
+  mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, mSavedViewportRect);
+  mGL->fViewport(x, y, width, height);
+}
+
+void ScopedViewportRect::UnwrapImpl()
+{
+  mGL->fViewport(mSavedViewportRect[0],
+                 mSavedViewportRect[1],
+                 mSavedViewportRect[2],
+                 mSavedViewportRect[3]);
+}
+
+/* ScopedScissorRect **********************************************************/
+
+ScopedScissorRect::ScopedScissorRect(GLContext* aGL,
+                                     GLint x, GLint y,
+                                     GLsizei width, GLsizei height)
+  : ScopedGLWrapper<ScopedScissorRect>(aGL)
+{
+  mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect);
+  mGL->fScissor(x, y, width, height);
+}
+
+ScopedScissorRect::ScopedScissorRect(GLContext* aGL)
+  : ScopedGLWrapper<ScopedScissorRect>(aGL)
+{
+  mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect);
+}
+
+void ScopedScissorRect::UnwrapImpl()
+{
+  mGL->fScissor(mSavedScissorRect[0],
+                mSavedScissorRect[1],
+                mSavedScissorRect[2],
+                mSavedScissorRect[3]);
+}
+
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/ScopedGLHelpers.h
+++ b/gfx/gl/ScopedGLHelpers.h
@@ -54,16 +54,19 @@ struct ScopedGLState
 
 protected:
     const GLenum mCapability;
     bool mOldState;
 
 public:
     // Use |newState = true| to enable, |false| to disable.
     ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState);
+    // variant that doesn't change state; simply records existing state to be
+    // restored by the destructor
+    ScopedGLState(GLContext* aGL, GLenum aCapability);
 
 protected:
     void UnwrapImpl();
 };
 
 // Saves and restores with GetUserBoundFB and BindUserFB.
 struct ScopedBindFramebuffer
     : public ScopedGLWrapper<ScopedBindFramebuffer>
@@ -204,12 +207,43 @@ public:
     GLuint FB() const {
         return mFB;
     }
 
 protected:
     void UnwrapImpl();
 };
 
+struct ScopedViewportRect
+    : public ScopedGLWrapper<ScopedViewportRect>
+{
+    friend struct ScopedGLWrapper<ScopedViewportRect>;
+
+protected:
+    GLint mSavedViewportRect[4];
+
+public:
+    ScopedViewportRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height);
+
+protected:
+    void UnwrapImpl();
+};
+
+struct ScopedScissorRect
+    : public ScopedGLWrapper<ScopedScissorRect>
+{
+    friend struct ScopedGLWrapper<ScopedScissorRect>;
+
+protected:
+    GLint mSavedScissorRect[4];
+
+public:
+    ScopedScissorRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height);
+    explicit ScopedScissorRect(GLContext* aGL);
+
+protected:
+    void UnwrapImpl();
+};
+
 } /* namespace gl */
 } /* namespace mozilla */
 
 #endif /* SCOPEDGLHELPERS_H_ */
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -1,26 +1,22 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedSurfaceANGLE.h"
 
-#include "GLContext.h"
+#include "GLContextEGL.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace gl {
 
-class GLContextEGL;
-void SetEGLSurfaceOverride(GLContextEGL* context, EGLSurface surf);
-GLContextEGL* DowncastGLContextEGL(GLContext* context);
-
 SurfaceFactory_ANGLEShareHandle*
 SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
                                         ID3D10Device1* d3d,
                                         const SurfaceCaps& caps)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     if (!egl)
         return nullptr;
@@ -44,17 +40,17 @@ SharedSurface_ANGLEShareHandle::Display(
 SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle()
 {
     mEGL->fDestroySurface(Display(), mPBuffer);
 }
 
 void
 SharedSurface_ANGLEShareHandle::LockProdImpl()
 {
-    SetEGLSurfaceOverride(DowncastGLContextEGL(mGL), mPBuffer);
+    GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(mPBuffer);
 }
 
 void
 SharedSurface_ANGLEShareHandle::UnlockProdImpl()
 {
 }
 
 
@@ -270,14 +266,14 @@ SurfaceFactory_ANGLEShareHandle::Surface
                                                                  ID3D10Device1* d3d,
                                                                  const SurfaceCaps& caps)
     : SurfaceFactory_GL(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
     , mProdGL(gl)
     , mEGL(egl)
     , mConsD3D(d3d)
 {
     mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps);
-    mContext = mProdGL->GetNativeData(GLContext::NativeGLContext);
+    mContext = GLContextEGL::Cast(mProdGL)->GetEGLContext();
     MOZ_ASSERT(mConfig && mContext);
 }
 
 } /* namespace gl */
 } /* namespace mozilla */
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedSurfaceEGL.h"
-#include "GLContext.h"
+#include "GLContextEGL.h"
 #include "GLBlitHelper.h"
 #include "ScopedGLHelpers.h"
 #include "SharedSurfaceGL.h"
 #include "SurfaceFactory.h"
 #include "GLLibraryEGL.h"
 #include "TextureGarbageBin.h"
 #include "GLReadTexImageHelper.h"
 
@@ -129,17 +129,17 @@ CreateTexturePipe(GLLibraryEGL* const eg
     MOZ_ASSERT(out_tex && out_image);
     *out_tex = 0;
     *out_image = 0;
 
     GLuint tex = CreateTextureForOffscreen(gl, formats, size);
     if (!tex)
         return false;
 
-    EGLContext context = (EGLContext) gl->GetNativeData(GLContext::NativeGLContext);
+    EGLContext context = GLContextEGL::Cast(gl)->GetEGLContext();
     MOZ_ASSERT(context);
     EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex);
     EGLImage image = egl->fCreateImage(egl->Display(), context,
                                        LOCAL_EGL_GL_TEXTURE_2D, buffer,
                                        nullptr);
     if (!image) {
         gl->fDeleteTextures(1, &tex);
         return false;
@@ -282,15 +282,15 @@ SharedSurface_EGLImage::GetPixels() cons
 }
 
 
 
 SurfaceFactory_EGLImage*
 SurfaceFactory_EGLImage::Create(GLContext* prodGL,
                                         const SurfaceCaps& caps)
 {
-    EGLContext context = prodGL->GetNativeData(GLContext::NativeGLContext);
+    EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
 
     return new SurfaceFactory_EGLImage(prodGL, context, caps);
 }
 
 } /* namespace gfx */
 } /* namespace mozilla */
--- a/gfx/gl/SharedSurfaceIO.cpp
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedSurfaceIO.h"
-#include "GLContext.h"
+#include "GLContextCGL.h"
 #include "gfxImageSurface.h"
 #include "mozilla/gfx/MacIOSurface.h"
 #include "mozilla/DebugOnly.h"
 #include "ScopedGLHelpers.h"
 
 namespace mozilla {
 namespace gl {
 
@@ -75,17 +75,17 @@ SharedSurface_IOSurface::SharedSurface_I
                         LOCAL_GL_LINEAR);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
                         LOCAL_GL_TEXTURE_WRAP_S,
                         LOCAL_GL_CLAMP_TO_EDGE);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
                         LOCAL_GL_TEXTURE_WRAP_T,
                         LOCAL_GL_CLAMP_TO_EDGE);
 
-    CGLContextObj ctx = static_cast<CGLContextObj>(mGL->GetNativeData(GLContext::NativeCGLContext));
+    CGLContextObj ctx = GLContextCGL::Cast(mGL)->GetCGLContext();
     MOZ_ASSERT(ctx);
 
     surface->CGLTexImageIOSurface2D(ctx);
 }
 
 SharedSurface_IOSurface::~SharedSurface_IOSurface()
 {
     if (mTexture) {
--- a/gfx/gl/WGLLibrary.h
+++ b/gfx/gl/WGLLibrary.h
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GLContextTypes.h"
+#include <windows.h>
+
 struct PRLibrary;
 
 namespace mozilla {
 namespace gl {
 
 class WGLLibrary
 {
 public:
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -27,16 +27,17 @@ if CONFIG['MOZ_GL_PROVIDER']:
 
 EXPORTS += [
     'DecomposeIntoNoRepeatTriangles.h',
     'ForceDiscreteGPUHelperCGL.h',
     'GfxTexturesReporter.h',
     'GLBlitTextureImageHelper.h',
     'GLConsts.h',
     'GLContext.h',
+    'GLContextEGL.h',
     'GLContextProvider.h',
     'GLContextProviderImpl.h',
     'GLContextSymbols.h',
     'GLContextTypes.h',
     'GLDefs.h',
     'GLLibraryEGL.h',
     'GLLibraryLoader.h',
     'GLReadTexImageHelper.h',
@@ -52,21 +53,25 @@ EXPORTS += [
     'SurfaceFactory.h',
     'SurfaceStream.h',
     'SurfaceTypes.h',
     'TextureGarbageBin.h',
     'VBOArena.h',
 ]
 
 if CONFIG['MOZ_X11']:
-    EXPORTS += ['GLXLibrary.h']
+    EXPORTS += [
+        'GLContextGLX.h',
+        'GLXLibrary.h',
+    ]
 
 # Win32 is a special snowflake, for ANGLE
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     EXPORTS += [
+        'GLContextWGL.h',
         'SharedSurfaceANGLE.h',
         'WGLLibrary.h',
     ]
     UNIFIED_SOURCES += [
         'GLContextProviderEGL.cpp',
         'SharedSurfaceANGLE.cpp',
     ]
 if CONFIG['MOZ_ENABLE_SKIA_GPU']:
@@ -82,16 +87,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
 
 if gl_provider == 'CGL':
     # These files include Mac headers that are unfriendly to unified builds
     SOURCES += [
         "GLContextProviderCGL.mm",
         "TextureImageCGL.mm"
     ]
     EXPORTS += [
+        'GLContextCGL.h',
         'SharedSurfaceIO.h',
     ]
     # SharedSurfaceIO.cpp includes MacIOSurface.h which include Mac headers
     # which define Size and Point types in root namespace with often conflict with
     # our own types. While I haven't actually hit this issue in the present case,
     # it's been an issue in gfx/layers so let's not risk it.
     SOURCES += [
         'SharedSurfaceIO.cpp',
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -427,22 +427,16 @@ public:
    * composite. Returns false if rendering should be aborted.
    */
   virtual bool Ready() { return true; }
 
   // XXX I expect we will want to move mWidget into this class and implement
   // these methods properly.
   virtual nsIWidget* GetWidget() const { return nullptr; }
 
-  // Call before and after any rendering not done by this compositor but which
-  // might affect the compositor's internal state or the state of any APIs it
-  // uses. For example, internal GL state.
-  virtual void SaveState() {}
-  virtual void RestoreState() {}
-
   /**
    * Debug-build assertion that can be called to ensure code is running on the
    * compositor thread.
    */
   static void AssertOnCompositorThread();
 
   /**
    * We enforce that there can only be one Compositor backend type off the main
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1493,48 +1493,54 @@ PrintInfo(nsACString& aTo, LayerComposit
   }
   if (!aLayerComposite->GetShadowVisibleRegion().IsEmpty()) {
     AppendToString(aTo, aLayerComposite->GetShadowVisibleRegion(), " [shadow-visible=", "]");
   }
   return aTo;
 }
 
 void
-SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget)
+SetAntialiasingFlags(Layer* aLayer, DrawTarget* aTarget)
 {
   bool permitSubpixelAA = !(aLayer->GetContentFlags() & Layer::CONTENT_DISABLE_SUBPIXEL_AA);
-  if (!aTarget->IsCairo()) {
-    RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
+  if (aTarget->GetFormat() != FORMAT_B8G8R8A8) {
+    aTarget->SetPermitSubpixelAA(permitSubpixelAA);
+    return;
+  }
 
-    if (dt->GetFormat() != FORMAT_B8G8R8A8) {
-      dt->SetPermitSubpixelAA(permitSubpixelAA);
-      return;
-    }
+  const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
+  gfx::Rect transformedBounds = aTarget->GetTransform().TransformBounds(gfx::Rect(Float(bounds.x), Float(bounds.y),
+                                                                                  Float(bounds.width), Float(bounds.height)));
+  transformedBounds.RoundOut();
+  IntRect intTransformedBounds;
+  transformedBounds.ToIntRect(&intTransformedBounds);
+  permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
+                      aTarget->GetOpaqueRect().Contains(intTransformedBounds);
+  aTarget->SetPermitSubpixelAA(permitSubpixelAA);
+}
 
-    const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
-    gfx::Rect transformedBounds = dt->GetTransform().TransformBounds(gfx::Rect(Float(bounds.x), Float(bounds.y),
-                                                                     Float(bounds.width), Float(bounds.height)));
-    transformedBounds.RoundOut();
-    IntRect intTransformedBounds;
-    transformedBounds.ToIntRect(&intTransformedBounds);
-    permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
-                        dt->GetOpaqueRect().Contains(intTransformedBounds);
-    dt->SetPermitSubpixelAA(permitSubpixelAA);
-  } else {
-    nsRefPtr<gfxASurface> surface = aTarget->CurrentSurface();
-    if (surface->GetContentType() != GFX_CONTENT_COLOR_ALPHA) {
-      // Destination doesn't have alpha channel; no need to set any special flags
-      surface->SetSubpixelAntialiasingEnabled(permitSubpixelAA);
-      return;
-    }
+void
+SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget)
+{
+  if (!aTarget->IsCairo()) {
+    SetAntialiasingFlags(aLayer, aTarget->GetDrawTarget());
+    return;
+  }
 
-    const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
-    permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
-        surface->GetOpaqueRect().Contains(
-        aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height)));
+  bool permitSubpixelAA = !(aLayer->GetContentFlags() & Layer::CONTENT_DISABLE_SUBPIXEL_AA);
+  nsRefPtr<gfxASurface> surface = aTarget->CurrentSurface();
+  if (surface->GetContentType() != GFX_CONTENT_COLOR_ALPHA) {
+    // Destination doesn't have alpha channel; no need to set any special flags
     surface->SetSubpixelAntialiasingEnabled(permitSubpixelAA);
+    return;
   }
+
+  const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
+  permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
+      surface->GetOpaqueRect().Contains(
+      aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height)));
+  surface->SetSubpixelAntialiasingEnabled(permitSubpixelAA);
 }
 
 PRLogModuleInfo* LayerManager::sLog;
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -2037,18 +2037,18 @@ protected:
 
   virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
 
   Layer* mTempReferent;
   // 0 is a special value that means "no ID".
   uint64_t mId;
 };
 
-void
-SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget);
+void SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget);
+void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget);
 
 #ifdef MOZ_DUMP_PAINTING
 void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf);
 void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf);
 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget);
 #endif
 
 }
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -6,20 +6,18 @@
 #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 "gfxContext.h"                 // for gfxContext, etc
 #include "gfxMatrix.h"                  // for gfxMatrix
 #include "gfxPlatform.h"                // for gfxPlatform
-#include "gfxPoint.h"                   // for gfxPoint
 #include "gfxUtils.h"                   // for gfxUtils
 #include "mozilla/ArrayUtils.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
@@ -173,114 +171,119 @@ 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
-RotatedContentBuffer::IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
+RotatedContentBuffer::IsClippingCheap(DrawTarget* aTarget, const nsIntRegion& aRegion)
 {
-  // Assume clipping is cheap if the context just has an integer
+  // Assume clipping is cheap if the draw target just has an integer
   // translation, and the visible region is simple.
-  return !aTarget->CurrentMatrix().HasNonIntegerTranslation() &&
+  return !aTarget->GetTransform().HasNonIntegerTranslation() &&
          aRegion.GetNumRects() <= 1;
 }
 
 void
 RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
-                             gfxContext* aTarget,
+                             DrawTarget* aTarget,
                              float aOpacity,
+                             CompositionOp aOp,
                              gfxASurface* aMask,
                              const gfxMatrix* aMaskTransform)
 {
   if (!EnsureBuffer()) {
     return;
   }
 
-  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());
+    gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
     clipped = true;
   }
 
   RefPtr<gfx::SourceSurface> mask;
   if (aMask) {
-    mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
+    mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, aMask);
   }
 
   Matrix maskTransform;
   if (aMaskTransform) {
     maskTransform = ToMatrix(*aMaskTransform);
   }
 
-  CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
-  DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
+  DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aOp, mask, &maskTransform);
   if (clipped) {
-    dt->PopClip();
+    aTarget->PopClip();
   }
 }
 
-already_AddRefed<gfxContext>
-RotatedContentBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds,
-                                                  ContextSource aSource,
-                                                  nsIntPoint *aTopLeft)
+DrawTarget*
+RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds,
+                                                        ContextSource aSource)
 {
   if (!EnsureBuffer()) {
     return nullptr;
   }
 
-  nsRefPtr<gfxContext> ctx;
+  MOZ_ASSERT(!mLoanedDrawTarget, "draw target has been borrowed and not returned");
   if (aSource == BUFFER_BOTH && HaveBufferOnWhite()) {
     if (!EnsureBufferOnWhite()) {
       return nullptr;
     }
     MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
-    RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
-    ctx = new gfxContext(dualDT);
+    mLoanedDrawTarget = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
   } else if (aSource == BUFFER_WHITE) {
     if (!EnsureBufferOnWhite()) {
       return nullptr;
     }
-    ctx = new gfxContext(mDTBufferOnWhite);
+    mLoanedDrawTarget = mDTBufferOnWhite;
   } else {
     // BUFFER_BLACK, or BUFFER_BOTH with a single buffer.
-    ctx = new gfxContext(mDTBuffer);
+    mLoanedDrawTarget = 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);
   NS_ASSERTION(quadrantRect.Contains(aBounds), "Messed up quadrants");
-  ctx->Translate(-gfxPoint(quadrantRect.x, quadrantRect.y));
+
+  mLoanedTransform = mLoanedDrawTarget->GetTransform();
+  mLoanedTransform.Translate(-quadrantRect.x, -quadrantRect.y);
+  mLoanedDrawTarget->SetTransform(mLoanedTransform);
+  mLoanedTransform.Translate(quadrantRect.x, quadrantRect.y);
 
-  if (aTopLeft) {
-    *aTopLeft = nsIntPoint(quadrantRect.x, quadrantRect.y);
-  }
+  return mLoanedDrawTarget;
+}
 
-  return ctx.forget();
+void
+BorrowDrawTarget::ReturnDrawTarget(gfx::DrawTarget*& aReturned)
+{
+  MOZ_ASSERT(aReturned == mLoanedDrawTarget);
+  mLoanedDrawTarget->SetTransform(mLoanedTransform);
+  mLoanedDrawTarget = nullptr;
+  aReturned = nullptr;
 }
 
 gfxContentType
 RotatedContentBuffer::BufferContentType()
 {
   if (mDeprecatedBufferProvider) {
     return mDeprecatedBufferProvider->GetContentType();
   }
@@ -304,31 +307,33 @@ RotatedContentBuffer::BufferSizeOkFor(co
   return (aSize == mBufferRect.Size() ||
           (SizedToVisibleBounds != mBufferSizePolicy &&
            aSize < mBufferRect.Size()));
 }
 
 bool
 RotatedContentBuffer::EnsureBuffer()
 {
+  NS_ASSERTION(!mLoanedDrawTarget, "Loaned draw target must be returned");
   if (!mDTBuffer) {
     if (mDeprecatedBufferProvider) {
       mDTBuffer = mDeprecatedBufferProvider->LockDrawTarget();
     } else if (mBufferProvider) {
       mDTBuffer = mBufferProvider->AsTextureClientDrawTarget()->GetAsDrawTarget();
     }
   }
 
   NS_WARN_IF_FALSE(mDTBuffer, "no buffer");
   return !!mDTBuffer;
 }
 
 bool
 RotatedContentBuffer::EnsureBufferOnWhite()
 {
+  NS_ASSERTION(!mLoanedDrawTarget, "Loaned draw target must be returned");
   if (!mDTBufferOnWhite) {
     if (mDeprecatedBufferProviderOnWhite) {
       mDTBufferOnWhite = mDeprecatedBufferProviderOnWhite->LockDrawTarget();
     } else if (mBufferProviderOnWhite) {
       mDTBufferOnWhite =
         mBufferProviderOnWhite->AsTextureClientDrawTarget()->GetAsDrawTarget();
     }
   }
@@ -639,35 +644,34 @@ RotatedContentBuffer::BeginPaint(ThebesL
   }
   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.mTarget = BorrowDrawTargetForQuadrantUpdate(drawBounds, BUFFER_BOTH);
   result.mClip = CLIP_DRAW_SNAPPED;
 
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
     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) {
     nsIntRegionRectIterator iter(result.mRegionToDraw);
     const nsIntRect *iterRect;
     while ((iterRect = iter.Next())) {
-      result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
+      result.mTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     }
   }
 
   return result;
 }
 
 }
 }
--- a/gfx/layers/RotatedBuffer.h
+++ b/gfx/layers/RotatedBuffer.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef 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 "nsPoint.h"                    // for nsIntPoint
@@ -132,21 +131,37 @@ protected:
    * buffer at the other end, not 2D rotation!
    */
   nsIntPoint            mBufferRotation;
   // When this is true it means that all pixels have moved inside the buffer.
   // It's not possible to sync with another buffer without a full copy.
   bool                  mDidSelfCopy;
 };
 
+// Mixin class for classes which need logic for loaning out a draw target.
+// See comments on BorrowDrawTargetForQuadrantUpdate.
+class BorrowDrawTarget
+{
+protected:
+  void ReturnDrawTarget(gfx::DrawTarget*& aReturned);
+
+  // The draw target loaned by BorrowDrawTargetForQuadrantUpdate. It should not
+  // be used, we just keep a reference to ensure it is kept alive and so we can
+  // correctly restore state when it is returned.
+  RefPtr<gfx::DrawTarget> mLoanedDrawTarget;
+  gfx::Matrix mLoanedTransform;
+};
+
 /**
  * This class encapsulates the buffer used to retain ThebesLayer contents,
  * i.e., the contents of the layer's GetVisibleRegion().
  */
-class RotatedContentBuffer : public RotatedBuffer {
+class RotatedContentBuffer : public RotatedBuffer
+                           , public BorrowDrawTarget
+{
 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
@@ -182,45 +197,46 @@ public:
     mDeprecatedBufferProvider = nullptr;
     mDeprecatedBufferProviderOnWhite = nullptr;
     mBufferProvider = nullptr;
     mBufferProviderOnWhite = nullptr;
     mBufferRect.SetEmpty();
   }
 
   /**
-   * This is returned by BeginPaint. The caller should draw into mContext.
+   * This is returned by BeginPaint. The caller should draw into mTarget.
    * mRegionToDraw must be drawn. mRegionToInvalidate has been invalidated
    * 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)
+      : mTarget(nullptr)
+      , mDidSelfCopy(false)
     {}
 
-    nsRefPtr<gfxContext> mContext;
+    gfx::DrawTarget* mTarget;
     nsIntRegion mRegionToDraw;
     nsIntRegion mRegionToInvalidate;
+    DrawRegionClip mClip;
     bool mDidSelfCopy;
-    DrawRegionClip mClip;
   };
 
   enum {
     PAINT_WILL_RESAMPLE = 0x01,
     PAINT_NO_ROTATION = 0x02
   };
   /**
    * Start a drawing operation. This returns a PaintState describing what
    * needs to be drawn to bring the buffer up to date in the visible region.
    * This queries aLayer to get the currently valid and visible regions.
-   * The returned mContext may be null if mRegionToDraw is empty.
+   * The returned mTarget may be null if mRegionToDraw is empty.
    * Otherwise it must not be null.
    * mRegionToInvalidate will contain mRegionToDraw.
    * @param aFlags when PAINT_WILL_RESAMPLE is passed, this indicates that
    * buffer will be resampled when rendering (i.e the effective transform
    * combined with the scale for the resolution is not just an integer
    * translation). This will disable buffer rotation (since we don't want
    * to resample across the rotation boundary) and will ensure that we
    * make the entire buffer contents valid (since we don't want to sample
@@ -255,18 +271,22 @@ public:
   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);
+  void DrawTo(ThebesLayer* aLayer,
+              gfx::DrawTarget* aTarget,
+              float aOpacity,
+              gfx::CompositionOp aOp,
+              gfxASurface* aMask,
+              const gfxMatrix* aMaskTransform);
 
 protected:
   TemporaryRef<gfx::DrawTarget>
   SetDTBuffer(gfx::DrawTarget* aBuffer,
               const nsIntRect& aBufferRect,
               const nsIntPoint& aBufferRotation)
   {
     RefPtr<gfx::DrawTarget> tmp = mDTBuffer.forget();
@@ -340,25 +360,34 @@ protected:
 
     mBufferProviderOnWhite = aClient;
     if (!mBufferProviderOnWhite) {
       mDTBufferOnWhite = nullptr;
     } 
   }
 
   /**
-   * Get a context at the specified resolution for updating |aBounds|,
+   * Get a draw target 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.
+   * The result should only be held temporarily by the caller (it will be kept
+   * alive by this). Once used it should be returned using ReturnDrawTarget.
+   * BorrowDrawTargetForQuadrantUpdate may not be called more than once without
+   * first calling ReturnDrawTarget.
+   *
+   * ReturnDrawTarget will restore the transform on the draw target. But it is
+   * the callers responsibility to restore the clip. The caller should flush the
+   * draw target, if necessary.
    */
-  already_AddRefed<gfxContext>
-  GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint* aTopLeft = nullptr);
+  gfx::DrawTarget*
+  BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds,
+                                    ContextSource aSource);
+  void ReturnDrawTarget(gfx::DrawTarget* aReturned);
 
-  static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion);
+  static bool IsClippingCheap(gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
 
 protected:
   /**
    * Return the buffer's content type.  Requires a valid buffer or
    * buffer provider.
    */
   gfxContentType BufferContentType();
   bool BufferSizeOkFor(const nsIntSize& aSize);
--- a/gfx/layers/basic/BasicThebesLayer.cpp
+++ b/gfx/layers/basic/BasicThebesLayer.cpp
@@ -22,16 +22,17 @@
 #include "mozilla/layers/LayersTypes.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for gfxContext::Release, etc
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRect.h"                     // for nsIntRect
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "AutoMaskData.h"
+#include "gfx2DGlue.h"
 
 struct gfxMatrix;
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
@@ -127,30 +128,33 @@ BasicThebesLayer::PaintThebes(gfxContext
   gfxASurface* maskSurface = nullptr;
   const gfxMatrix* maskTransform = nullptr;
   if (GetMaskData(aMaskLayer, &mask)) {
     maskSurface = mask.GetSurface();
     maskTransform = &mask.GetTransform();
   }
 
   if (!IsHidden() && !clipExtents.IsEmpty()) {
-    AutoSetOperator setOperator(aContext, GetOperator());
-    mContentClient->DrawTo(this, aContext, opacity, maskSurface, maskTransform);
+    mContentClient->DrawTo(this, aContext->GetDrawTarget(), opacity,
+                           CompositionOpForOp(GetOperator()),
+                           maskSurface, maskTransform);
   }
 
   for (uint32_t i = 0; i < readbackUpdates.Length(); ++i) {
     ReadbackProcessor::Update& update = readbackUpdates[i];
     nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
     nsRefPtr<gfxContext> ctx =
       update.mLayer->GetSink()->BeginUpdate(update.mUpdateRect + offset,
                                             update.mSequenceCounter);
     if (ctx) {
       NS_ASSERTION(opacity == 1.0, "Should only read back opaque layers");
       ctx->Translate(gfxPoint(offset.x, offset.y));
-      mContentClient->DrawTo(this, ctx, 1.0, maskSurface, maskTransform);
+      mContentClient->DrawTo(this, ctx->GetDrawTarget(), 1.0,
+                             CompositionOpForOp(ctx->CurrentOperator()),
+                             maskSurface, maskTransform);
       update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
     }
   }
 }
 
 void
 BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
                            void* aCallbackData)
@@ -183,35 +187,38 @@ BasicThebesLayer::Validate(LayerManager:
 #endif
   if (mDrawAtomically) {
     flags |= RotatedContentBuffer::PAINT_NO_ROTATION;
   }
   PaintState state =
     mContentClient->BeginPaintBuffer(this, contentType, flags);
   mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
-  if (state.mContext) {
+  if (state.mTarget) {
     // The area that became invalid and is visible needs to be repainted
     // (this could be the whole visible area if our buffer switched
     // from RGB to RGBA, because we might need to repaint with
     // subpixel AA)
     state.mRegionToInvalidate.And(state.mRegionToInvalidate,
                                   GetEffectiveVisibleRegion());
     nsIntRegion extendedDrawRegion = state.mRegionToDraw;
-    SetAntialiasingFlags(this, state.mContext);
+    SetAntialiasingFlags(this, state.mTarget);
 
     RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
 
-    PaintBuffer(state.mContext,
+    nsRefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(state.mTarget);
+    PaintBuffer(ctx,
                 state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
                 state.mDidSelfCopy,
                 state.mClip,
                 aCallback, aCallbackData);
     MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
     Mutated();
+    ctx = nullptr;
+    mContentClient->ReturnDrawTarget(state.mTarget);
 
     RenderTraceInvalidateEnd(this, "FFFF00");
   } else {
     // It's possible that state.mRegionToInvalidate is nonempty here,
     // if we are shrinking the valid region to nothing. So use mRegionToDraw
     // instead.
     NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
                      "No context when we have something to draw, resource exhaustion?");
--- a/gfx/layers/client/ClientThebesLayer.cpp
+++ b/gfx/layers/client/ClientThebesLayer.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/Preferences.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
 #include "nsRect.h"                     // for nsIntRect
+#include "gfx2DGlue.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 void
 ClientThebesLayer::PaintThebes()
@@ -56,31 +57,34 @@ ClientThebesLayer::PaintThebes()
         flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
       }
     }
 #endif
     PaintState state =
       mContentClient->BeginPaintBuffer(this, contentType, flags);
     mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
-    if (state.mContext) {
+    if (state.mTarget) {
       // The area that became invalid and is visible needs to be repainted
       // (this could be the whole visible area if our buffer switched
       // from RGB to RGBA, because we might need to repaint with
       // subpixel AA)
       state.mRegionToInvalidate.And(state.mRegionToInvalidate,
                                     GetEffectiveVisibleRegion());
       nsIntRegion extendedDrawRegion = state.mRegionToDraw;
-      SetAntialiasingFlags(this, state.mContext);
+      SetAntialiasingFlags(this, state.mTarget);
 
-      PaintBuffer(state.mContext,
+      nsRefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(state.mTarget);
+      PaintBuffer(ctx,
                   state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
                   state.mDidSelfCopy, state.mClip);
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
       Mutated();
+      ctx = nullptr;
+      mContentClient->ReturnDrawTarget(state.mTarget);
     } else {
       // It's possible that state.mRegionToInvalidate is nonempty here,
       // if we are shrinking the valid region to nothing. So use mRegionToDraw
       // instead.
       NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
                        "No context when we have something to draw, resource exhaustion?");
     }
   }
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -603,39 +603,45 @@ ContentClientDoubleBuffered::SyncFrontBu
     mFrontClientOnWhite->Unlock();
   }
 }
 
 void
 ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
                                                    const nsIntRegion& aUpdateRegion)
 {
-  nsRefPtr<gfxContext> destCtx =
-    GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
-  destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
+  DrawTarget* destDT =
+    BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
 
-  bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
+  bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
   if (isClippingCheap) {
-    gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
+    gfxUtils::ClipToRegion(destDT, aUpdateRegion);
   }
 
-  aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
+  aSource.DrawBufferWithRotation(destDT, BUFFER_BLACK, 1.0, OP_SOURCE);
+  if (isClippingCheap) {
+    destDT->PopClip();
+  }
+  ReturnDrawTarget(destDT);
 
   if (aSource.HaveBufferOnWhite()) {
     MOZ_ASSERT(HaveBufferOnWhite());
-    nsRefPtr<gfxContext> destCtx =
-      GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
-    destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
+    DrawTarget* destDT =
+      BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
 
-    bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
+    bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
     if (isClippingCheap) {
-      gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
+      gfxUtils::ClipToRegion(destDT, aUpdateRegion);
     }
 
-    aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
+    aSource.DrawBufferWithRotation(destDT, BUFFER_WHITE, 1.0, OP_SOURCE);
+    if (isClippingCheap) {
+      destDT->PopClip();
+    }
+    ReturnDrawTarget(destDT);
   }
 }
 
 DeprecatedContentClientDoubleBuffered::~DeprecatedContentClientDoubleBuffered()
 {
   if (mDeprecatedTextureClient) {
     MOZ_ASSERT(mFrontClient);
     mDeprecatedTextureClient->SetDescriptor(SurfaceDescriptor());
@@ -812,42 +818,48 @@ DeprecatedContentClientDoubleBuffered::S
 
   mFrontAndBackBufferDiffer = false;
 }
 
 void
 DeprecatedContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
                                                    const nsIntRegion& aUpdateRegion)
 {
-  nsRefPtr<gfxContext> destCtx =
-    GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
-  if (!destCtx) {
+  DrawTarget* destDT =
+    BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
+  if (!destDT) {
     return;
   }
-  destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
 
-  bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
+  bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
   if (isClippingCheap) {
-    gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
+    gfxUtils::ClipToRegion(destDT, aUpdateRegion);
   }
 
-  aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
+  aSource.DrawBufferWithRotation(destDT, BUFFER_BLACK, 1.0, OP_SOURCE);
+  if (isClippingCheap) {
+    destDT->PopClip();
+  }
+  ReturnDrawTarget(destDT);
 
   if (aSource.HaveBufferOnWhite()) {
     MOZ_ASSERT(HaveBufferOnWhite());
-    nsRefPtr<gfxContext> destCtx =
-      GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
-    destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
+    DrawTarget* destDT =
+      BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
 
-    bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
+    bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
     if (isClippingCheap) {
-      gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
+      gfxUtils::ClipToRegion(destDT, aUpdateRegion);
     }
 
-    aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
+    aSource.DrawBufferWithRotation(destDT, BUFFER_WHITE, 1.0, OP_SOURCE);
+    if (isClippingCheap) {
+      destDT->PopClip();
+    }
+    ReturnDrawTarget(destDT);
   }
 }
 
 void
 ContentClientSingleBuffered::SyncFrontBufferToBackBuffer()
 {
   if (!mFrontAndBackBufferDiffer) {
     return;
@@ -1130,62 +1142,65 @@ ContentClientIncremental::BeginPaintBuff
 
   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);
 
+  MOZ_ASSERT(!mLoanedDrawTarget);
+
   // BeginUpdate is allowed to modify the given region,
   // if it wants more to be repainted than we request.
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
     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));
       MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
       RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize().ToIntSize());
       RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize().ToIntSize());
-      RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
-      result.mContext = new gfxContext(dt);
+      mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
     } else {
-      result.mContext = nullptr;
+      mLoanedDrawTarget = nullptr;
     }
   } else {
     nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw);
     MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
-    RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize().ToIntSize());
-    result.mContext = new gfxContext(dt);
+    mLoanedDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize().ToIntSize());
   }
-  if (!result.mContext) {
+  if (!mLoanedDrawTarget) {
     NS_WARNING("unable to get context for update");
     return result;
   }
-  result.mContext->Translate(-gfxPoint(drawBounds.x, drawBounds.y));
+
+  result.mTarget = mLoanedDrawTarget;
+  mLoanedTransform = mLoanedDrawTarget->GetTransform();
+  mLoanedTransform.Translate(-drawBounds.x, -drawBounds.y);
+  result.mTarget->SetTransform(mLoanedTransform);
+  mLoanedTransform.Translate(drawBounds.x, drawBounds.y);
 
   // If we do partial updates, we have to clip drawing to the regionToDraw.
   // If we don't clip, background images will be fillrect'd to the region correctly,
   // while text or lines will paint outside of the regionToDraw. This becomes apparent
   // with concave regions. Right now the scrollbars invalidate a narrow strip of the bar
   // although they never cover it. This leads to two draw rects, the narow strip and the actually
   // newly exposed area. It would be wise to fix this glitch in any way to have simpler
   // clip and draw regions.
   result.mClip = CLIP_DRAW;
 
   if (mContentType == GFX_CONTENT_COLOR_ALPHA) {
-    result.mContext->Save();
-    gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
-    result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
-    result.mContext->Paint();
-    result.mContext->Restore();
+    gfxUtils::ClipToRegion(result.mTarget, result.mRegionToDraw);
+    nsIntRect bounds = result.mRegionToDraw.GetBounds();
+    result.mTarget->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height));
   }
 
   return result;
 }
 
 void
 ContentClientIncremental::Updated(const nsIntRegion& aRegionToDraw,
                                   const nsIntRegion& aVisibleRegion,
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -92,16 +92,17 @@ public:
   virtual ~ContentClient()
   {}
 
 
   virtual void Clear() = 0;
   virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
                                                             RotatedContentBuffer::ContentType aContentType,
                                                             uint32_t aFlags) = 0;
+  virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) = 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
@@ -135,26 +136,35 @@ class ContentClientBasic : public Conten
 {
 public:
   ContentClientBasic();
 
   typedef RotatedContentBuffer::PaintState PaintState;
   typedef RotatedContentBuffer::ContentType ContentType;
 
   virtual void Clear() { RotatedContentBuffer::Clear(); }
-  PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
-                              uint32_t aFlags)
+  virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
+                                      uint32_t aFlags) MOZ_OVERRIDE
   {
     return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
   }
+  virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
+  {
+    BorrowDrawTarget::ReturnDrawTarget(aReturned);
+  }
 
-  void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
-              gfxASurface* aMask, const gfxMatrix* aMaskTransform)
+  void DrawTo(ThebesLayer* aLayer,
+              gfx::DrawTarget* aTarget,
+              float aOpacity,
+              gfx::CompositionOp aOp,
+              gfxASurface* aMask,
+              const gfxMatrix* aMaskTransform)
   {
-    RotatedContentBuffer::DrawTo(aLayer, aTarget, aOpacity, aMask, aMaskTransform);
+    RotatedContentBuffer::DrawTo(aLayer, aTarget, aOpacity, aOp,
+                                 aMask, aMaskTransform);
   }
 
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     MOZ_CRASH("Should not be called on non-remote ContentClient");
@@ -190,21 +200,26 @@ public:
     , mFrontAndBackBufferDiffer(false)
     , mSurfaceFormat(gfx::FORMAT_B8G8R8A8)
   {}
 
   typedef RotatedContentBuffer::PaintState PaintState;
   typedef RotatedContentBuffer::ContentType ContentType;
 
   virtual void Clear() { RotatedContentBuffer::Clear(); }
-  PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
-                              uint32_t aFlags)
+
+  virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
+                                      uint32_t aFlags) MOZ_OVERRIDE
   {
     return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
   }
+  virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
+  {
+    BorrowDrawTarget::ReturnDrawTarget(aReturned);
+  }
 
   /**
    * Begin/End Paint map a gfxASurface from the texture client
    * into the buffer of RotatedBuffer. The surface is only
    * valid when the texture client is locked, so is mapped out
    * of RotatedContentBuffer when we are done painting.
    * None of the underlying buffer attributes (rect, rotation)
    * are affected by mapping/unmapping.
@@ -290,21 +305,26 @@ public:
     , mFrontAndBackBufferDiffer(false)
     , mContentType(GFX_CONTENT_COLOR_ALPHA)
   {}
 
   typedef RotatedContentBuffer::PaintState PaintState;
   typedef RotatedContentBuffer::ContentType ContentType;
 
   virtual void Clear() { RotatedContentBuffer::Clear(); }
-  PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
-                              uint32_t aFlags)
+
+  virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
+                                      uint32_t aFlags) MOZ_OVERRIDE
   {
     return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
   }
+  virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
+  {
+    BorrowDrawTarget::ReturnDrawTarget(aReturned);
+  }
 
   /**
    * Begin/End Paint map a gfxASurface from the texture client
    * into the buffer of RotatedContentBuffer. The surface is only
    * valid when the texture client is locked, so is mapped out
    * of RotatedContentBuffer when we are done painting.
    * None of the underlying buffer attributes (rect, rotation)
    * are affected by mapping/unmapping.
@@ -491,16 +511,17 @@ protected:
 
 /**
  * A single buffered ContentClient that creates temporary buffers which are 
  * used to update the host-side texture. The ownership of the buffers is
  * passed to the host side during the transaction, and we need to create
  * new ones each frame.
  */
 class ContentClientIncremental : public ContentClientRemote
+                               , public BorrowDrawTarget
 {
 public:
   ContentClientIncremental(CompositableForwarder* aFwd)
     : ContentClientRemote(aFwd)
     , mContentType(GFX_CONTENT_COLOR_ALPHA)
     , mHasBuffer(false)
     , mHasBufferOnWhite(false)
   {
@@ -516,19 +537,24 @@ public:
   }
 
   virtual void Clear()
   {
     mBufferRect.SetEmpty();
     mHasBuffer = false;
     mHasBufferOnWhite = false;
   }
+
   virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
                                                             RotatedContentBuffer::ContentType aContentType,
-                                                            uint32_t aFlags);
+                                                            uint32_t aFlags) MOZ_OVERRIDE;
+  virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
+  {
+    BorrowDrawTarget::ReturnDrawTarget(aReturned);
+  }
 
   virtual void Updated(const nsIntRegion& aRegionToDraw,
                        const nsIntRegion& aVisibleRegion,
                        bool aDidSelfCopy);
 
   virtual void EndPaint()
   {
     if (IsSurfaceDescriptorValid(mUpdateDescriptor)) {
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -383,33 +383,29 @@ LayerManagerComposite::Render()
   mInvalidRegion.SetEmpty();
 
   if (actualBounds.IsEmpty()) {
     mCompositor->GetWidget()->PostRender(this);
     return;
   }
 
   // Allow widget to render a custom background.
-  mCompositor->SaveState();
   mCompositor->GetWidget()->DrawWindowUnderlay(this, nsIntRect(actualBounds.x,
                                                                actualBounds.y,
                                                                actualBounds.width,
                                                                actualBounds.height));
-  mCompositor->RestoreState();
 
   // Render our layers.
   RootLayer()->RenderLayer(clipRect);
 
   // Allow widget to render a custom foreground.
-  mCompositor->SaveState();
   mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x,
                                                               actualBounds.y,
                                                               actualBounds.width,
                                                               actualBounds.height));
-  mCompositor->RestoreState();
 
   // Debugging
   RenderDebugOverlay(actualBounds);
 
   {
     PROFILER_LABEL("LayerManagerComposite", "EndFrame");
     mCompositor->EndFrame();
   }
--- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp
+++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
@@ -54,19 +54,25 @@ CanvasLayerD3D10::Initialize(const Data&
 
     GLScreenBuffer* screen = mGLContext->Screen();
     SurfaceStreamType streamType =
         SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
                                           screen->PreserveBuffer());
 
     SurfaceFactory_GL* factory = nullptr;
     if (!mForceReadback) {
-      factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext,
-                                                        device(),
-                                                        screen->Caps());
+      if (mGLContext->IsANGLE()) {
+        factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext,
+                                                          device(),
+                                                          screen->Caps());
+      } else {
+        factory = new SurfaceFactory_GLTexture(mGLContext,
+                                               nullptr,
+                                               screen->Caps());
+      }
     }
 
     if (factory) {
       screen->Morph(factory, streamType);
     }
   } else if (aData.mDrawTarget) {
     mDrawTarget = aData.mDrawTarget;
     mNeedsYFlip = false;
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -245,16 +245,17 @@ CompositorOGL::CompositorOGL(nsIWidget *
                              int aSurfaceHeight, bool aUseExternalSurfaceSize)
   : mWidget(aWidget)
   , mWidgetSize(-1, -1)
   , mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
   , mHasBGRA(0)
   , mUseExternalSurfaceSize(aUseExternalSurfaceSize)
   , mFrameInProgress(false)
   , mDestroyed(false)
+  , mHeight(0)
 {
   MOZ_COUNT_CTOR(CompositorOGL);
   sBackend = LAYERS_OPENGL;
 }
 
 CompositorOGL::~CompositorOGL()
 {
   MOZ_COUNT_DTOR(CompositorOGL);
@@ -390,18 +391,16 @@ CompositorOGL::Initialize()
 #ifdef MOZ_WIDGET_ANDROID
   if (!mGLContext)
     NS_RUNTIMEABORT("We need a context on Android");
 #endif
 
   if (!mGLContext)
     return false;
 
-  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);
@@ -628,16 +627,18 @@ CompositorOGL::BindAndDrawQuadWithTextur
 
 void
 CompositorOGL::PrepareViewport(const gfx::IntSize& aSize,
                                const gfxMatrix& aWorldTransform)
 {
   // Set the viewport correctly.
   mGLContext->fViewport(0, 0, aSize.width, aSize.height);
 
+  mHeight = aSize.height;
+
   // 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 aWorldTransform for this to work
   // though.
 
@@ -711,24 +712,16 @@ CompositorOGL::CreateRenderTargetFromSou
 
 void
 CompositorOGL::SetRenderTarget(CompositingRenderTarget *aSurface)
 {
   MOZ_ASSERT(aSurface);
   CompositingRenderTargetOGL* surface
     = static_cast<CompositingRenderTargetOGL*>(aSurface);
   if (mCurrentRenderTarget != surface) {
-    // Restore the scissor rect that was active before we set the current
-    // render target.
-    mGLContext->PopScissorRect();
-
-    // Save the current scissor rect so that we can pop back to it when
-    // changing the render target again.
-    mGLContext->PushScissorRect();
-
     surface->BindRenderTarget();
     mCurrentRenderTarget = surface;
   }
 }
 
 CompositingRenderTarget*
 CompositorOGL::GetCurrentRenderTarget()
 {
@@ -838,28 +831,20 @@ CompositorOGL::BeginFrame(const nsIntReg
 
   // 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);
 
   mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
 
-  if (!aClipRectIn) {
-    mGLContext->fScissor(0, 0, width, height);
-    if (aClipRectOut) {
-      aClipRectOut->SetRect(0, 0, width, height);
-    }
-  } else {
-    mGLContext->fScissor(aClipRectIn->x, aClipRectIn->y, aClipRectIn->width, aClipRectIn->height);
+  if (aClipRectOut && !aClipRectIn) {
+    aClipRectOut->SetRect(0, 0, width, height);
   }
 
-  // Save the current scissor rect so that SetRenderTarget can pop back to it.
-  mGLContext->PushScissorRect();
-
   // 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
 }
@@ -1097,18 +1082,21 @@ CompositorOGL::DrawQuadInternal(const Re
   MOZ_ASSERT(mFrameInProgress, "frame not started");
 
   Rect clipRect = aClipRect;
   if (!mTarget) {
     clipRect.MoveBy(mRenderOffset.x, mRenderOffset.y);
   }
   IntRect intClipRect;
   clipRect.ToIntRect(&intClipRect);
-  mGLContext->PushScissorRect(nsIntRect(intClipRect.x, intClipRect.y,
-                                        intClipRect.width, intClipRect.height));
+  ScopedScissorRect autoScissor(mGLContext,
+                                intClipRect.x,
+                                FlipY(intClipRect.y + intClipRect.height),
+                                intClipRect.width,
+                                intClipRect.height);
 
   LayerScope::SendEffectChain(mGLContext, aEffectChain,
                               aRect.width, aRect.height);
 
   MaskType maskType;
   EffectMask* effectMask;
   TextureSourceOGL* sourceMask = nullptr;
   gfx::Matrix4x4 maskQuadTransform;
@@ -1359,17 +1347,16 @@ CompositorOGL::DrawQuadInternal(const Re
       }
     }
     break;
   default:
     MOZ_ASSERT(false, "Unhandled effect type");
     break;
   }
 
-  mGLContext->PopScissorRect();
   mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
   // in case rendering has used some other GL context
   MakeCurrent();
 }
 
 void
 CompositorOGL::EndFrame()
 {
@@ -1397,19 +1384,16 @@ CompositorOGL::EndFrame()
 
   if (mTarget) {
     CopyToTarget(mTarget, mCurrentRenderTarget->GetTransform());
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     mCurrentRenderTarget = nullptr;
     return;
   }
 
-  // Restore the scissor rect that we saved in BeginFrame.
-  mGLContext->PopScissorRect();
-
   mCurrentRenderTarget = nullptr;
 
   if (sDrawFPS && !mFPS) {
     mFPS = new FPSState();
   } else if (!sDrawFPS && mFPS) {
     mFPS = nullptr;
   }
 
@@ -1572,31 +1556,16 @@ CompositorOGL::GetMaxTextureSize() const
   GLint texSize = 0;
   mGLContext->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE,
                             &texSize);
   MOZ_ASSERT(texSize != 0);
   return texSize;
 }
 
 void
-CompositorOGL::SaveState()
-{
-  mGLContext->PushScissorRect();
-}
-
-void
-CompositorOGL::RestoreState()
-{
-  // Restore state that might be changed by drawBackground/drawForeground in
-  // mobile/android/base/gfx/LayerRenderer.java
-  mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
-  mGLContext->PopScissorRect();
-}
-
-void
 CompositorOGL::MakeCurrent(MakeCurrentFlags aFlags) {
   if (mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
     return;
   }
   mGLContext->MakeCurrent(aFlags & ForceMakeCurrent);
 }
 
@@ -1663,11 +1632,10 @@ CompositorOGL::BindAndDrawQuad(ShaderPro
                                GLuint aDrawMode)
 {
   NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
   BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib),
                   aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib),
                   aFlipped, aDrawMode);
 }
 
-
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -163,19 +163,16 @@ public:
   ShaderProgramType GetFBOLayerProgramType() const {
     return mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB ?
            RGBARectLayerProgramType : RGBALayerProgramType;
   }
   gfx::SurfaceFormat GetFBOFormat() const {
     return gfx::FORMAT_R8G8B8A8;
   }
 
-  virtual void SaveState() MOZ_OVERRIDE;
-  virtual void RestoreState() MOZ_OVERRIDE;
-
   /**
    * The compositor provides with temporary textures for use with direct
    * textruing like gralloc texture.
    * Doing so lets us use gralloc the way it has been designed to be used
    * (see https://wiki.mozilla.org/Platform/GFX/Gralloc)
    */
   GLuint GetTemporaryTexture(GLenum aUnit);
 private:
@@ -323,21 +320,38 @@ private:
    */
   void CopyToTarget(gfx::DrawTarget* aTarget, const gfxMatrix& aWorldMatrix);
 
   /**
    * Records the passed frame timestamp and returns the current estimated FPS.
    */
   double AddFrameAndGetFps(const TimeStamp& timestamp);
 
+  /**
+   * Implements the flipping of the y-axis to convert from layers/compositor
+   * coordinates to OpenGL coordinates.
+   *
+   * Indeed, the only coordinate system that OpenGL knows has the y-axis
+   * pointing upwards, but the layers/compositor coordinate system has the
+   * y-axis pointing downwards, for good reason as Web pages are typically
+   * scrolled downwards. So, some flipping has to take place; FlippedY does it.
+   */
+  GLint FlipY(GLint y) const { return mHeight - y; }
+
   bool mDestroyed;
 
   nsAutoPtr<FPSState> mFPS;
   // Textures used for direct texturing of buffers like gralloc.
   // The index of the texture in this array must correspond to the texture unit.
   nsTArray<GLuint> mTextures;
   static bool sDrawFPS;
+
+  /**
+   * Height of the OpenGL context's primary framebuffer in pixels. Used by
+   * FlipY for the y-flipping calculation.
+   */
+  GLint mHeight;
 };
 
 }
 }
 
 #endif /* MOZILLA_GFX_COMPOSITOROGL_H */
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MacIOSurfaceTextureHostOGL.h"
 #include "mozilla/gfx/MacIOSurface.h"
 #include "mozilla/layers/CompositorOGL.h"
-#include "GLContext.h"
+#include "GLContextCGL.h"
 
 namespace mozilla {
 namespace layers {
 
 MacIOSurfaceTextureSourceOGL::MacIOSurfaceTextureSourceOGL(
                                 CompositorOGL* aCompositor,
                                 MacIOSurface* aSurface)
   : mCompositor(aCompositor)
@@ -72,17 +72,17 @@ MacIOSurfaceTextureSourceOGL::BindTextur
   if (!gl()) {
     NS_WARNING("Trying to bind a texture without a GLContext");
     return;
   }
   GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex);
-  mSurface->CGLTexImageIOSurface2D(static_cast<CGLContextObj>(gl()->GetNativeData(gl::GLContext::NativeCGLContext)));
+  mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl())->GetCGLContext());
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 }
 
 gl::GLContext*
 MacIOSurfaceTextureSourceOGL::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
--- a/gfx/layers/opengl/OGLShaders.h
+++ b/gfx/layers/opengl/OGLShaders.h
@@ -1,9 +1,9 @@
-/* AUTOMATICALLY GENERATED from LayerManagerOGLShaders.txt */
+/* AUTOMATICALLY GENERATED from OGLShaders.txt */
 /* DO NOT EDIT! */
 
 static const char sLayerVS[] = "/* sLayerVS */\n\
 /* Vertex Shader */\n\
 uniform mat4 uMatrixProj;\n\
 uniform mat4 uLayerQuadTransform;\n\
 uniform mat4 uLayerTransform;\n\
 uniform mat4 uTextureTransform;\n\
--- a/gfx/layers/opengl/OGLShaders.txt
+++ b/gfx/layers/opengl/OGLShaders.txt
@@ -116,16 +116,17 @@ void main()
 
 $VERTEX_MASK_STUFF<mask>$
 
   finalPosition = finalPosition - uRenderTargetOffset;
   finalPosition.xyz *= finalPosition.w;
   finalPosition = uMatrixProj * finalPosition;
 
   vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;
+
   gl_Position = finalPosition;
 }
 @end
 
 
 /*
  * Fragment shaders
  */
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -110,16 +110,25 @@ gfxContext::gfxContext(DrawTarget *aTarg
 {
   MOZ_COUNT_CTOR(gfxContext);
 
   mStateStack.SetLength(1);
   CurrentState().drawTarget = mDT;
   mDT->SetTransform(Matrix());
 }
 
+/* static */ already_AddRefed<gfxContext>
+gfxContext::ContextForDrawTarget(DrawTarget* aTarget)
+{
+  Matrix transform = aTarget->GetTransform();
+  nsRefPtr<gfxContext> result = new gfxContext(aTarget);
+  result->SetMatrix(ThebesMatrix(transform));
+  return result.forget();
+}
+
 gfxContext::~gfxContext()
 {
   if (mCairo) {
     cairo_destroy(mCairo);
   }
   if (mRefCairo) {
     cairo_destroy(mRefCairo);
   }
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -43,22 +43,31 @@ class gfxContext {
 public:
     /**
      * Initialize this context from a surface.
      */
     gfxContext(gfxASurface *surface);
 
     /**
      * Initialize this context from a DrawTarget.
+     * Strips any transform from aTarget.
+     * aTarget will be flushed in the gfxContext's destructor.
      */
     gfxContext(mozilla::gfx::DrawTarget *aTarget);
 
     ~gfxContext();
 
     /**
+     * Create a new gfxContext wrapping aTarget and preserving aTarget's
+     * transform. Note that the transform is moved from aTarget to the resulting
+     * gfxContext, aTarget will no longer have its transform.
+     */
+    static already_AddRefed<gfxContext> ContextForDrawTarget(mozilla::gfx::DrawTarget* aTarget);
+
+    /**
      * Return the surface that this gfxContext was created with
      */
     gfxASurface *OriginalSurface();
 
     /**
      * Return the current transparency group target, if any, along
      * with its device offsets from the top.  If no group is
      * active, returns the surface the gfxContext was created with,
--- a/js/public/OldDebugAPI.h
+++ b/js/public/OldDebugAPI.h
@@ -18,23 +18,55 @@
 #include "js/CallArgs.h"
 #include "js/TypeDecls.h"
 
 class JSAtom;
 class JSFreeOp;
 
 namespace js { class StackFrame; }
 
+// Raw JSScript* because this needs to be callable from a signal handler.
+extern JS_PUBLIC_API(unsigned)
+JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
+
 namespace JS {
 
-struct FrameDescription
+class FrameDescription
 {
-    JSScript *script;
-    unsigned lineno;
-    JSFunction *fun;
+  public:
+    FrameDescription(JSScript *script, JSFunction *fun, jsbytecode *pc)
+        : script_(script)
+        , fun_(fun)
+        , pc_(pc)
+        , linenoComputed(false)
+    {
+    }
+
+    unsigned lineno() {
+        if (!linenoComputed) {
+            lineno_ = JS_PCToLineNumber(nullptr, script_, pc_);
+            linenoComputed = true;
+        }
+        return lineno_;
+    }
+
+    Heap<JSScript*> &script() {
+        return script_;
+    }
+
+    Heap<JSFunction*> &fun() {
+        return fun_;
+    }
+
+  private:
+    Heap<JSScript*> script_;
+    Heap<JSFunction*> fun_;
+    jsbytecode *pc_;
+    unsigned lineno_;
+    bool linenoComputed;
 };
 
 struct StackDescription
 {
     unsigned nframes;
     FrameDescription *frames;
 };
 
@@ -42,17 +74,17 @@ extern JS_PUBLIC_API(StackDescription *)
 DescribeStack(JSContext *cx, unsigned maxFrames);
 
 extern JS_PUBLIC_API(void)
 FreeStackDescription(JSContext *cx, StackDescription *desc);
 
 extern JS_PUBLIC_API(char *)
 FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps);
 
-}
+} // namespace JS
 
 # ifdef JS_DEBUG
 JS_FRIEND_API(void) js_DumpValue(const JS::Value &val);
 JS_FRIEND_API(void) js_DumpId(jsid id);
 JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, js::StackFrame *start = nullptr);
 # endif
 
 JS_FRIEND_API(void)
@@ -190,20 +222,16 @@ extern JS_PUBLIC_API(bool)
 JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
                    JSWatchPointHandler *handlerp, JSObject **closurep);
 
 extern JS_PUBLIC_API(bool)
 JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj);
 
 /************************************************************************/
 
-// Raw JSScript* because this needs to be callable from a signal handler.
-extern JS_PUBLIC_API(unsigned)
-JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
-
 extern JS_PUBLIC_API(jsbytecode *)
 JS_LineNumberToPC(JSContext *cx, JSScript *script, unsigned lineno);
 
 extern JS_PUBLIC_API(jsbytecode *)
 JS_EndPC(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(bool)
 JS_GetLinePCs(JSContext *cx, JSScript *script,
--- a/js/public/Tracer.h
+++ b/js/public/Tracer.h
@@ -152,16 +152,19 @@ extern JS_PUBLIC_API(void)
 JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap<JSObject *> *objp, const char *name);
 
 extern JS_PUBLIC_API(void)
 JS_CallHeapStringTracer(JSTracer *trc, JS::Heap<JSString *> *strp, const char *name);
 
 extern JS_PUBLIC_API(void)
 JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char *name);
 
+extern JS_PUBLIC_API(void)
+JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap<JSFunction *> *funp, const char *name);
+
 template <typename HashSetEnum>
 inline void
 JS_CallHashSetObjectTracer(JSTracer *trc, HashSetEnum &e, JSObject *const &key, const char *name)
 {
     JSObject *updated = key;
     JS_SET_TRACING_LOCATION(trc, reinterpret_cast<void *>(&const_cast<JSObject *&>(key)));
     JS_CallObjectTracer(trc, &updated, name);
     if (updated != key)
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -74,16 +74,22 @@ JS_CallHeapStringTracer(JSTracer *trc, J
 
 JS_PUBLIC_API(void)
 JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char *name)
 {
     MarkScriptUnbarriered(trc, scriptp->unsafeGet(), name);
 }
 
 JS_PUBLIC_API(void)
+JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap<JSFunction *> *funp, const char *name)
+{
+    MarkObjectUnbarriered(trc, funp->unsafeGet(), name);
+}
+
+JS_PUBLIC_API(void)
 JS_CallTenuredObjectTracer(JSTracer *trc, JS::TenuredHeap<JSObject *> *objp, const char *name)
 {
     JSObject *obj = objp->getPtr();
     if (!obj)
         return;
 
     JS_SET_TRACING_LOCATION(trc, (void*)objp);
     MarkObjectUnbarriered(trc, &obj, name);
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -929,20 +929,17 @@ js_CallContextDebugHandler(JSContext *cx
 }
 
 JS_PUBLIC_API(JS::StackDescription *)
 JS::DescribeStack(JSContext *cx, unsigned maxFrames)
 {
     Vector<FrameDescription> frames(cx);
 
     for (NonBuiltinScriptFrameIter i(cx); !i.done(); ++i) {
-        FrameDescription desc;
-        desc.script = i.script();
-        desc.lineno = PCToLineNumber(i.script(), i.pc());
-        desc.fun = i.maybeCallee();
+        FrameDescription desc(i.script(), i.maybeCallee(), i.pc());
         if (!frames.append(desc))
             return nullptr;
         if (frames.length() == maxFrames)
             break;
     }
 
     JS::StackDescription *desc = js_new<JS::StackDescription>();
     if (!desc)
@@ -951,17 +948,19 @@ JS::DescribeStack(JSContext *cx, unsigne
     desc->nframes = frames.length();
     desc->frames = frames.extractRawBuffer();
     return desc;
 }
 
 JS_PUBLIC_API(void)
 JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc)
 {
-    js_delete(desc->frames);
+    for (size_t i = 0; i < desc->nframes; ++i)
+        desc->frames[i].~FrameDescription();
+    js_free(desc->frames);
     js_delete(desc);
 }
 
 namespace {
 
 class AutoPropertyDescArray
 {
     JSContext *cx_;
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -14,16 +14,17 @@ import org.mozilla.gecko.mozglue.JNITarg
 import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter;
 import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
 import org.mozilla.gecko.prompts.PromptService;
 import org.mozilla.gecko.mozglue.GeckoLoader;
 import org.mozilla.gecko.mozglue.RobocopTarget;
 import org.mozilla.gecko.util.EventDispatcher;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.HardwareUtils;
+import org.mozilla.gecko.util.ProxySelector;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
@@ -92,17 +93,16 @@ import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.Proxy;
-import java.net.ProxySelector;
 import java.net.URI;
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -2658,88 +2658,21 @@ public class GeckoAppShell
         if (getGeckoInterface() != null) {
             GeckoProfile profile = getGeckoInterface().getProfile();
             File lock = profile.getFile(".parentlock");
             return lock.exists() && lock.delete();
         }
         return false;
     }
 
-    // Holds mappings from hostnames to URIs.
-    // We only use this for HTTP and HTTPS on default ports (-1), because it's
-    // simpler to do so while addressing most uses.
-    private static LruCache<String, URI> httpURIs = new LruCache<String, URI>(10);
-    private static LruCache<String, URI> httpsURIs = new LruCache<String, URI>(10);
-
-    private static URI getAndCacheURIByParts(String scheme, String host, LruCache<String, URI> cache) {
-        URI uri = cache.get(host);
-        if (uri != null) {
-            return uri;
-        }
-
-        try {
-            uri = new URI(scheme, null, host, -1, null, null, null);
-        } catch (java.net.URISyntaxException uriEx) {
-            Log.d("GeckoProxy", "Failed to create URI from parts.", uriEx);
-            return null;
-        }
-
-        cache.put(host, uri);
-        return uri;
-    }
-
-    private static URI getURIByParts(String scheme, String host, int port) {
-        if (port == -1) {
-            if (scheme.equals("http")) {
-                return getAndCacheURIByParts("http", host, httpURIs);
-            } else if (scheme.equals("https")) {
-                return getAndCacheURIByParts("https", host, httpsURIs);
-            }
-        }
-
-        try {
-            return new URI(scheme, null, host, port, null, null, null);
-        } catch (java.net.URISyntaxException uriEx) {
-            Log.d("GeckoProxy", "Failed to create URI from parts.", uriEx);
-        }
-
-        return null;
-    }
-
     @WrapElementForJNI(stubName = "GetProxyForURIWrapper")
     public static String getProxyForURI(String spec, String scheme, String host, int port) {
-        final ProxySelector ps;
-        try {
-            // This is cheap -- just a SecurityManager check and a static
-            // access inside ProxySelector.
-            ps = ProxySelector.getDefault();
-        } catch (SecurityException ex) {
-            Log.w(LOGTAG, "Not allowed to use default ProxySelector.");
-            return "DIRECT";
-        }
-
-        if (ps == null) {
-            return "DIRECT";
-        }
+        final ProxySelector ps = new ProxySelector();
 
-        // We don't use the whole spec because parsing a URI from a string
-        // is expensive, and the stock Android proxy behavior looks only at
-        // the scheme and host.
-        URI uri = getURIByParts(scheme, host, port);
-
-        if (uri == null) {
-            return "DIRECT";
-        }
-
-        List<Proxy> proxies = ps.select(uri);
-        if (proxies == null || proxies.isEmpty()) {
-            return "DIRECT";
-        }
-
-        Proxy proxy = proxies.get(0);
+        Proxy proxy = ps.select(scheme, host);
         if (Proxy.NO_PROXY.equals(proxy)) {
             return "DIRECT";
         }
         
         switch (proxy.type()) {
             case HTTP:
                 return "PROXY " + proxy.address().toString();
             case SOCKS:
--- a/mobile/android/base/Tab.java
+++ b/mobile/android/base/Tab.java
@@ -202,17 +202,17 @@ public class Tab {
     }
 
     public void updateThumbnail(final Bitmap b) {
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
                 if (b != null) {
                     try {
-                        mThumbnail = new BitmapDrawable(b);
+                        mThumbnail = new BitmapDrawable(mAppContext.getResources(), b);
                         if (mState == Tab.STATE_SUCCESS)
                             saveThumbnailToDB();
                     } catch (OutOfMemoryError oom) {
                         Log.w(LOGTAG, "Unable to create/scale bitmap.", oom);
                         mThumbnail = null;
                     }
                 } else {
                     mThumbnail = null;
--- a/mobile/android/base/gfx/BitmapUtils.java
+++ b/mobile/android/base/gfx/BitmapUtils.java
@@ -42,17 +42,17 @@ public final class BitmapUtils {
 
     public static void getDrawable(final Context context, final String data, final BitmapLoader loader) {
         if (TextUtils.isEmpty(data)) {
             loader.onBitmapFound(null);
             return;
         }
 
         if (data.startsWith("data")) {
-            BitmapDrawable d = new BitmapDrawable(getBitmapFromDataURI(data));
+            BitmapDrawable d = new BitmapDrawable(context.getResources(), getBitmapFromDataURI(data));
             loader.onBitmapFound(d);
             return;
         }
 
         if (data.startsWith("jar:") || data.startsWith("file://")) {
             (new UiAsyncTask<Void, Void, Drawable>(ThreadUtils.getBackgroundHandler()) {
                 @Override
                 public Drawable doInBackground(Void... params) {
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -48,16 +48,17 @@ gujar.sources += [
     'util/GeckoEventListener.java',
     'util/GeckoEventResponder.java',
     'util/GeckoJarReader.java',
     'util/HardwareUtils.java',
     'util/INIParser.java',
     'util/INISection.java',
     'util/JSONUtils.java',
     'util/NonEvictingLruCache.java',
+    'util/ProxySelector.java',
     'util/StringUtils.java',
     'util/ThreadUtils.java',
     'util/UiAsyncTask.java',
 ]
 gujar.extra_jars = [
     'gecko-mozglue.jar'
 ]
 gujar.javac_flags += ['-Xlint:all,-deprecation']
--- a/mobile/android/base/preferences/SearchEnginePreference.java
+++ b/mobile/android/base/preferences/SearchEnginePreference.java
@@ -188,17 +188,17 @@ public class SearchEnginePreference exte
                         break;
                 }
             }
         });
 
         // Copy the icon from this object to the prompt we produce. We lazily create the drawable,
         // as the user may not ever actually tap this object.
         if (mPromptIcon == null && mIconBitmap != null) {
-            mPromptIcon = new BitmapDrawable(mFaviconView.getBitmap());
+            mPromptIcon = new BitmapDrawable(getContext().getResources(), mFaviconView.getBitmap());
         }
 
         // Icons are hidden until Bug 926711 is fixed.
         //builder.setIcon(mPromptIcon);
 
         // We have to construct the dialog itself on the UI thread.
         ThreadUtils.postToUiThread(new Runnable() {
             @Override
--- a/mobile/android/base/prompts/Prompt.java
+++ b/mobile/android/base/prompts/Prompt.java
@@ -581,17 +581,17 @@ public class Prompt implements OnClickLi
             Drawable d = null;
             Resources res = mContext.getResources();
             // Set the padding between the icon and the text.
             t.setCompoundDrawablePadding(mIconTextPadding);
             if (item.icon != null) {
                 // We want the icon to be of a specific size. Some do not
                 // follow this rule so we have to resize them.
                 Bitmap bitmap = ((BitmapDrawable) item.icon).getBitmap();
-                d = new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, mIconSize, mIconSize, true));
+                d = new BitmapDrawable(res, Bitmap.createScaledBitmap(bitmap, mIconSize, mIconSize, true));
             } else if (item.inGroup) {
                 // We don't currently support "indenting" items with icons
                 d = getBlankDrawable(res);
             }
 
             Drawable moreDrawable = null;
             if (item.isParent) {
                 moreDrawable = getMoreDrawable(res);
--- a/mobile/android/base/tests/helpers/WaitHelper.java
+++ b/mobile/android/base/tests/helpers/WaitHelper.java
@@ -20,17 +20,17 @@ import java.util.regex.Pattern;
 /**
  * Provides functionality related to waiting on certain events to happen.
  */
 public final class WaitHelper {
     // TODO: Make public for when Solo.waitForCondition is used directly (i.e. do not want
     // assertion from waitFor)?
     private static final int DEFAULT_MAX_WAIT_MS = 5000;
     private static final int PAGE_LOAD_WAIT_MS = 10000;
-    private static final int CHANGE_WAIT_MS = 5000;
+    private static final int CHANGE_WAIT_MS = 10000;
 
     // TODO: via lucasr - Add ThrobberVisibilityChangeVerifier?
     private static final ChangeVerifier[] PAGE_LOAD_VERIFIERS = new ChangeVerifier[] {
         new ToolbarTitleTextChangeVerifier()
     };
 
     private static UITestContext sContext;
     private static Solo sSolo;
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/util/ProxySelector.java
@@ -0,0 +1,130 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This code is based on AOSP /libcore/luni/src/main/java/java/net/ProxySelectorImpl.java
+
+package org.mozilla.gecko.util;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+
+public class ProxySelector {
+    public ProxySelector() {
+    }
+
+    public Proxy select(String scheme, String host) {
+        int port = -1;
+        Proxy proxy = null;
+        String nonProxyHostsKey = null;
+        boolean httpProxyOkay = true;
+        if ("http".equalsIgnoreCase(scheme)) {
+            port = 80;
+            nonProxyHostsKey = "http.nonProxyHosts";
+            proxy = lookupProxy("http.proxyHost", "http.proxyPort", Proxy.Type.HTTP, port);
+        } else if ("https".equalsIgnoreCase(scheme)) {
+            port = 443;
+            nonProxyHostsKey = "https.nonProxyHosts"; // RI doesn't support this
+            proxy = lookupProxy("https.proxyHost", "https.proxyPort", Proxy.Type.HTTP, port);
+        } else if ("ftp".equalsIgnoreCase(scheme)) {
+            port = 80; // not 21 as you might guess
+            nonProxyHostsKey = "ftp.nonProxyHosts";
+            proxy = lookupProxy("ftp.proxyHost", "ftp.proxyPort", Proxy.Type.HTTP, port);
+        } else if ("socket".equalsIgnoreCase(scheme)) {
+            httpProxyOkay = false;
+        } else {
+            return Proxy.NO_PROXY;
+        }
+
+        if (nonProxyHostsKey != null
+                && isNonProxyHost(host, System.getProperty(nonProxyHostsKey))) {
+            return Proxy.NO_PROXY;
+        }
+
+        if (proxy != null) {
+            return proxy;
+        }
+
+        if (httpProxyOkay) {
+            proxy = lookupProxy("proxyHost", "proxyPort", Proxy.Type.HTTP, port);
+            if (proxy != null) {
+                return proxy;
+            }
+        }
+
+        proxy = lookupProxy("socksProxyHost", "socksProxyPort", Proxy.Type.SOCKS, 1080);
+        if (proxy != null) {
+            return proxy;
+        }
+
+        return Proxy.NO_PROXY;
+    }
+
+    /**
+     * Returns the proxy identified by the {@code hostKey} system property, or
+     * null.
+     */
+    private Proxy lookupProxy(String hostKey, String portKey, Proxy.Type type, int defaultPort) {
+        String host = System.getProperty(hostKey);
+        if (host == null || host.isEmpty()) {
+            return null;
+        }
+
+        int port = getSystemPropertyInt(portKey, defaultPort);
+        return new Proxy(type, InetSocketAddress.createUnresolved(host, port));
+    }
+
+    private int getSystemPropertyInt(String key, int defaultValue) {
+        String string = System.getProperty(key);
+        if (string != null) {
+            try {
+                return Integer.parseInt(string);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Returns true if the {@code nonProxyHosts} system property pattern exists
+     * and matches {@code host}.
+     */
+    private boolean isNonProxyHost(String host, String nonProxyHosts) {
+        if (host == null || nonProxyHosts == null) {
+            return false;
+        }
+
+        // construct pattern
+        StringBuilder patternBuilder = new StringBuilder();
+        for (int i = 0; i < nonProxyHosts.length(); i++) {
+            char c = nonProxyHosts.charAt(i);
+            switch (c) {
+            case '.':
+                patternBuilder.append("\\.");
+                break;
+            case '*':
+                patternBuilder.append(".*");
+                break;
+            default:
+                patternBuilder.append(c);
+            }
+        }
+        // check whether the host is the nonProxyHosts.
+        String pattern = patternBuilder.toString();
+        return host.matches(pattern);
+    }
+}
+
--- a/mobile/android/chrome/content/SelectionHandler.js
+++ b/mobile/android/chrome/content/SelectionHandler.js
@@ -536,16 +536,20 @@ var SelectionHandler = {
    * @param aIsStartHandle whether the user is moving the start handle (as opposed to the end handle)
    * @param aX, aY selection point in client coordinates
    */
   _moveSelection: function sh_moveSelection(aIsStartHandle, aX, aY) {
     // XXX We should be smarter about the coordinates we pass to caretPositionFromPoint, especially
     // in editable targets. We should factor out the logic that's currently in _sendMouseEvents.
     let viewOffset = this._getViewOffset();
     let caretPos = this._contentWindow.document.caretPositionFromPoint(aX - viewOffset.x, aY - viewOffset.y);
+    if (!caretPos) {
+      // User moves handle offscreen while positioning
+      return;
+    }
 
     // Constrain text selection within editable elements.
     let targetIsEditable = this._targetElement instanceof Ci.nsIDOMNSEditableElement;
     if (targetIsEditable && (caretPos.offsetNode != this._targetElement)) {
       return;
     }
 
     // Update the cache as the handle is dragged (keep the cache in client coordinates).
--- a/mobile/locales/en-US/searchplugins/bing.xml
+++ b/mobile/locales/en-US/searchplugins/bing.xml
@@ -1,15 +1,15 @@
 <!-- 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/. -->
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Bing</ShortName>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAIAAAD+THXTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABOZJREFUeNrsm1tMIlccxmcYLmMERRRhRLzgBRQVulqUZpuuXbNtHxpp003Ntpv2pUnTlybtW9+6bbrdvjR9rL1k29S0TZpsTVe7Ju5qutRdQOKlgjBQGUdEUBFEBQSG6YNJNV27EbnIkPneIAPkN3PO/3zf/xxAnU4HFJYYQMGJRqKRaCQaiUY6XoLiKJcTy3MkSKFQnPxqrcxzXXe/vXqDB8dDUfbuPjsPkZipfgAESSXiVyL+N7ULq0GeCRMbMDHqEyRJkKpIRyXh70jUOzq1IxRlm5fFRgyZdQujcSaFkf5VCRzrleO9cjxOMD4Yftq5XlY4FY8FJWEmQRdxGolGopFoJBop/5AgBskASaq6h//TjZf+WAnwjBgyu1IZTUCURyKS4AQqfev8fK8cjxPQvFtowBATJg5GOBR+SndttQNdNh4cY0FEZ623s9ZLPgOgPoERQ4yY2B3gUQ9pPwHdsdRf7rQfZhMAkIu25KKtq92WtW2uwYUYMLHdJyAzl02yHgRuL8h0aicLOsbLIqW7OrVDp3aEIhzTssiIIbPuyljaUy7rSKEI55695rlW1+OySdH+RQV+UYHHCWhmRWjEqkzLotBpp1wu4trwXMOlVtdJBhYLIjR1Xk2dlyRBu09gwMRGF+LZ5uYd0to21+Cq6qn3pNQOUIj9CrH/jR7LapBncCGjCzL/HpxH7uHWbGM67YCXn0AbKwP5ZYhQn2DRW15oHu/WTFOhIU0viz8e1f61KqS2xzsqEgDMuMiMi2QVwX6V83zjapZM7RmEi6VN/ud3u94eujQ81xjJQtPvzPLSxm7RzQdt7/zYh2+VUHXgPZqmepvxV7tsFdwI5ZFAANDKPFc0Vgl/l9rl4UCq6o3Xuy2NwmAhVLymysDVbmu7ZINiRXwCldq8gv+8KS3buaKx9tSvUS+o/zrb9P1D5dG1RsiNDDy5eKF5Jc0laGqpyv7Inco60rdT7b/NNxxGIDh2udP+vNLFZCTT+drVIPcrfcecuzKnT4lIMr64d+6+s/rgZREr0a9y9qsdae7KROPMn83y2/MNiSQjpwMvEmfeGNMc3EUWRLygxF45Z+fB6W5R6/+W3JxqP2FAyiRSKML5cES7tMmHGOSFZnwgE+smvsUb1KssnoozKA/eUPG1kae828Vamec1zaKEv5MmTDjG/Gm6ZXRBRiTT6hadEmlpk39tRFtXHnqvz5SRdXMSlX73oC0jXcvTIM25hb/MyN/vm87IuunaLB3Uq2wnrtGZRzLjokSS8dGL+vR/e2+fNWRqGbPUZ/bMRGpILn/pQJdNyAunHwfHF2t/MChD0cyfb0ntwE0wDE+gUlFJuEZw+mLgXC/7bKz7jrV+Pzt7GakhAQAQI6CpJYkvVNwh2WBBqTmDnSj7mz/bv9Sr/HtFeefxJlGpda383WfNrYj/RCONBMesdUPGlhycpEr5KR1O7hhrEq2JEVBblf/xrhT1Ca7f6Rm31caIXOyanR4JAAASABe95dPLorYqf8lxJmg7whnUq77WdwTCMJArpYV0oEAYHrfVctmJpiM93iQJji40fDqmcawLgNwqA0gHZtyMixzrZSrJJsxKWNbKP/m9ZwKtiRMQkHOBmf2DQgkca0X8BhdyBjvpWQrqoSj7oQsBzlT0UQ4aiUaikWgkGolGyqr+GQA3EekkujFd/wAAAABJRU5ErkJggg==</Image>
+<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjMzMkQxN0Y5NkYxMDExRTNCRERGREFGNkIwOTFENDc1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjMzMkQxN0ZBNkYxMDExRTNCRERGREFGNkIwOTFENDc1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MzMyRDE3Rjc2RjEwMTFFM0JEREZEQUY2QjA5MUQ0NzUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MzMyRDE3Rjg2RjEwMTFFM0JEREZEQUY2QjA5MUQ0NzUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4iSWmdAAACDElEQVR42mIMCAhgoCVgYqAxGPoWMGtoaGCKzo7ZKcH37c9fpjdfOf//Z6TEAhasoiI837107gHR15+sZx9JzDum8/E7O02CiJv9t53qYyHuH6OpiCBgZPxPWwv4OX71BB+INL2uJPKBCqkIE3z4zv7gLV+Y8U0gev2F8+R9qRP3Ja8/F/5HKBGzEO+WTZdUnDUeARmiPN99dO8C0acfbKcfSJ68L3nhiejvv8yUWvDoHd+Fx2IGsq/gInwcv5w1HgLRjz/M5x6Jd+8yozQVbbioglWcg+WvldIzKiTTS0/EmrdZXn4qQv1IhgBgUgUGBRDpSr+u9DjJyfqHyhaASkemf25aD8KNbxJjOlEW/PnH9O0nKyivMTBYKj+NMbsmyf+VakH07RdLx07zl5+5dKTexFtcVRF7j8sRGy6okGwBMJk3b7X6/Zepxuu4sdxLXMouPhGdfUT/6Qce0ix4+5Vzwl5jYJXgoP4IV2Z9/40DWFUcuSNDchA9/8hz6alInfdxVua/WBUAS4itl5VWnNEEhiE5cfDoHa+71gNcem6+FJpxSP/BW37y6+Sjd2V+/GbRkX7DhFpKf/7BNveo3uzD+h++c1CUiv6DS4VLT0WLXE5LC3yBiOy5Lr/4pDbQDiq0KuBxuO+GPD/nL6A/Onea77iq9OsPM3VaFXAALCanHTQYbToObQsAAgwAOOjO/za44IcAAAAASUVORK5CYII=</Image>
 <Url type="application/x-suggestions+json" template="http://api.bing.com/osjson.aspx">
   <Param name="query" value="{searchTerms}"/>
   <Param name="form" value="OSDJAS"/>
   <Param name="language" value="{moz:locale}"/>
 </Url>
 <Url type="text/html" method="GET" template="http://www.bing.com/search">
   <Param name="q" value="{searchTerms}" />
   <MozParam name="pc" condition="defaultEngine" trueValue="MOZI" falseValue="" />
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -225,26 +225,30 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFt
 #undef LOG
 #undef LOG_ENABLED
 #include "nsHttpAuthManager.h"
 #include "nsHttpChannelAuthProvider.h"
 #include "nsHttpBasicAuth.h"
 #include "nsHttpDigestAuth.h"
 #include "nsHttpNTLMAuth.h"
 #include "nsHttpActivityDistributor.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNTLMAuth)
 #undef LOG
 #undef LOG_ENABLED
+namespace mozilla {
+namespace net {
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNTLMAuth)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpHandler, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpsHandler, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpAuthManager, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpChannelAuthProvider)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpActivityDistributor)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
+}
+}
 #endif // !NECKO_PROTOCOL_http
 
 #include "mozilla/net/Dashboard.h"
 namespace mozilla {
 namespace net {
   NS_GENERIC_FACTORY_CONSTRUCTOR(Dashboard)
 }
 }
@@ -881,24 +885,24 @@ static const mozilla::Module::CIDEntry k
 #endif
     { &kMOZITXTTOHTMLCONV_CID, false, nullptr, CreateNewTXTToHTMLConvFactory },
     { &kNS_DIRINDEX_CID, false, nullptr, nsDirIndexConstructor },
     { &kNS_MIMEHEADERPARAM_CID, false, nullptr, nsMIMEHeaderParamImplConstructor },
 #ifdef NECKO_PROTOCOL_file
     { &kNS_FILEPROTOCOLHANDLER_CID, false, nullptr, nsFileProtocolHandlerConstructor },
 #endif
 #ifdef NECKO_PROTOCOL_http
-    { &kNS_HTTPPROTOCOLHANDLER_CID, false, nullptr, nsHttpHandlerConstructor },
-    { &kNS_HTTPSPROTOCOLHANDLER_CID, false, nullptr, nsHttpsHandlerConstructor },
-    { &kNS_HTTPBASICAUTH_CID, false, nullptr, nsHttpBasicAuthConstructor },
-    { &kNS_HTTPDIGESTAUTH_CID, false, nullptr, nsHttpDigestAuthConstructor },
-    { &kNS_HTTPNTLMAUTH_CID, false, nullptr, nsHttpNTLMAuthConstructor },
-    { &kNS_HTTPAUTHMANAGER_CID, false, nullptr, nsHttpAuthManagerConstructor },
-    { &kNS_HTTPCHANNELAUTHPROVIDER_CID, false, nullptr, nsHttpChannelAuthProviderConstructor },
-    { &kNS_HTTPACTIVITYDISTRIBUTOR_CID, false, nullptr, nsHttpActivityDistributorConstructor },
+    { &kNS_HTTPPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::nsHttpHandlerConstructor },
+    { &kNS_HTTPSPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::nsHttpsHandlerConstructor },
+    { &kNS_HTTPBASICAUTH_CID, false, nullptr, mozilla::net::nsHttpBasicAuthConstructor },
+    { &kNS_HTTPDIGESTAUTH_CID, false, nullptr, mozilla::net::nsHttpDigestAuthConstructor },
+    { &kNS_HTTPNTLMAUTH_CID, false, nullptr, mozilla::net::nsHttpNTLMAuthConstructor },
+    { &kNS_HTTPAUTHMANAGER_CID, false, nullptr, mozilla::net::nsHttpAuthManagerConstructor },
+    { &kNS_HTTPCHANNELAUTHPROVIDER_CID, false, nullptr, mozilla::net::nsHttpChannelAuthProviderConstructor },
+    { &kNS_HTTPACTIVITYDISTRIBUTOR_CID, false, nullptr, mozilla::net::nsHttpActivityDistributorConstructor },
 #endif // !NECKO_PROTOCOL_http
 #ifdef NECKO_PROTOCOL_ftp
     { &kNS_FTPPROTOCOLHANDLER_CID, false, nullptr, nsFtpProtocolHandlerConstructor },
 #endif
 #ifdef NECKO_PROTOCOL_res
     { &kNS_RESPROTOCOLHANDLER_CID, false, nullptr, nsResProtocolHandlerConstructor },
     { &kNS_RESURL_CID, false, nullptr, nsResURLConstructor },
 #endif
--- a/netwerk/protocol/http/ConnectionDiagnostics.cpp
+++ b/netwerk/protocol/http/ConnectionDiagnostics.cpp
@@ -10,20 +10,21 @@
 #include "nsHttpConnectionMgr.h"
 #include "nsHttpConnection.h"
 #include "SpdySession3.h"
 #include "SpdySession31.h"
 #include "nsHttpHandler.h"
 #include "nsIConsoleService.h"
 #include "nsHttpRequestHead.h"
 
-using namespace mozilla;
-using namespace mozilla::net;
 extern PRThread *gSocketThread;
 
+namespace mozilla {
+namespace net {
+
 void
 nsHttpConnectionMgr::PrintDiagnostics()
 {
   PostEvent(&nsHttpConnectionMgr::OnMsgPrintDiagnostics, 0, nullptr);
 }
 
 void
 nsHttpConnectionMgr::OnMsgPrintDiagnostics(int32_t, void *)
@@ -242,8 +243,11 @@ nsHttpTransaction::PrintDiagnostics(nsCS
 
   log.AppendPrintf("     ::: uri = %s\n",
                    nsAutoCString(mRequestHead->RequestURI()).get());
   log.AppendPrintf("     caps = 0x%x\n", mCaps);
   log.AppendPrintf("     priority = %d\n", mPriority);
   log.AppendPrintf("     restart count = %u\n", mRestartCount);
   log.AppendPrintf("     classification = 0x%x\n", mClassification);
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -94,18 +94,18 @@ protected:
   bool RecvOnStartRequest(const nsHttpResponseHead& responseHead,
                           const bool& useResponseHead,
                           const nsHttpHeaderArray& requestHeaders,
                           const bool& isFromCache,
                           const bool& cacheEntryAvailable,
                           const uint32_t& cacheExpirationTime,
                           const nsCString& cachedCharset,
                           const nsCString& securityInfoSerialization,
-                          const mozilla::net::NetAddr& selfAddr,
-                          const mozilla::net::NetAddr& peerAddr);
+                          const NetAddr& selfAddr,
+                          const NetAddr& peerAddr);
   bool RecvOnTransportAndData(const nsresult& status,
                               const uint64_t& progress,
                               const uint64_t& progressMax,
                               const nsCString& data,
                               const uint64_t& offset,
                               const uint32_t& count);
   bool RecvOnStopRequest(const nsresult& statusCode);
   bool RecvOnProgress(const uint64_t& progress, const uint64_t& progressMax);
@@ -148,18 +148,18 @@ private:
   void OnStartRequest(const nsHttpResponseHead& responseHead,
                       const bool& useResponseHead,
                       const nsHttpHeaderArray& requestHeaders,
                       const bool& isFromCache,
                       const bool& cacheEntryAvailable,
                       const uint32_t& cacheExpirationTime,
                       const nsCString& cachedCharset,
                       const nsCString& securityInfoSerialization,
-                      const mozilla::net::NetAddr& selfAddr,
-                      const mozilla::net::NetAddr& peerAddr);
+                      const NetAddr& selfAddr,
+                      const NetAddr& peerAddr);
   void OnTransportAndData(const nsresult& status,
                           const uint64_t progress,
                           const uint64_t& progressMax,
                           const nsCString& data,
                           const uint64_t& offset,
                           const uint32_t& count);
   void OnStopRequest(const nsresult& statusCode);
   void OnProgress(const uint64_t& progress, const uint64_t& progressMax);
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -14,17 +14,16 @@
 #include "mozilla/net/NeckoCommon.h"
 #include "mozilla/net/NeckoParent.h"
 #include "nsIParentRedirectingChannel.h"
 #include "nsIProgressEventSink.h"
 #include "nsHttpChannel.h"
 
 class nsICacheEntry;
 class nsIAssociatedContentSecurity;
-class nsHttpHandler;
 
 namespace mozilla {
 
 namespace dom{
 class TabParent;
 }
 
 namespace net {
@@ -89,17 +88,17 @@ protected:
   virtual bool RecvUpdateAssociatedContentSecurity(const int32_t& broken,
                                                    const int32_t& no);
   virtual bool RecvDocumentChannelCleanup();
   virtual bool RecvMarkOfflineCacheEntryAsForeign();
 
   virtual void ActorDestroy(ActorDestroyReason why);
 
 protected:
-  friend class mozilla::net::HttpChannelParentListener;
+  friend class HttpChannelParentListener;
   nsRefPtr<mozilla::dom::TabParent> mTabParent;
 
 private:
   nsCOMPtr<nsIChannel>                    mChannel;
   nsCOMPtr<nsICacheEntry>       mCacheEntry;
   nsCOMPtr<nsIAssociatedContentSecurity>  mAssociatedContentSecurity;
   bool mIPCClosed;                // PHttpChannel actor has been Closed()
 
--- a/netwerk/protocol/http/NullHttpTransaction.h
+++ b/netwerk/protocol/http/NullHttpTransaction.h
@@ -5,27 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_net_NullHttpTransaction_h
 #define mozilla_net_NullHttpTransaction_h
 
 #include "nsAHttpTransaction.h"
 #include "mozilla/Attributes.h"
 
-class nsAHttpConnection;
-class nsHttpRequestHead;
-class nsHttpConnectionInfo;
-
 // This is the minimal nsAHttpTransaction implementation. A NullHttpTransaction
 // can be used to drive connection level semantics (such as SSL handshakes
 // tunnels) so that a nsHttpConnection becomes fully established in
 // anticipation of a real transaction needing to use it soon.
 
 namespace mozilla { namespace net {
 
+class nsAHttpConnection;
+class nsHttpConnectionInfo;
+class nsHttpRequestHead;
+
 class NullHttpTransaction MOZ_FINAL : public nsAHttpTransaction
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSAHTTPTRANSACTION
 
   NullHttpTransaction(nsHttpConnectionInfo *ci,
                       nsIInterfaceRequestor *callbacks,
--- a/netwerk/protocol/http/PHttpChannelParams.h
+++ b/netwerk/protocol/http/PHttpChannelParams.h
@@ -59,44 +59,44 @@ struct ParamTraits<mozilla::net::Request
         !ReadParam(aMsg, aIter, &aResult->mMerge))
       return false;
 
     return true;
   }
 };
 
 template<>
-struct ParamTraits<nsHttpAtom>
+struct ParamTraits<mozilla::net::nsHttpAtom>
 {
-  typedef nsHttpAtom paramType;
+  typedef mozilla::net::nsHttpAtom paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     // aParam.get() cannot be null.
     MOZ_ASSERT(aParam.get(), "null nsHTTPAtom value");
     nsAutoCString value(aParam.get());
     WriteParam(aMsg, value);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     nsAutoCString value;
     if (!ReadParam(aMsg, aIter, &value))
       return false;
 
-    *aResult = nsHttp::ResolveAtom(value.get());
+    *aResult = mozilla::net::nsHttp::ResolveAtom(value.get());
     MOZ_ASSERT(aResult->get(), "atom table not initialized");
     return true;
   }
 };
 
 template<>
-struct ParamTraits<nsHttpHeaderArray::nsEntry>
+struct ParamTraits<mozilla::net::nsHttpHeaderArray::nsEntry>
 {
-  typedef nsHttpHeaderArray::nsEntry paramType;
+  typedef mozilla::net::nsHttpHeaderArray::nsEntry paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.header);
     WriteParam(aMsg, aParam.value);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
@@ -106,19 +106,19 @@ struct ParamTraits<nsHttpHeaderArray::ns
       return false;
 
     return true;
   }
 };
 
 
 template<>
-struct ParamTraits<nsHttpHeaderArray>
+struct ParamTraits<mozilla::net::nsHttpHeaderArray>
 {
-  typedef nsHttpHeaderArray paramType;
+  typedef mozilla::net::nsHttpHeaderArray paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     paramType& p = const_cast<paramType&>(aParam);
 
     WriteParam(aMsg, p.mHeaders);
   }
 
@@ -127,19 +127,19 @@ struct ParamTraits<nsHttpHeaderArray>
     if (!ReadParam(aMsg, aIter, &aResult->mHeaders))
       return false;
 
     return true;
   }
 };
 
 template<>
-struct ParamTraits<nsHttpResponseHead>
+struct ParamTraits<mozilla::net::nsHttpResponseHead>
 {
-  typedef nsHttpResponseHead paramType;
+  typedef mozilla::net::nsHttpResponseHead paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mHeaders);
     WriteParam(aMsg, aParam.mVersion);
     WriteParam(aMsg, aParam.mStatus);
     WriteParam(aMsg, aParam.mStatusText);
     WriteParam(aMsg, aParam.mContentLength);
--- a/netwerk/protocol/http/SpdyPush3.h
+++ b/netwerk/protocol/http/SpdyPush3.h
@@ -56,17 +56,17 @@ public:
 private:
 
   SpdyStream3 *mConsumerStream; // paired request stream that consumes from
                                 // real spdy one.. null until a match is made.
 
   nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
 
   SpdyPush3TransactionBuffer *mBufferedPush;
-  mozilla::TimeStamp          mLastRead;
+  TimeStamp          mLastRead;
 
   nsCString mHashKey;
   nsresult mStatus;
   bool mPushCompleted; // server push FIN received
   bool mDeferCleanupOnSuccess;
 };
 
 class SpdyPush3TransactionBuffer MOZ_FINAL : public nsAHttpTransaction
--- a/netwerk/protocol/http/SpdyPush31.h
+++ b/netwerk/protocol/http/SpdyPush31.h
@@ -56,17 +56,17 @@ public:
 private:
 
   SpdyStream31 *mConsumerStream; // paired request stream that consumes from
   // real spdy one.. null until a match is made.
 
   nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
 
   SpdyPush31TransactionBuffer *mBufferedPush;
-  mozilla::TimeStamp          mLastRead;
+  TimeStamp          mLastRead;
 
   nsCString mHashKey;
   nsresult mStatus;
   bool mPushCompleted; // server push FIN received
   bool mDeferCleanupOnSuccess;
 };
 
 class SpdyPush31TransactionBuffer MOZ_FINAL : public nsAHttpTransaction
--- a/netwerk/protocol/http/TimingStruct.h
+++ b/netwerk/protocol/http/TimingStruct.h
@@ -3,19 +3,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef TimingStruct_h_
 #define TimingStruct_h_
 
 #include "mozilla/TimeStamp.h"
 
+namespace mozilla { namespace net {
+
 struct TimingStruct {
-  mozilla::TimeStamp domainLookupStart;
-  mozilla::TimeStamp domainLookupEnd;
-  mozilla::TimeStamp connectStart;
-  mozilla::TimeStamp connectEnd;
-  mozilla::TimeStamp requestStart;
-  mozilla::TimeStamp responseStart;
-  mozilla::TimeStamp responseEnd;
+  TimeStamp domainLookupStart;
+  TimeStamp domainLookupEnd;
+  TimeStamp connectStart;
+  TimeStamp connectEnd;
+  TimeStamp requestStart;
+  TimeStamp responseStart;
+  TimeStamp responseEnd;
 };
 
+}} // namespace mozilla::net
+
 #endif
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -3,24 +3,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAHttpConnection_h__
 #define nsAHttpConnection_h__
 
 #include "nsISupports.h"
 #include "nsAHttpTransaction.h"
 
-class nsHttpRequestHead;
-class nsHttpResponseHead;
-class nsHttpConnectionInfo;
-class nsHttpConnection;
 class nsISocketTransport;
 class nsIAsyncInputStream;
 class nsIAsyncOutputStream;
 
+namespace mozilla { namespace net {
+
+class nsHttpConnectionInfo;
+class nsHttpConnection;
+
 //-----------------------------------------------------------------------------
 // Abstract base class for a HTTP connection
 //-----------------------------------------------------------------------------
 
 class nsAHttpConnection : public nsISupports
 {
 public:
     //-------------------------------------------------------------------------
@@ -211,9 +212,11 @@ public:
     int64_t BytesWritten()                                  \
     {     return fwdObject ? (fwdObject)->BytesWritten() : 0; } \
     void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) \
     {                                                       \
         if (fwdObject)                                      \
             (fwdObject)->SetSecurityCallbacks(aCallbacks);  \
     }
 
+}} // namespace mozilla::net
+
 #endif // nsAHttpConnection_h__
--- a/netwerk/protocol/http/nsAHttpTransaction.h
+++ b/netwerk/protocol/http/nsAHttpTransaction.h
@@ -3,26 +3,29 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAHttpTransaction_h__
 #define nsAHttpTransaction_h__
 
 #include "nsISupports.h"
 #include "nsTArray.h"
 
+class nsIInterfaceRequestor;
+class nsIEventTarget;
+class nsITransport;
+class nsILoadGroupConnectionInfo;
+
+namespace mozilla { namespace net {
+
 class nsAHttpConnection;
 class nsAHttpSegmentReader;
 class nsAHttpSegmentWriter;
-class nsIInterfaceRequestor;
-class nsIEventTarget;
-class nsITransport;
+class nsHttpTransaction;
+class nsHttpPipeline;
 class nsHttpRequestHead;
-class nsHttpPipeline;
-class nsHttpTransaction;
-class nsILoadGroupConnectionInfo;
 
 //----------------------------------------------------------------------------
 // Abstract base class for a HTTP transaction:
 //
 // A transaction is a "sink" for the response data.  The connection pushes
 // data to the transaction by writing to it.  The transaction supports
 // WriteSegments and may refuse to accept data if its buffers are full (its
 // write function returns NS_BASE_STREAM_WOULD_BLOCK in this case).
@@ -215,9 +218,11 @@ public:
     virtual nsresult OnWriteSegment(char *segment,
                                     uint32_t count,
                                     uint32_t *countWritten) = 0;
 };
 
 #define NS_DECL_NSAHTTPSEGMENTWRITER \
     nsresult OnWriteSegment(char *, uint32_t, uint32_t *);
 
+}} // namespace mozilla::net
+
 #endif // nsAHttpTransaction_h__
--- a/netwerk/protocol/http/nsHttp.cpp
+++ b/netwerk/protocol/http/nsHttp.cpp
@@ -8,37 +8,36 @@
 #include "HttpLog.h"
 
 #include "nsHttp.h"
 #include "pldhash.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/HashFunctions.h"
 #include "nsCRT.h"
 
-using namespace mozilla;
-
 #if defined(PR_LOGGING)
 PRLogModuleInfo *gHttpLog = nullptr;
 #endif
 
+namespace mozilla {
+namespace net {
+
 // define storage for all atoms
 #define HTTP_ATOM(_name, _value) nsHttpAtom nsHttp::_name = { _value };
 #include "nsHttpAtomList.h"
 #undef HTTP_ATOM
 
 // find out how many atoms we have
 #define HTTP_ATOM(_name, _value) Unused_ ## _name,
 enum {
 #include "nsHttpAtomList.h"
     NUM_HTTP_ATOMS
 };
 #undef HTTP_ATOM
 
-using namespace mozilla;
-
 // we keep a linked list of atoms allocated on the heap for easy clean up when
 // the atom table is destroyed.  The structure and value string are allocated
 // as one contiguous block.
 
 struct HttpHeapAtom {
     struct HttpHeapAtom *next;
     char                 value[1];
 };
@@ -319,8 +318,10 @@ nsHttp::IsSafeMethod(nsHttpAtom method)
          method == nsHttp::Head ||
          method == nsHttp::Options ||
          method == nsHttp::Propfind ||
          method == nsHttp::Report ||
          method == nsHttp::Search ||
          method == nsHttp::Trace;
 }
 
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -23,18 +23,16 @@ namespace mozilla {
 class Mutex;
 
 namespace net {
     enum {
         SPDY_VERSION_2_REMOVED = 2,
         SPDY_VERSION_3 = 3,
         SPDY_VERSION_31 = 4
     };
-} // namespace mozilla::net
-} // namespace mozilla
 
 typedef uint8_t nsHttpVersion;
 
 //-----------------------------------------------------------------------------
 // http connection capabilities
 //-----------------------------------------------------------------------------
 
 #define NS_HTTP_ALLOW_KEEPALIVE      (1<<0)
@@ -100,17 +98,17 @@ struct nsHttpAtom
 struct nsHttp
 {
     static nsresult CreateAtomTable();
     static void DestroyAtomTable();
 
     // The mutex is valid any time the Atom Table is valid
     // This mutex is used in the unusual case that the network thread and
     // main thread might access the same data
-    static mozilla::Mutex *GetLock();
+    static Mutex *GetLock();
 
     // will dynamically add atoms to the table if they don't already exist
     static nsHttpAtom ResolveAtom(const char *);
     static nsHttpAtom ResolveAtom(const nsACString &s)
     {
         return ResolveAtom(PromiseFlatCString(s).get());
     }
 
@@ -184,9 +182,12 @@ PRTimeToSeconds(PRTime t_usec)
 #define NowInSeconds() PRTimeToSeconds(PR_Now())
 
 // Round q-value to 2 decimal places; return 2 most significant digits as uint.
 #define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.005) * 100.0))
 
 #define HTTP_LWS " \t"
 #define HTTP_HEADER_VALUE_SEPS HTTP_LWS ","
 
+} // namespace mozilla::net
+} // namespace mozilla
+
 #endif // nsHttp_h__
--- a/netwerk/protocol/http/nsHttpActivityDistributor.cpp
+++ b/netwerk/protocol/http/nsHttpActivityDistributor.cpp
@@ -5,17 +5,19 @@
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpActivityDistributor.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 
-using namespace mozilla;
+namespace mozilla {
+namespace net {
+
 typedef nsMainThreadPtrHolder<nsIHttpActivityObserver> ObserverHolder;
 typedef nsMainThreadPtrHandle<nsIHttpActivityObserver> ObserverHandle;
 typedef nsTArray<ObserverHandle> ObserverArray;
 
 class nsHttpActivityEvent : public nsRunnable
 {
 public:
     nsHttpActivityEvent(nsISupports *aHttpChannel,
@@ -123,8 +125,10 @@ nsHttpActivityDistributor::RemoveObserve
     MutexAutoLock lock(mLock);
 
     ObserverHandle observer(new ObserverHolder(aObserver));
     if (!mObservers.RemoveElement(observer))
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpActivityDistributor.h
+++ b/netwerk/protocol/http/nsHttpActivityDistributor.h
@@ -5,26 +5,29 @@
 #ifndef nsHttpActivityDistributor_h__
 #define nsHttpActivityDistributor_h__
 
 #include "nsIHttpActivityObserver.h"
 #include "nsTArray.h"
 #include "nsProxyRelease.h"
 #include "mozilla/Mutex.h"
 
+namespace mozilla { namespace net {
 
 class nsHttpActivityDistributor : public nsIHttpActivityDistributor
 {
 public:
     typedef nsTArray<nsMainThreadPtrHandle<nsIHttpActivityObserver> > ObserverArray;
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIHTTPACTIVITYOBSERVER
     NS_DECL_NSIHTTPACTIVITYDISTRIBUTOR
 
     nsHttpActivityDistributor();
     virtual ~nsHttpActivityDistributor();
 
 protected:
     ObserverArray mObservers;
-    mozilla::Mutex mLock;
+    Mutex mLock;
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpActivityDistributor_h__
--- a/netwerk/protocol/http/nsHttpAuthCache.cpp
+++ b/netwerk/protocol/http/nsHttpAuthCache.cpp
@@ -13,16 +13,19 @@
 #include "mozilla/Attributes.h"
 #include "nsString.h"
 #include "nsCRT.h"
 #include "mozIApplicationClearPrivateDataParams.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "nsNetUtil.h"
 
+namespace mozilla {
+namespace net {
+
 static inline void
 GetAuthKey(const char *scheme, const char *host, int32_t port, uint32_t appId, bool inBrowserElement, nsCString &key)
 {
     key.Truncate();
     key.AppendInt(appId);
     key.Append(':');
     key.AppendInt(inBrowserElement);
     key.Append(':');
@@ -51,27 +54,27 @@ StrEquivalent(const char16_t *a, const c
 //-----------------------------------------------------------------------------
 // nsHttpAuthCache <public>
 //-----------------------------------------------------------------------------
 
 nsHttpAuthCache::nsHttpAuthCache()
     : mDB(nullptr)
     , mObserver(new AppDataClearObserver(MOZ_THIS_IN_INITIALIZER_LIST()))
 {
-    nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+    nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->AddObserver(mObserver, "webapps-clear-data", false);
     }
 }
 
 nsHttpAuthCache::~nsHttpAuthCache()
 {
     if (mDB)
         ClearAll();
-    nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+    nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->RemoveObserver(mObserver, "webapps-clear-data");
         mObserver->mOwner = nullptr;
     }
 }
 
 nsresult
 nsHttpAuthCache::Init()
@@ -600,8 +603,11 @@ nsHttpAuthNode::SetAuthEntry(const char 
 void
 nsHttpAuthNode::ClearAuthEntry(const char *realm)
 {
     nsHttpAuthEntry *entry = LookupEntryByRealm(realm);
     if (entry) {
         mList.RemoveElement(entry); // double search OK
     }
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpAuthCache.h
+++ b/netwerk/protocol/http/nsHttpAuthCache.h
@@ -10,16 +10,19 @@
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "plhash.h"
 #include "nsIObserver.h"
 
 class nsCString;
 
+namespace mozilla {
+namespace net {
+
 struct nsHttpAuthPath {
     struct nsHttpAuthPath *mNext;
     char                   mPath[1];
 };
 
 //-----------------------------------------------------------------------------
 // nsHttpAuthIdentity
 //-----------------------------------------------------------------------------
@@ -247,9 +250,11 @@ private:
 
     void ClearAppData(uint32_t appId, bool browserOnly);
 
 private:
     PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
     nsRefPtr<AppDataClearObserver> mObserver;
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpAuthCache_h__
--- a/netwerk/protocol/http/nsHttpAuthManager.cpp
+++ b/netwerk/protocol/http/nsHttpAuthManager.cpp
@@ -6,16 +6,19 @@
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpHandler.h"
 #include "nsHttpAuthManager.h"
 #include "nsNetUtil.h"
 #include "nsIPrincipal.h"
 
+namespace mozilla {
+namespace net {
+
 NS_IMPL_ISUPPORTS1(nsHttpAuthManager, nsIHttpAuthManager)
 
 nsHttpAuthManager::nsHttpAuthManager()
 {
 }
 
 nsresult nsHttpAuthManager::Init()
 {
@@ -140,8 +143,11 @@ nsHttpAuthManager::ClearAll()
   nsresult rv = mAuthCache->ClearAll();
   nsresult rv2 = mPrivateAuthCache->ClearAll();
   if (NS_FAILED(rv))
     return rv;
   if (NS_FAILED(rv2))
     return rv2;
   return NS_OK;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpAuthManager.h
+++ b/netwerk/protocol/http/nsHttpAuthManager.h
@@ -3,16 +3,19 @@
  * 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 nsHttpAuthManager_h__
 #define nsHttpAuthManager_h__
 
 #include "nsIHttpAuthManager.h"
 
+namespace mozilla {
+namespace net {
+
 class nsHttpAuthCache;
 
 class nsHttpAuthManager : public nsIHttpAuthManager
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIHTTPAUTHMANAGER
 
@@ -20,9 +23,11 @@ public:
   virtual ~nsHttpAuthManager();
   nsresult Init();
 
 protected:
   nsHttpAuthCache *mAuthCache;
   nsHttpAuthCache *mPrivateAuthCache;
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpAuthManager_h__
--- a/netwerk/protocol/http/nsHttpBasicAuth.cpp
+++ b/netwerk/protocol/http/nsHttpBasicAuth.cpp
@@ -5,16 +5,19 @@
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpBasicAuth.h"
 #include "plbase64.h"
 #include "nsString.h"
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpBasicAuth <public>
 //-----------------------------------------------------------------------------
 
 nsHttpBasicAuth::nsHttpBasicAuth()
 {
 }
 
@@ -88,8 +91,11 @@ nsHttpBasicAuth::GenerateCredentials(nsI
 }
 
 NS_IMETHODIMP
 nsHttpBasicAuth::GetAuthFlags(uint32_t *flags)
 {
     *flags = REQUEST_BASED | REUSABLE_CREDENTIALS | REUSABLE_CHALLENGE;
     return NS_OK;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpBasicAuth.h
+++ b/netwerk/protocol/http/nsHttpBasicAuth.h
@@ -3,24 +3,28 @@
  * 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 nsBasicAuth_h__
 #define nsBasicAuth_h__
 
 #include "nsIHttpAuthenticator.h"
 
+namespace mozilla { namespace net {
+
 //-----------------------------------------------------------------------------
 // The nsHttpBasicAuth class produces HTTP Basic-auth responses for a username/
 // (optional)password pair, BASE64("user:pass").
 //-----------------------------------------------------------------------------
 
 class nsHttpBasicAuth : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
 	nsHttpBasicAuth();
 	virtual ~nsHttpBasicAuth();
 };
 
+}} // namespace mozilla::net
+
 #endif // !nsHttpBasicAuth_h__
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -2410,18 +2410,18 @@ nsHttpChannel::ContinueProcessFallback(n
     // Make sure to do this _after_ calling OnChannelRedirect
     mRedirectChannel->SetOriginalURI(mOriginalURI);
 
     rv = mRedirectChannel->AsyncOpen(mListener, mListenerContext);
     if (NS_FAILED(rv))
         return rv;
 
     if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
-        mozilla::Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
-                                       true);
+        Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
+                              true);
     }
 
     // close down this channel
     Cancel(NS_BINDING_REDIRECTED);
 
     notifier.RedirectSucceeded();
 
     ReleaseListeners();
@@ -3060,18 +3060,18 @@ nsHttpChannel::OnNormalCacheEntryAvailab
         }
     }
 
     if (NS_SUCCEEDED(aEntryStatus)) {
         mCacheEntry = aEntry;
         mCacheEntryIsWriteOnly = aNew;
 
         if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
-            mozilla::Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
-                                           false);
+            Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
+                                  false);
         }
     }
 
     return NS_OK;
 }
 
 nsresult
 nsHttpChannel::OnOfflineCacheEntryAvailable(nsICacheEntry *aEntry,
@@ -3093,18 +3093,18 @@ nsHttpChannel::OnOfflineCacheEntryAvaila
         // We successfully opened an offline cache session and the entry,
         // so indicate we will load from the offline cache.
         mLoadedFromApplicationCache = true;
         mCacheEntryIsReadOnly = true;
         mCacheEntry = aEntry;
         mCacheEntryIsWriteOnly = false;
 
         if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI && !mApplicationCacheForWrite) {
-            mozilla::Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
-                                           true);
+            Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
+                                  true);
         }
 
         return NS_OK;
     }
 
     if (!mApplicationCacheForWrite && !mFallbackChannel) {
         // Check for namespace match.
         nsCOMPtr<nsIApplicationCacheNamespace> namespaceEntry;
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -20,20 +20,18 @@
 #include "nsITimedChannel.h"
 #include "nsIThreadRetargetableRequest.h"
 #include "nsIThreadRetargetableStreamListener.h"
 #include "nsWeakReference.h"
 #include "TimingStruct.h"
 #include "AutoClose.h"
 #include "mozilla/Telemetry.h"
 
-class nsAHttpConnection;
 class nsIPrincipal;
 class nsDNSPrefetch;
-class nsHttpTransaction;
 class nsICacheEntryDescriptor;
 class nsICancelable;
 class nsIHttpChannelAuthProvider;
 class nsInputStreamPump;
 
 namespace mozilla { namespace net {
 
 //-----------------------------------------------------------------------------
@@ -397,20 +395,20 @@ private:
     // to the consumer.
     uint32_t                          mConcurentCacheAccess : 1;
     // whether the request is setup be byte-range
     uint32_t                          mIsPartialRequest : 1;
 
     nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack;
 
     PRTime                            mChannelCreationTime;
-    mozilla::TimeStamp                mChannelCreationTimestamp;
-    mozilla::TimeStamp                mAsyncOpenTime;
-    mozilla::TimeStamp                mCacheReadStart;
-    mozilla::TimeStamp                mCacheReadEnd;
+    TimeStamp                         mChannelCreationTimestamp;
+    TimeStamp                         mAsyncOpenTime;
+    TimeStamp                         mCacheReadStart;
+    TimeStamp                         mCacheReadEnd;
     // copied from the transaction before we null out mTransaction
     // so that the timing can still be queried from OnStopRequest
     TimingStruct                      mTransactionTimings;
     // Needed for accurate DNS timing
     nsRefPtr<nsDNSPrefetch>           mDNSPrefetch;
 
     nsresult WaitForRedirectCallback();
     void PushRedirectAsyncFunc(nsContinueRedirectionFunc func);
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -18,16 +18,19 @@
 #include "nsEscape.h"
 #include "nsAuthInformationHolder.h"
 #include "nsIStringBundle.h"
 #include "nsIPrompt.h"
 #include "netCore.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsIURI.h"
 
+namespace mozilla {
+namespace net {
+
 static void
 GetAppIdAndBrowserStatus(nsIChannel* aChan, uint32_t* aAppId, bool* aInBrowserElem)
 {
     nsCOMPtr<nsILoadContext> loadContext;
     if (aChan) {
         NS_QueryNotificationCallbacks(aChan, loadContext);
     }
     if (!loadContext) {
@@ -1331,8 +1334,11 @@ nsHttpChannelAuthProvider::GetCurrentPat
         rv = url->GetDirectory(path);
     else
         rv = mURI->GetPath(path);
     return rv;
 }
 
 NS_IMPL_ISUPPORTS3(nsHttpChannelAuthProvider, nsICancelable,
                    nsIHttpChannelAuthProvider, nsIAuthPromptCallback)
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.h
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.h
@@ -12,18 +12,21 @@
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsHttpAuthCache.h"
 #include "nsProxyInfo.h"
 #include "nsCRT.h"
 
 class nsIHttpAuthenticableChannel;
 class nsIHttpAuthenticator;
+class nsIURI;
+
+namespace mozilla { namespace net {
+
 class nsHttpHandler;
-class nsIURI;
 
 class nsHttpChannelAuthProvider : public nsIHttpChannelAuthProvider
                                 , public nsIAuthPromptCallback
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSICANCELABLE
     NS_DECL_NSIHTTPCHANNELAUTHPROVIDER
@@ -142,9 +145,11 @@ private:
     uint32_t                          mProxyAuth                : 1;
     uint32_t                          mTriedProxyAuth           : 1;
     uint32_t                          mTriedHostAuth            : 1;
     uint32_t                          mSuppressDefensiveAuth    : 1;
 
     nsRefPtr<nsHttpHandler>           mHttpHandler;  // keep gHttpHandler alive
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpChannelAuthProvider_h__
--- a/netwerk/protocol/http/nsHttpChunkedDecoder.cpp
+++ b/netwerk/protocol/http/nsHttpChunkedDecoder.cpp
@@ -4,16 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpChunkedDecoder.h"
 #include <algorithm>
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpChunkedDecoder <public>
 //-----------------------------------------------------------------------------
 
 nsresult
 nsHttpChunkedDecoder::HandleChunkedContent(char *buf,
                                            uint32_t count,
                                            uint32_t *contentRead,
@@ -141,8 +144,11 @@ nsHttpChunkedDecoder::ParseChunkRemainin
         // ignore a trailing CR
         if (buf[count-1] == '\r')
             count--;
         mLineBuf.Append(buf, count);
     }
 
     return NS_OK;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpChunkedDecoder.h
+++ b/netwerk/protocol/http/nsHttpChunkedDecoder.h
@@ -5,16 +5,18 @@
 
 #ifndef nsHttpChunkedDecoder_h__
 #define nsHttpChunkedDecoder_h__
 
 #include "nsError.h"
 #include "nsString.h"
 #include "nsHttpHeaderArray.h"
 
+namespace mozilla { namespace net {
+
 class nsHttpChunkedDecoder
 {
 public:
     nsHttpChunkedDecoder() : mTrailers(nullptr)
                            , mChunkRemaining(0)
                            , mReachedEOF(false)
                            , mWaitEOF(false) {}
    ~nsHttpChunkedDecoder() { delete mTrailers; }
@@ -43,9 +45,11 @@ private:
 private:
     nsHttpHeaderArray *mTrailers;
     uint32_t           mChunkRemaining;
     nsCString          mLineBuf; // may hold a partial line
     bool               mReachedEOF;
     bool               mWaitEOF;
 };
 
+}} // namespace mozilla::net
+
 #endif
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -23,18 +23,18 @@
 #include "nsISupportsPriority.h"
 #include "nsHttpPipeline.h"
 
 #ifdef DEBUG
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 #endif
 
-using namespace mozilla;
-using namespace mozilla::net;
+namespace mozilla {
+namespace net {
 
 //-----------------------------------------------------------------------------
 // nsHttpConnection <public>
 //-----------------------------------------------------------------------------
 
 nsHttpConnection::nsHttpConnection()
     : mTransaction(nullptr)
     , mHttpHandler(gHttpHandler)
@@ -1665,8 +1665,11 @@ nsHttpConnection::GetInterface(const nsI
     {
         MutexAutoLock lock(mCallbacksLock);
         callbacks = mCallbacks;
     }
     if (callbacks)
         return callbacks->GetInterface(iid, result);
     return NS_ERROR_NO_INTERFACE;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -12,26 +12,23 @@
 #include "nsAutoPtr.h"
 #include "nsProxyRelease.h"
 #include "prinrval.h"
 
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
 #include "nsIInterfaceRequestor.h"
 
-class nsHttpRequestHead;
-class nsHttpResponseHead;
-class nsHttpHandler;
 class nsISocketTransport;
 
 namespace mozilla {
 namespace net {
+
+class nsHttpHandler;
 class ASpdySession;
-}
-}
 
 //-----------------------------------------------------------------------------
 // nsHttpConnection - represents a connection to a HTTP server (or proxy)
 //
 // NOTE: this objects lives on the socket thread only.  it should not be
 // accessed from any other thread.
 //-----------------------------------------------------------------------------
 
@@ -208,17 +205,17 @@ private:
     nsCOMPtr<nsIInputStream>        mRequestStream;
 
     // mTransaction only points to the HTTP Transaction callbacks if the
     // transaction is open, otherwise it is null.
     nsRefPtr<nsAHttpTransaction>    mTransaction;
 
     nsRefPtr<nsHttpHandler>         mHttpHandler; // keep gHttpHandler alive
 
-    mozilla::Mutex                  mCallbacksLock;
+    Mutex                           mCallbacksLock;
     nsMainThreadPtrHandle<nsIInterfaceRequestor> mCallbacks;
 
     nsRefPtr<nsHttpConnectionInfo> mConnInfo;
 
     PRIntervalTime                  mLastReadTime;
     PRIntervalTime                  mLastWriteTime;
     PRIntervalTime                  mMaxHangTime;    // max download time before dropping keep-alive status
     PRIntervalTime                  mIdleTimeout;    // value of keep-alive: timeout=
@@ -261,25 +258,27 @@ private:
 
     // SPDY related
     bool                            mNPNComplete;
     bool                            mSetupSSLCalled;
 
     // version level in use, 0 if unused
     uint8_t                         mUsingSpdyVersion;
 
-    nsRefPtr<mozilla::net::ASpdySession> mSpdySession;
+    nsRefPtr<ASpdySession>          mSpdySession;
     int32_t                         mPriority;
     bool                            mReportedSpdy;
 
     // mUsingSpdyVersion is cleared when mSpdySession is freed, this is permanent
     bool                            mEverUsedSpdy;
 
     // mLastHttpResponseVersion stores the last response's http version seen.
     uint8_t                         mLastHttpResponseVersion;
 
     // The capabailities associated with the most recent transaction
     uint32_t                        mTransactionCaps;
 
     bool                            mResponseTimeoutEnabled;
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpConnection_h__
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -6,17 +6,18 @@
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpConnectionInfo.h"
 #include "mozilla/net/DNS.h"
 #include "prnetdb.h"
 
-using namespace mozilla::net;
+namespace mozilla {
+namespace net {
 
 nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &host, int32_t port,
                                            nsProxyInfo* proxyInfo,
                                            bool usingSSL)
     : mProxyInfo(proxyInfo)
     , mUsingSSL(usingSSL)
     , mUsingConnect(false)
 {
@@ -127,8 +128,11 @@ nsHttpConnectionInfo::HostIsLocalIPLiter
         }
     } else if (PR_StringToNetAddr(Host(), &prAddr) != PR_SUCCESS) {
         return false;
     }
     NetAddr netAddr;
     PRNetAddrToNetAddr(&prAddr, &netAddr);
     return IsIPAddrLocal(&netAddr);
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.h
@@ -13,16 +13,18 @@
 #include "nsStringFwd.h"
 
 extern PRLogModuleInfo *gHttpLog;
 
 //-----------------------------------------------------------------------------
 // nsHttpConnectionInfo - holds the properties of a connection
 //-----------------------------------------------------------------------------
 
+namespace mozilla { namespace net {
+
 class nsHttpConnectionInfo
 {
 public:
     nsHttpConnectionInfo(const nsACString &host, int32_t port,
                          nsProxyInfo* proxyInfo,
                          bool usingSSL=false);
 
     virtual ~nsHttpConnectionInfo()
@@ -87,9 +89,11 @@ private:
     bool                   mUsingHttpProxy;
     bool                   mUsingSSL;
     bool                   mUsingConnect;  // if will use CONNECT with http proxy
 
 // for nsRefPtr
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo)
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpConnectionInfo_h__
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -19,25 +19,24 @@
 #include "nsISSLSocketControl.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/net/DashboardTypes.h"
 #include "NullHttpTransaction.h"
 #include "nsITransport.h"
 #include "nsISocketTransportService.h"
 #include <algorithm>
 
-using namespace mozilla;
-using namespace mozilla::net;
-
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 
-
 NS_IMPL_ISUPPORTS1(nsHttpConnectionMgr, nsIObserver)
 
 static void
 InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransaction *trans)
 {
     // insert into queue with smallest valued number first.  search in reverse
     // order under the assumption that many of the existing transactions will
     // have the same priority (usually 0).
@@ -335,17 +334,17 @@ public: // intentional!
     bool mOverridesOK;
     uint32_t mParallelSpeculativeConnectLimit;
     bool mIgnoreIdle;
     bool mIgnorePossibleSpdyConnections;
 
     // As above, added manually so we can use nsRefPtr without inheriting from
     // nsISupports
 protected:
-    ::mozilla::ThreadSafeAutoRefCnt mRefCnt;
+    ThreadSafeAutoRefCnt mRefCnt;
     NS_DECL_OWNINGTHREAD
 };
 
 NS_IMPL_ADDREF(SpeculativeConnectArgs)
 NS_IMPL_RELEASE(SpeculativeConnectArgs)
 
 nsresult
 nsHttpConnectionMgr::SpeculativeConnect(nsHttpConnectionInfo *ci,
@@ -3461,17 +3460,17 @@ nsHttpConnectionMgr::ReadConnectionEntry
     }
     data.spdy = ent->mUsingSpdy;
     data.ssl = ent->mConnInfo->UsingSSL();
     args->AppendElement(data);
     return PL_DHASH_NEXT;
 }
 
 bool
-nsHttpConnectionMgr::GetConnectionData(nsTArray<mozilla::net::HttpRetParams> *aArg)
+nsHttpConnectionMgr::GetConnectionData(nsTArray<HttpRetParams> *aArg)
 {
     mCT.Enumerate(ReadConnectionEntry, aArg);
     return true;
 }
 
 void
 nsHttpConnectionMgr::ResetIPFamilyPreference(nsHttpConnectionInfo *ci)
 {
@@ -3523,8 +3522,11 @@ nsConnectionEntry::RecordIPFamilyPrefere
 
 void
 nsHttpConnectionMgr::
 nsConnectionEntry::ResetIPFamilyPreference()
 {
   mPreferIPv4 = false;
   mPreferIPv6 = false;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -15,26 +15,22 @@
 #include "nsAutoPtr.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Attributes.h"
 
 #include "nsIObserver.h"
 #include "nsITimer.h"
 
-class nsHttpPipeline;
-
 class nsIHttpUpgradeListener;
 
 namespace mozilla {
 namespace net {
 class EventTokenBucket;
 struct HttpRetParams;
-}
-}
 
 //-----------------------------------------------------------------------------
 
 class nsHttpConnectionMgr : public nsIObserver
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIOBSERVER
@@ -125,17 +121,17 @@ public:
                              nsIHttpUpgradeListener *aUpgradeListener);
 
     // called to update a parameter after the connection manager has already
     // been initialized.
     nsresult UpdateParam(nsParamName name, uint16_t value);
 
     // called from main thread to post a new request token bucket
     // to the socket thread
-    nsresult UpdateRequestTokenBucket(mozilla::net::EventTokenBucket *aBucket);
+    nsresult UpdateRequestTokenBucket(EventTokenBucket *aBucket);
 
     // Pipielining Interfaces and Datatypes
 
     const static uint32_t kPipelineInfoTypeMask = 0xffff0000;
     const static uint32_t kPipelineInfoIDMask   = ~kPipelineInfoTypeMask;
 
     const static uint32_t kPipelineInfoTypeRed     = 0x00010000;
     const static uint32_t kPipelineInfoTypeBad     = 0x00020000;
@@ -226,17 +222,17 @@ public:
 
     // A spdy server can supply cwnd information for the session that is used
     // in future sessions to speed up the opening portions of the connection.
     void ReportSpdyCWNDSetting(nsHttpConnectionInfo *host, uint32_t cwndValue);
     uint32_t GetSpdyCWNDSetting(nsHttpConnectionInfo *host);
 
     bool     SupportsPipelining(nsHttpConnectionInfo *);
 
-    bool GetConnectionData(nsTArray<mozilla::net::HttpRetParams> *);
+    bool GetConnectionData(nsTArray<HttpRetParams> *);
 
     void ResetIPFamilyPreference(nsHttpConnectionInfo *);
 
 private:
     virtual ~nsHttpConnectionMgr();
 
     enum PipeliningState {
         // Host has proven itself pipeline capable through past experience and
@@ -323,33 +319,33 @@ private:
         int16_t                   mPipeliningPenalty;
 
         // some penalty points only apply to particular classifications of
         // transactions - this allows a server that perhaps has head of line
         // blocking problems on CGI queries to still serve JS pipelined.
         int16_t                   mPipeliningClassPenalty[nsAHttpTransaction::CLASS_MAX];
 
         // for calculating penalty repair credits
-        mozilla::TimeStamp        mLastCreditTime;
+        TimeStamp        mLastCreditTime;
 
         // Spdy sometimes resolves the address in the socket manager in order
         // to re-coalesce sharded HTTP hosts. The dotted decimal address is
         // combined with the Anonymous flag from the connection information
         // to build the hash key for hosts in the same ip pool.
         //
         // When a set of hosts are coalesced together one of them is marked
         // mSpdyPreferred. The mapping is maintained in the connection mananger
         // mSpdyPreferred hash.
         //
         nsCString mCoalescingKey;
 
         // The value of a recevied SPDY settings type 5 previously received
         // for this connection entry and the time it was set.
         uint32_t            mSpdyCWND;
-        mozilla::TimeStamp  mSpdyCWNDTimeStamp;
+        TimeStamp  mSpdyCWNDTimeStamp;
 
         // To have the UsingSpdy flag means some host with the same connection
         // entry has done NPN=spdy/* at some point. It does not mean every
         // connection is currently using spdy.
         bool mUsingSpdy;
 
         // mTestedSpdy is set after NPN negotiation has occurred and we know
         // with confidence whether a host speaks spdy or not (which is reflected
@@ -419,17 +415,17 @@ private:
                               nsIAsyncInputStream **,
                               nsIAsyncOutputStream **,
                               bool isBackup);
         nsresult SetupPrimaryStreams();
         nsresult SetupBackupStreams();
         void     SetupBackupTimer();
         void     CancelBackupTimer();
         void     Abandon();
-        double   Duration(mozilla::TimeStamp epoch);
+        double   Duration(TimeStamp epoch);
         nsISocketTransport *SocketTransport() { return mSocketTransport; }
         nsISocketTransport *BackupTransport() { return mBackupTransport; }
 
         nsAHttpTransaction *Transaction() { return mTransaction; }
 
         bool IsSpeculative() { return mSpeculative; }
         void SetSpeculative(bool val) { mSpeculative = val; }
 
@@ -448,34 +444,34 @@ private:
         // SpeculativeConnect(). It is cleared when a transaction would normally
         // start a new connection from scratch but instead finds this one in
         // the half open list and claims it for its own use. (which due to
         // the vagaries of scheduling from the pending queue might not actually
         // match up - but it prevents a speculative connection from opening
         // more connections that are needed.)
         bool                           mSpeculative;
 
-        mozilla::TimeStamp             mPrimarySynStarted;
-        mozilla::TimeStamp             mBackupSynStarted;
+        TimeStamp             mPrimarySynStarted;
+        TimeStamp             mBackupSynStarted;
 
         // for syn retry
         nsCOMPtr<nsITimer>             mSynTimer;
         nsCOMPtr<nsISocketTransport>   mBackupTransport;
         nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
         nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
 
         bool                           mHasConnected;
     };
     friend class nsHalfOpenSocket;
 
     //-------------------------------------------------------------------------
     // NOTE: these members may be accessed from any thread (use mReentrantMonitor)
     //-------------------------------------------------------------------------
 
-    mozilla::ReentrantMonitor    mReentrantMonitor;
+    ReentrantMonitor    mReentrantMonitor;
     nsCOMPtr<nsIEventTarget>     mSocketThreadTarget;
 
     // connection limits
     uint16_t mMaxConns;
     uint16_t mMaxPersistConnsPerHost;
     uint16_t mMaxPersistConnsPerProxy;
     uint16_t mMaxRequestDelay; // in seconds
     uint16_t mMaxPipelinedRequests;
@@ -657,9 +653,11 @@ private:
     // For diagnostics
     void OnMsgPrintDiagnostics(int32_t, void *);
     static PLDHashOperator PrintDiagnosticsCB(const nsACString &key,
                                               nsAutoPtr<nsConnectionEntry> &ent,
                                               void *closure);
     nsCString mLogData;
 };
 
+}} // namespace mozilla::net
+
 #endif // !nsHttpConnectionMgr_h__
--- a/netwerk/protocol/http/nsHttpDigestAuth.cpp
+++ b/netwerk/protocol/http/nsHttpDigestAuth.cpp
@@ -14,16 +14,19 @@
 #include "nsIURI.h"
 #include "nsString.h"
 #include "nsEscape.h"
 #include "nsNetCID.h"
 #include "prprf.h"
 #include "nsCRT.h"
 #include "nsICryptoHash.h"
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpDigestAuth <public>
 //-----------------------------------------------------------------------------
 
 nsHttpDigestAuth::nsHttpDigestAuth()
 {}
 
 nsHttpDigestAuth::~nsHttpDigestAuth()
@@ -687,9 +690,12 @@ nsHttpDigestAuth::AppendQuotedString(con
   }
   // FIXME: bug 41489
   // We should RFC2047-encode non-Latin-1 values according to spec
   quoted.Append('"');
   aHeaderLine.Append(quoted);
   return NS_OK;
 }
 
+} // namespace mozilla::net
+} // namespace mozilla
+
 // vim: ts=2 sw=2
--- a/netwerk/protocol/http/nsHttpDigestAuth.h
+++ b/netwerk/protocol/http/nsHttpDigestAuth.h
@@ -9,16 +9,18 @@
 
 #include "nsIHttpAuthenticator.h"
 #include "nsStringFwd.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
 
 class nsICryptoHash;
 
+namespace mozilla { namespace net {
+
 #define ALGO_SPECIFIED 0x01
 #define ALGO_MD5 0x02
 #define ALGO_MD5_SESS 0x04
 #define QOP_AUTH 0x01
 #define QOP_AUTH_INT 0x02
 
 #define DIGEST_LENGTH 16
 #define EXPANDED_DIGEST_LENGTH 32
@@ -81,9 +83,11 @@ class nsHttpDigestAuth MOZ_FINAL : publi
     nsresult AppendQuotedString(const nsACString & value,
                                 nsACString & aHeaderLine);
 
   protected:
     nsCOMPtr<nsICryptoHash>        mVerifier;
     char                           mHashBuf[DIGEST_LENGTH];
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpDigestAuth_h__
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -68,18 +68,16 @@
 #include <os2.h>
 #endif
 
 #if defined(MOZ_WIDGET_GONK)
 #include "nsINetworkManager.h"
 #endif
 
 //-----------------------------------------------------------------------------
-using namespace mozilla;
-using namespace mozilla::net;
 #include "mozilla/net/HttpChannelChild.h"
 
 
 #ifdef DEBUG
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 #endif
 
@@ -104,16 +102,19 @@ extern PRThread *gSocketThread;
 #define UA_PREF(_pref) UA_PREF_PREFIX _pref
 #define HTTP_PREF(_pref) HTTP_PREF_PREFIX _pref
 #define BROWSER_PREF(_pref) BROWSER_PREF_PREFIX _pref
 
 #define NS_HTTP_PROTOCOL_FLAGS (URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE)
 
 //-----------------------------------------------------------------------------
 
+namespace mozilla {
+namespace net {
+
 static nsresult
 NewURI(const nsACString &aSpec,
        const char *aCharset,
        nsIURI *aBaseURI,
        int32_t aDefaultPort,
        nsIURI **aURI)
 {
     nsStandardURL *url = new nsStandardURL();
@@ -368,18 +369,18 @@ nsHttpHandler::Init()
 }
 
 void
 nsHttpHandler::MakeNewRequestTokenBucket()
 {
     if (!mConnMgr)
         return;
 
-    nsRefPtr<mozilla::net::EventTokenBucket> tokenBucket =
-        new mozilla::net::EventTokenBucket(RequestTokenBucketHz(),
+    nsRefPtr<EventTokenBucket> tokenBucket =
+        new EventTokenBucket(RequestTokenBucketHz(),
                                            RequestTokenBucketBurst());
     mConnMgr->UpdateRequestTokenBucket(tokenBucket);
 }
 
 nsresult
 nsHttpHandler::InitConnectionMgr()
 {
     nsresult rv;
@@ -1398,18 +1399,18 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
         rv = prefs->GetIntPref(HTTP_PREF("pacing.requests.burst"), &val);
         if (NS_SUCCEEDED(rv)) {
             mRequestTokenBucketBurst = val ? val : 1;
             requestTokenBucketUpdated = true;
         }
     }
     if (requestTokenBucketUpdated) {
         mRequestTokenBucket =
-            new mozilla::net::EventTokenBucket(RequestTokenBucketHz(),
-                                               RequestTokenBucketBurst());
+            new EventTokenBucket(RequestTokenBucketHz(),
+                                 RequestTokenBucketBurst());
     }
 
 #undef PREF_CHANGED
 #undef MULTI_PREF_CHANGED
 }
 
 
 /**
@@ -1577,17 +1578,17 @@ nsHttpHandler::GetProtocolFlags(uint32_t
 }
 
 NS_IMETHODIMP
 nsHttpHandler::NewURI(const nsACString &aSpec,
                       const char *aCharset,
                       nsIURI *aBaseURI,
                       nsIURI **aURI)
 {
-    return ::NewURI(aSpec, aCharset, aBaseURI, NS_HTTP_DEFAULT_PORT, aURI);
+    return mozilla::net::NewURI(aSpec, aCharset, aBaseURI, NS_HTTP_DEFAULT_PORT, aURI);
 }
 
 NS_IMETHODIMP
 nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result)
 {
     LOG(("nsHttpHandler::NewChannel\n"));
 
     NS_ENSURE_ARG_POINTER(uri);
@@ -2163,17 +2164,17 @@ nsHttpsHandler::GetProtocolFlags(uint32_
 }
 
 NS_IMETHODIMP
 nsHttpsHandler::NewURI(const nsACString &aSpec,
                        const char *aOriginCharset,
                        nsIURI *aBaseURI,
                        nsIURI **_retval)
 {
-    return ::NewURI(aSpec, aOriginCharset, aBaseURI, NS_HTTPS_DEFAULT_PORT, _retval);
+    return mozilla::net::NewURI(aSpec, aOriginCharset, aBaseURI, NS_HTTPS_DEFAULT_PORT, _retval);
 }
 
 NS_IMETHODIMP
 nsHttpsHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval)
 {
     MOZ_ASSERT(gHttpHandler);
     if (!gHttpHandler)
       return NS_ERROR_UNEXPECTED;
@@ -2182,8 +2183,11 @@ nsHttpsHandler::NewChannel(nsIURI *aURI,
 
 NS_IMETHODIMP
 nsHttpsHandler::AllowPort(int32_t aPort, const char *aScheme, bool *_retval)
 {
     // don't override anything.
     *_retval = false;
     return NS_OK;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -16,37 +16,34 @@
 #include "nsWeakReference.h"
 
 #include "nsIHttpDataUsage.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsIObserver.h"
 #include "nsISpeculativeConnect.h"
 #include "nsICache.h"
 
-class nsHttpConnection;
-class nsHttpConnectionInfo;
-class nsHttpHeaderArray;
-class nsHttpTransaction;
 class nsIHttpChannel;
 class nsIPrefBranch;
 class nsICancelable;
 class nsICookieService;
 class nsIIOService;
 class nsIObserverService;
 class nsISiteSecurityService;
 class nsIStreamConverterService;
 class nsITimer;
 
 namespace mozilla {
 namespace net {
 class ATokenBucketEvent;
 class EventTokenBucket;
 class Tickler;
-}
-}
+class nsHttpConnection;
+class nsHttpConnectionInfo;
+class nsHttpTransaction;
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler - protocol handler for HTTP and HTTPS
 //-----------------------------------------------------------------------------
 
 class nsHttpHandler : public nsIHttpProtocolHandler
                     , public nsIObserver
                     , public nsSupportsWeakReference
@@ -264,33 +261,33 @@ public:
 
     PRIntervalTime GetPipelineRescheduleTimeout()
     {
         return mPipelineRescheduleTimeout;
     }
 
     PRIntervalTime GetPipelineTimeout()   { return mPipelineReadTimeout; }
 
-    mozilla::net::SpdyInformation *SpdyInfo() { return &mSpdyInfo; }
+    SpdyInformation *SpdyInfo() { return &mSpdyInfo; }
 
     // returns true in between Init and Shutdown states
     bool Active() { return mHandlerActive; }
 
     static void GetCacheSessionNameForStoragePolicy(
             nsCacheStoragePolicy storagePolicy,
             bool isPrivate,
             uint32_t appId,
             bool inBrowser,
             nsACString& sessionName);
 
     // When the disk cache is responding slowly its use is suppressed
     // for 1 minute for most requests. Callable from main thread only.
-    mozilla::TimeStamp GetCacheSkippedUntil() { return mCacheSkippedUntil; }
-    void SetCacheSkippedUntil(mozilla::TimeStamp arg) { mCacheSkippedUntil = arg; }
-    void ClearCacheSkippedUntil() { mCacheSkippedUntil = mozilla::TimeStamp(); }
+    TimeStamp GetCacheSkippedUntil() { return mCacheSkippedUntil; }
+    void SetCacheSkippedUntil(TimeStamp arg) { mCacheSkippedUntil = arg; }
+    void ClearCacheSkippedUntil() { mCacheSkippedUntil = TimeStamp(); }
 
 private:
 
     //
     // Useragent/prefs helper methods
     //
     void     BuildUserAgent();
     void     InitUserAgentComponents();
@@ -416,17 +413,17 @@ private:
 
     // The value of network.allow-experiments
     bool           mAllowExperiments;
 
     // true in between init and shutdown states
     bool           mHandlerActive;
 
     // Try to use SPDY features instead of HTTP/1.1 over SSL
-    mozilla::net::SpdyInformation mSpdyInfo;
+    SpdyInformation mSpdyInfo;
     bool           mEnableSpdy;
     bool           mSpdyV3;
     bool           mSpdyV31;
     bool           mCoalesceSpdy;
     bool           mSpdyPersistentSettings;
     bool           mAllowSpdyPush;
     uint32_t       mSpdySendingChunkSize;
     uint32_t       mSpdySendBufferSize;
@@ -454,50 +451,50 @@ private:
     uint32_t       mRequestTokenBucketBurst; // EventTokenBucket Burst
 
     // Whether or not to block requests for non head js/css items (e.g. media)
     // while those elements load.
     bool           mCriticalRequestPrioritization;
 
     // When the disk cache is responding slowly its use is suppressed
     // for 1 minute for most requests.
-    mozilla::TimeStamp                mCacheSkippedUntil;
+    TimeStamp      mCacheSkippedUntil;
 
 private:
     // For Rate Pacing Certain Network Events. Only assign this pointer on
     // socket thread.
     void MakeNewRequestTokenBucket();
-    nsRefPtr<mozilla::net::EventTokenBucket> mRequestTokenBucket;
+    nsRefPtr<EventTokenBucket> mRequestTokenBucket;
 
 public:
     // Socket thread only
-    nsresult SubmitPacedRequest(mozilla::net::ATokenBucketEvent *event,
+    nsresult SubmitPacedRequest(ATokenBucketEvent *event,
                                 nsICancelable **cancel)
     {
         if (!mRequestTokenBucket)
             return NS_ERROR_UNEXPECTED;
         return mRequestTokenBucket->SubmitEvent(event, cancel);
     }
 
     // Socket thread only
-    void SetRequestTokenBucket(mozilla::net::EventTokenBucket *aTokenBucket)
+    void SetRequestTokenBucket(EventTokenBucket *aTokenBucket)
     {
         mRequestTokenBucket = aTokenBucket;
     }
 
 private:
     // for nsIHttpDataUsage
     uint64_t mEthernetBytesRead;
     uint64_t mEthernetBytesWritten;
     uint64_t mCellBytesRead;
     uint64_t mCellBytesWritten;
     bool     mNetworkTypeKnown;
     bool     mNetworkTypeWasEthernet;
 
-    nsRefPtr<mozilla::net::Tickler> mWifiTickler;
+    nsRefPtr<Tickler> mWifiTickler;
     nsresult GetNetworkEthernetInfo(nsIInterfaceRequestor *cb,
                                     bool *ethernet);
     nsresult GetNetworkEthernetInfoInner(nsIInterfaceRequestor *cb,
                                          bool *ethernet);
     nsresult GetNetworkInfo(nsIInterfaceRequestor *cb,
                             bool *ethernet, uint32_t *gw);
     nsresult GetNetworkInfoInner(nsIInterfaceRequestor *cb,
                                  bool *ethernet, uint32_t *gw);
@@ -532,9 +529,11 @@ public:
     NS_FORWARD_NSISPECULATIVECONNECT     (gHttpHandler->)
 
     nsHttpsHandler() { }
     virtual ~nsHttpsHandler() { }
 
     nsresult Init();
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpHandler_h__
--- a/netwerk/protocol/http/nsHttpHeaderArray.cpp
+++ b/netwerk/protocol/http/nsHttpHeaderArray.cpp
@@ -6,16 +6,19 @@
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpHeaderArray.h"
 #include "nsURLHelper.h"
 #include "nsIHttpHeaderVisitor.h"
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpHeaderArray <public>
 //-----------------------------------------------------------------------------
 nsresult
 nsHttpHeaderArray::SetHeader(nsHttpAtom header,
                              const nsACString &value,
                              bool merge)
 {
@@ -207,8 +210,11 @@ nsHttpHeaderArray::PeekHeaderAt(uint32_t
     return entry.value.get();
 }
 
 void
 nsHttpHeaderArray::Clear()
 {
     mHeaders.Clear();
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpHeaderArray.h
+++ b/netwerk/protocol/http/nsHttpHeaderArray.h
@@ -8,16 +8,18 @@
 #define nsHttpHeaderArray_h__
 
 #include "nsHttp.h"
 #include "nsTArray.h"
 #include "nsString.h"
 
 class nsIHttpHeaderVisitor;
 
+namespace mozilla { namespace net {
+
 class nsHttpHeaderArray
 {
 public:
     const char *PeekHeader(nsHttpAtom header) const;
 
     // Used by internal setters: to set header from network use SetHeaderFromNet
     nsresult SetHeader(nsHttpAtom header, const nsACString &value,
                        bool merge = false);
@@ -173,9 +175,11 @@ nsHttpHeaderArray::IsSuspectDuplicateHea
                      header == nsHttp::Location;
 
     MOZ_ASSERT(!retval || IsSingletonHeader(header),
                "Only non-mergeable headers should be in this list\n");
 
     return retval;
 }
 
+}} // namespace mozilla::net
+
 #endif
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -20,16 +20,19 @@
 #include "nsIURI.h"
 #ifdef XP_WIN
 #include "nsIX509Cert.h"
 #include "nsISSLStatus.h"
 #include "nsISSLStatusProvider.h"
 #endif
 #include "mozilla/Attributes.h"
 
+namespace mozilla {
+namespace net {
+
 static const char kAllowProxies[] = "network.automatic-ntlm-auth.allow-proxies";
 static const char kAllowNonFqdn[] = "network.automatic-ntlm-auth.allow-non-fqdn";
 static const char kTrustedURIs[]  = "network.automatic-ntlm-auth.trusted-uris";
 static const char kForceGeneric[] = "network.auth.force-generic-ntlm";
 
 // XXX MatchesBaseURI and TestPref are duplicated in nsHttpNegotiateAuth.cpp,
 // but since that file lives in a separate library we cannot directly share it.
 // bug 236865 addresses this problem.
@@ -475,8 +478,11 @@ nsHttpNTLMAuth::GenerateCredentials(nsIH
 }
 
 NS_IMETHODIMP
 nsHttpNTLMAuth::GetAuthFlags(uint32_t *flags)
 {
     *flags = CONNECTION_BASED | IDENTITY_INCLUDES_DOMAIN | IDENTITY_ENCRYPTED;
     return NS_OK;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpNTLMAuth.h
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.h
@@ -2,24 +2,28 @@
  * 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 nsHttpNTLMAuth_h__
 #define nsHttpNTLMAuth_h__
 
 #include "nsIHttpAuthenticator.h"
 
+namespace mozilla { namespace net {
+
 class nsHttpNTLMAuth : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpNTLMAuth() {}
     virtual ~nsHttpNTLMAuth() {}
 
 private:
     // This flag indicates whether we are using the native NTLM implementation
     // or the internal one.
     bool  mUseNative;
 };
 
+}} // namespace mozilla::net
+
 #endif // !nsHttpNTLMAuth_h__
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -15,16 +15,19 @@
 #include <algorithm>
 
 #ifdef DEBUG
 #include "prthread.h"
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 #endif
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpPushBackWriter
 //-----------------------------------------------------------------------------
 
 class nsHttpPushBackWriter : public nsAHttpSegmentWriter
 {
 public:
     nsHttpPushBackWriter(const char *buf, uint32_t bufLen)
@@ -896,8 +899,11 @@ nsHttpPipeline::FillSendBuf()
             // except the read handler code can be synchronously dispatched on
             // the stack.
         }
         else
             mRequestIsPartial = true;
     }
     return NS_OK;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpPipeline.h
+++ b/netwerk/protocol/http/nsHttpPipeline.h
@@ -9,16 +9,18 @@
 #include "nsAHttpConnection.h"
 #include "nsAHttpTransaction.h"
 #include "nsTArray.h"
 #include "nsCOMPtr.h"
 
 class nsIInputStream;
 class nsIOutputStream;
 
+namespace mozilla { namespace net {
+
 class nsHttpPipeline : public nsAHttpConnection
                      , public nsAHttpTransaction
                      , public nsAHttpSegmentReader
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSAHTTPCONNECTION(mConnection)
     NS_DECL_NSAHTTPTRANSACTION
@@ -91,9 +93,11 @@ private:
     uint32_t  mHttp1xTransactionCount;
 
     // For support of OnTransportStatus()
     uint64_t  mReceivingFromProgress;
     uint64_t  mSendingToProgress;
     bool      mSuppressSendEvents;
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpPipeline_h__
--- a/netwerk/protocol/http/nsHttpRequestHead.cpp
+++ b/netwerk/protocol/http/nsHttpRequestHead.cpp
@@ -7,16 +7,19 @@
 #include "HttpLog.h"
 
 #include "nsHttpRequestHead.h"
 
 //-----------------------------------------------------------------------------
 // nsHttpRequestHead
 //-----------------------------------------------------------------------------
 
+namespace mozilla {
+namespace net {
+
 void
 nsHttpRequestHead::Flatten(nsACString &buf, bool pruneProxyHeaders)
 {
     // note: the first append is intentional.
 
     buf.Append(mMethod.get());
     buf.Append(' ');
     buf.Append(mRequestURI);
@@ -32,8 +35,11 @@ nsHttpRequestHead::Flatten(nsACString &b
     default:
         buf.AppendLiteral("1.0");
     }
 
     buf.AppendLiteral("\r\n");
 
     mHeaders.Flatten(buf, pruneProxyHeaders);
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpRequestHead.h
+++ b/netwerk/protocol/http/nsHttpRequestHead.h
@@ -5,16 +5,18 @@
 
 #ifndef nsHttpRequestHead_h__
 #define nsHttpRequestHead_h__
 
 #include "nsHttp.h"
 #include "nsHttpHeaderArray.h"
 #include "nsString.h"
 
+namespace mozilla { namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpRequestHead represents the request line and headers from an HTTP
 // request.
 //-----------------------------------------------------------------------------
 
 class nsHttpRequestHead
 {
 public:
@@ -64,9 +66,11 @@ public:
 private:
     // All members must be copy-constructable and assignable
     nsHttpHeaderArray mHeaders;
     nsHttpAtom        mMethod;
     nsHttpVersion     mVersion;
     nsCString         mRequestURI;
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpRequestHead_h__
--- a/netwerk/protocol/http/nsHttpResponseHead.cpp
+++ b/netwerk/protocol/http/nsHttpResponseHead.cpp
@@ -8,16 +8,19 @@
 #include "HttpLog.h"
 
 #include "nsHttpResponseHead.h"
 #include "nsPrintfCString.h"
 #include "prtime.h"
 #include "nsURLHelper.h"
 #include <algorithm>
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpResponseHead <public>
 //-----------------------------------------------------------------------------
 
 nsresult
 nsHttpResponseHead::SetHeader(nsHttpAtom hdr,
                               const nsACString &val,
                               bool merge)
@@ -803,8 +806,11 @@ nsHttpResponseHead::ParsePragma(const ch
     }
 
     // Although 'Pragma: no-cache' is not a standard HTTP response header (it's
     // a request header), caching is inhibited when this header is present so
     // as to match existing Navigator behavior.
     if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS))
         mPragmaNoCache = true;
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpResponseHead.h
+++ b/netwerk/protocol/http/nsHttpResponseHead.h
@@ -5,16 +5,18 @@
 
 #ifndef nsHttpResponseHead_h__
 #define nsHttpResponseHead_h__
 
 #include "nsHttpHeaderArray.h"
 #include "nsHttp.h"
 #include "nsString.h"
 
+namespace mozilla { namespace net {
+
 //-----------------------------------------------------------------------------
 // nsHttpResponseHead represents the status line and headers from an HTTP
 // response.
 //-----------------------------------------------------------------------------
 
 class nsHttpResponseHead
 {
 public:
@@ -127,10 +129,11 @@ private:
     nsCString         mContentType;
     nsCString         mContentCharset;
     bool              mCacheControlNoStore;
     bool              mCacheControlNoCache;
     bool              mPragmaNoCache;
 
     friend struct IPC::ParamTraits<nsHttpResponseHead>;
 };
+}} // namespace mozilla::net
 
 #endif // nsHttpResponseHead_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -34,33 +34,35 @@
 #include "nsITransport.h"
 #include "nsIOService.h"
 #include <algorithm>
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsINetworkStatsServiceProxy.h"
 #endif
 
-using namespace mozilla;
 
 //-----------------------------------------------------------------------------
 
 #ifdef DEBUG
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 #endif
 
 //-----------------------------------------------------------------------------
 
 static NS_DEFINE_CID(kMultiplexInputStream, NS_MULTIPLEXINPUTSTREAM_CID);
 
 // Place a limit on how much non-compliant HTTP can be skipped while
 // looking for a response header
 #define MAX_INVALID_RESPONSE_BODY_SIZE (1024 * 128)
 
+namespace mozilla {
+namespace net {
+
 //-----------------------------------------------------------------------------
 // helpers
 //-----------------------------------------------------------------------------
 
 #if defined(PR_LOGGING)
 static void
 LogHeaders(const char *lineStart)
 {
@@ -1957,8 +1959,11 @@ nsHttpTransaction::RestartVerifier::Set(
         // We can only restart with any confidence if we have a stored etag or
         // last-modified header
         if (mETag.IsEmpty() && mLastModified.IsEmpty())
             return;
 
         mSetup = true;
     }
 }
+
+} // namespace mozilla::net
+} // namespace mozilla
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -18,31 +18,34 @@
 #include "nsProxyRelease.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsINetworkManager.h"
 #endif
 
 //-----------------------------------------------------------------------------
 
-class nsHttpRequestHead;
-class nsHttpResponseHead;
-class nsHttpChunkedDecoder;
 class nsIHttpActivityObserver;
 class nsIEventTarget;
 class nsIInputStream;
 class nsIOutputStream;
 
+namespace mozilla { namespace net {
+
+class nsHttpChunkedDecoder;
+class nsHttpRequestHead;
+class nsHttpResponseHead;
+
 //-----------------------------------------------------------------------------
 // nsHttpTransaction represents a single HTTP transaction.  It is thread-safe,
 // intended to run on the socket thread.
 //-----------------------------------------------------------------------------
 
 class nsHttpTransaction : public nsAHttpTransaction
-                        , public mozilla::net::ATokenBucketEvent
+                        , public ATokenBucketEvent
                         , public nsIInputStreamCallback
                         , public nsIOutputStreamCallback
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSAHTTPTRANSACTION
     NS_DECL_NSIINPUTSTREAMCALLBACK
     NS_DECL_NSIOUTPUTSTREAMCALLBACK
@@ -105,18 +108,18 @@ public:
     int32_t    Priority()                 { return mPriority; }
 
     const TimingStruct& Timings() const { return mTimings; }
     enum Classifier Classification() { return mClassification; }
 
     void PrintDiagnostics(nsCString &log);
 
     // Sets mPendingTime to the current time stamp or to a null time stamp (if now is false)
-    void SetPendingTime(bool now = true) { mPendingTime = now ? mozilla::TimeStamp::Now() : mozilla::TimeStamp(); }
-    const mozilla::TimeStamp GetPendingTime() { return mPendingTime; }
+    void SetPendingTime(bool now = true) { mPendingTime = now ? TimeStamp::Now() : TimeStamp(); }
+    const TimeStamp GetPendingTime() { return mPendingTime; }
     bool UsesPipelining() const { return mCaps & NS_HTTP_ALLOW_PIPELINING; }
 
     // overload of nsAHttpTransaction::LoadGroupConnectionInfo()
     nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return mLoadGroupCI.get(); }
     void SetLoadGroupConnectionInfo(nsILoadGroupConnectionInfo *aLoadGroupCI) { mLoadGroupCI = aLoadGroupCI; }
     void DispatchedAsBlocking();
     void RemoveDispatchedAsBlocking();
 
@@ -162,17 +165,17 @@ private:
                 mTrans->mConnection->SetSecurityCallbacks(mCallbacks);
             return NS_OK;
         }
       private:
         nsRefPtr<nsHttpTransaction> mTrans;
         nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
     };
 
-    mozilla::Mutex mCallbacksLock;
+    Mutex mCallbacksLock;
 
     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
     nsCOMPtr<nsITransportEventSink> mTransportSink;
     nsCOMPtr<nsIEventTarget>        mConsumerTarget;
     nsCOMPtr<nsISupports>           mSecurityInfo;
     nsCOMPtr<nsIAsyncInputStream>   mPipeIn;
     nsCOMPtr<nsIAsyncOutputStream>  mPipeOut;
     nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
@@ -254,17 +257,17 @@ private:
     bool                            mReportedStart;
     bool                            mReportedResponseHeader;
 
     // protected by nsHttp::GetLock()
     nsHttpResponseHead             *mForTakeResponseHead;
     bool                            mResponseHeadTaken;
 
     // The time when the transaction was submitted to the Connection Manager
-    mozilla::TimeStamp              mPendingTime;
+    TimeStamp                       mPendingTime;
 
     class RestartVerifier
     {
 
         // When a idemptotent transaction has received part of its response body
         // and incurs an error it can be restarted. To do this we mark the place
         // where we stopped feeding the body to the consumer and start the
         // network call over again. If everything we track (headers, length, etc..)
@@ -365,9 +368,11 @@ private:
     }
     void                               CountSentBytes(uint64_t sentBytes)
     {
         mCountSent += sentBytes;
         SaveNetworkStats(false);
     }
 };
 
+}} // namespace mozilla::net
+
 #endif // nsHttpTransaction_h__
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -42,16 +42,18 @@ using mozilla::unused;
 #include "gfxContext.h"
 
 #include "Layers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
+#include "ScopedGLHelpers.h"
+#include "mozilla/layers/CompositorOGL.h"
 
 #include "nsTArray.h"
 
 #include "AndroidBridge.h"
 #include "AndroidBridgeUtilities.h"
 #include "android_npapi.h"
 
 #include "imgIEncoder.h"
@@ -2375,16 +2377,20 @@ nsWindow::DrawWindowUnderlay(LayerManage
         return;
     }
 
     mLayerRendererFrame.Init(env, frameObj);
     if (!WidgetPaintsBackground()) {
         return;
     }
 
+    gl::GLContext* gl = static_cast<CompositorOGL*>(aManager->GetCompositor())->gl();
+    gl::ScopedGLState scopedScissorTestState(gl, LOCAL_GL_SCISSOR_TEST);
+    gl::ScopedScissorRect scopedScissorRectState(gl);
+
     client->ActivateProgram();
     if (!mLayerRendererFrame.BeginDrawing(&jniFrame)) return;
     if (!mLayerRendererFrame.DrawBackground(&jniFrame)) return;
     client->DeactivateProgram(); // redundant, but in case somebody adds code after this...
 }
 
 void
 nsWindow::DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect)
@@ -2397,16 +2403,20 @@ nsWindow::DrawWindowOverlay(LayerManager
 
     AutoLocalJNIFrame jniFrame(env);
 
     NS_ABORT_IF_FALSE(!mLayerRendererFrame.isNull(),
                       "Frame should have been created in DrawWindowUnderlay()!");
 
     GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient();
 
+    gl::GLContext* gl = static_cast<CompositorOGL*>(aManager->GetCompositor())->gl();
+    gl::ScopedGLState scopedScissorTestState(gl, LOCAL_GL_SCISSOR_TEST);
+    gl::ScopedScissorRect scopedScissorRectState(gl);
+
     client->ActivateProgram();
     if (!mLayerRendererFrame.DrawForeground(&jniFrame)) return;
     if (!mLayerRendererFrame.EndDrawing(&jniFrame)) return;
     client->DeactivateProgram();
     mLayerRendererFrame.Dispose(env);
 }
 
 // off-main-thread compositor fields and functions
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -55,18 +55,19 @@
 #include "gfxQuartzSurface.h"
 #include "gfxUtils.h"
 #include "nsRegion.h"
 #include "Layers.h"
 #include "ClientLayerManager.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "GLTextureImage.h"
 #include "GLContextProvider.h"
-#include "GLContext.h"
+#include "GLContextCGL.h"
 #include "GLUploadHelpers.h"
+#include "ScopedGLHelpers.h"
 #include "mozilla/layers/GLManager.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "mozilla/layers/BasicCompositor.h"
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/BorrowedContext.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
@@ -348,18 +349,17 @@ public:
   }
   virtual void BindAndDrawQuad(ShaderProgramOGL *aProg) MOZ_OVERRIDE;
 
   void BeginFrame(nsIntSize aRenderSize);
   void EndFrame();
 
   NSOpenGLContext* GetNSOpenGLContext()
   {
-    return static_cast<NSOpenGLContext*>(
-      mGLContext->GetNativeData(GLContext::NativeGLContext));
+    return GLContextCGL::Cast(mGLContext)->GetNSOpenGLContext();
   }
 
 protected:
   nsRefPtr<mozilla::gl::GLContext> mGLContext;
   nsAutoPtr<mozilla::layers::ShaderProgramOGL> mRGBARectProgram;
   GLuint mQuadVBO;
 };
 
@@ -2052,49 +2052,53 @@ nsChildView::PreRender(LayerManagerCompo
     return true;
   }
 
   // The lock makes sure that we don't attempt to tear down the view while
   // compositing. That would make us unable to call postRender on it when the
   // composition is done, thus keeping the GL context locked forever.
   mViewTearDownLock.Lock();
 
-  NSOpenGLContext *glContext = (NSOpenGLContext *)manager->gl()->GetNativeData(GLContext::NativeGLContext);
+  NSOpenGLContext *glContext = GLContextCGL::Cast(manager->gl())->GetNSOpenGLContext();
 
   if (![(ChildView*)mView preRender:glContext]) {
     mViewTearDownLock.Unlock();
     return false;
   }
   return true;
 }
 
 void
 nsChildView::PostRender(LayerManagerComposite* aManager)
 {
   nsAutoPtr<GLManager> manager(GLManager::CreateGLManager(aManager));
   if (!manager) {
     return;
   }
-  NSOpenGLContext *glContext = (NSOpenGLContext *)manager->gl()->GetNativeData(GLContext::NativeGLContext);
+  NSOpenGLContext *glContext = GLContextCGL::Cast(manager->gl())->GetNSOpenGLContext();
   [(ChildView*)mView postRender:glContext];
   mViewTearDownLock.Unlock();
 }
 
 void
 nsChildView::DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect)
 {
   nsAutoPtr<GLManager> manager(GLManager::CreateGLManager(aManager));
   if (manager) {
     DrawWindowOverlay(manager, aRect);
   }
 }
 
 void
 nsChildView::DrawWindowOverlay(GLManager* aManager, nsIntRect aRect)
 {
+  GLContext* gl = aManager->gl();
+  ScopedGLState scopedScissorTestState(gl, LOCAL_GL_SCISSOR_TEST);
+  ScopedScissorRect scopedScissorRectState(gl);
+
   MaybeDrawTitlebar(aManager, aRect);
   MaybeDrawResizeIndicator(aManager, aRect);
   MaybeDrawRoundedCorners(aManager, aRect);
 }
 
 static void
 ClearRegion(gfx::DrawTarget *aDT, nsIntRegion aRegion)
 {
@@ -2728,17 +2732,16 @@ RectTextureImage::Draw(GLManager* aManag
   aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
 }
 
 // GLPresenter implementation
 
 GLPresenter::GLPresenter(GLContext* aContext)
  : mGLContext(aContext)
 {
-  mGLContext->SetFlipped(true);
   mGLContext->MakeCurrent();
   mRGBARectProgram = new ShaderProgramOGL(mGLContext,
     ProgramProfileOGL::GetProfileFor(RGBARectLayerProgramType, MaskNone));
 
   // Create mQuadVBO.
   mGLContext->fGenBuffers(1, &mQuadVBO);
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
 
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -745,16 +745,19 @@ struct JsGcTracer : public TraceCallback
     JS_CallHeapObjectTracer(static_cast<JSTracer*>(closure), p, name);
   }
   virtual void Trace(JS::Heap<JSString *> *p, const char *name, void *closure) const MOZ_OVERRIDE {
     JS_CallHeapStringTracer(static_cast<JSTracer*>(closure), p, name);
   }
   virtual void Trace(JS::Heap<JSScript *> *p, const char *name, void *closure) const MOZ_OVERRIDE {
     JS_CallHeapScriptTracer(static_cast<JSTracer*>(closure), p, name);
   }
+  virtual void Trace(JS::Heap<JSFunction *> *p, const char *name, void *closure) const MOZ_OVERRIDE {
+    JS_CallHeapFunctionTracer(static_cast<JSTracer*>(closure), p, name);
+  }
 };
 
 static PLDHashOperator
 TraceJSHolder(void* aHolder, nsScriptObjectTracer*& aTracer, void* aArg)
 {
   aTracer->Trace(aHolder, JsGcTracer(), aArg);
 
   return PL_DHASH_NEXT;
@@ -797,16 +800,21 @@ struct ClearJSHolder : TraceCallbacks
   {
     *aPtr = nullptr;
   }
 
   virtual void Trace(JS::Heap<JSScript*>* aPtr, const char*, void*) const MOZ_OVERRIDE
   {
     *aPtr = nullptr;
   }
+
+  virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char*, void*) const MOZ_OVERRIDE
+  {
+    *aPtr = nullptr;
+  }
 };
 
 void
 CycleCollectedJSRuntime::RemoveJSHolder(void* aHolder)
 {
   nsScriptObjectTracer* tracer = mJSHolders.Get(aHolder);
   if (!tracer) {
     return;
@@ -859,17 +867,17 @@ CycleCollectedJSRuntime::GCThingParticip
 
 nsCycleCollectionParticipant*
 CycleCollectedJSRuntime::ZoneParticipant()
 {
     return &mJSZoneCycleCollectorGlobal;
 }
 
 nsresult
-CycleCollectedJSRuntime::BeginCycleCollection(nsCycleCollectionNoteRootCallback &aCb)
+CycleCollectedJSRuntime::TraverseRoots(nsCycleCollectionNoteRootCallback &aCb)
 {
   static bool gcHasRun = false;
   if (!gcHasRun) {
     uint32_t gcNumber = JS_GetGCParameter(mJSRuntime, JSGC_NUMBER);
     if (!gcNumber) {
       // Cannot cycle collect if GC has not run first!
       MOZ_CRASH();
     }
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -189,17 +189,17 @@ public:
 #endif
 
   already_AddRefed<nsIException> GetPendingException() const;
   void SetPendingException(nsIException* aException);
 
   nsCycleCollectionParticipant* GCThingParticipant();
   nsCycleCollectionParticipant* ZoneParticipant();
 
-  nsresult BeginCycleCollection(nsCycleCollectionNoteRootCallback &aCb);
+  nsresult TraverseRoots(nsCycleCollectionNoteRootCallback &aCb);
   bool UsefulToMergeZones() const;
   void FixWeakMappingGrayBits() const;
   bool NeedCollect() const;
   void Collect(uint32_t reason) const;
 
   void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc,
                         DeferredFinalizeFunction aFunc,
                         void* aThing);
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -3152,18 +3152,18 @@ nsCycleCollector::BeginCollection(ccType
     mResults.Init();
     bool mergeZones = ShouldMergeZones(aCCType);
     mResults.mMergedZones = mergeZones;
 
     MOZ_ASSERT(!mBuilder, "Forgot to clear mBuilder");
     mBuilder = new GCGraphBuilder(mGraph, mResults, mJSRuntime, mListener, mergeZones);
 
     if (mJSRuntime) {
-        mJSRuntime->BeginCycleCollection(*mBuilder);
-        timeLog.Checkpoint("mJSRuntime->BeginCycleCollection()");
+        mJSRuntime->TraverseRoots(*mBuilder);
+        timeLog.Checkpoint("mJSRuntime->TraverseRoots()");
     }
 
     AutoRestore<bool> ar(mScanInProgress);
     MOZ_ASSERT(!mScanInProgress);
     mScanInProgress = true;
     mPurpleBuf.SelectPointers(*mBuilder);
     timeLog.Checkpoint("SelectPointers()");
 
--- a/xpcom/glue/nsCycleCollectionParticipant.cpp
+++ b/xpcom/glue/nsCycleCollectionParticipant.cpp
@@ -83,16 +83,22 @@ TraceCallbackFunc::Trace(JS::Heap<jsid>*
 
 void
 TraceCallbackFunc::Trace(JS::Heap<JSObject*>* p, const char* name, void* closure) const
 {
   mCallback(*p, name, closure);
 }
 
 void
+TraceCallbackFunc::Trace(JS::Heap<JSFunction*>* p, const char* name, void* closure) const
+{
+  mCallback(*p, name, closure);
+}
+
+void
 TraceCallbackFunc::Trace(JS::Heap<JSString*>* p, const char* name, void* closure) const
 {
   mCallback(*p, name, closure);
 }
 
 void
 TraceCallbackFunc::Trace(JS::Heap<JSScript*>* p, const char* name, void* closure) const
 {
--- a/xpcom/glue/nsCycleCollectionParticipant.h
+++ b/xpcom/glue/nsCycleCollectionParticipant.h
@@ -55,16 +55,17 @@ template <class T> class Heap;
  */
 struct TraceCallbacks
 {
     virtual void Trace(JS::Heap<JS::Value>* p, const char* name, void* closure) const = 0;
     virtual void Trace(JS::Heap<jsid>* p, const char* name, void* closure) const = 0;
     virtual void Trace(JS::Heap<JSObject*>* p, const char* name, void* closure) const = 0;
     virtual void Trace(JS::Heap<JSString*>* p, const char* name, void* closure) const = 0;
     virtual void Trace(JS::Heap<JSScript*>* p, const char* name, void* closure) const = 0;
+    virtual void Trace(JS::Heap<JSFunction*>* p, const char* name, void* closure) const = 0;
 };
 
 /*
  * An implementation of TraceCallbacks that calls a single function for all JS
  * GC thing types encountered.
  */
 struct TraceCallbackFunc : public TraceCallbacks
 {
@@ -72,16 +73,17 @@ struct TraceCallbackFunc : public TraceC
 
     explicit TraceCallbackFunc(Func cb) : mCallback(cb) {}
 
     virtual void Trace(JS::Heap<JS::Value>* p, const char* name, void* closure) const MOZ_OVERRIDE;
     virtual void Trace(JS::Heap<jsid>* p, const char* name, void* closure) const MOZ_OVERRIDE;
     virtual void Trace(JS::Heap<JSObject*>* p, const char* name, void* closure) const MOZ_OVERRIDE;
     virtual void Trace(JS::Heap<JSString*>* p, const char* name, void* closure) const MOZ_OVERRIDE;
     virtual void Trace(JS::Heap<JSScript*>* p, const char* name, void* closure) const MOZ_OVERRIDE;
+    virtual void Trace(JS::Heap<JSFunction*>* p, const char* name, void* closure) const MOZ_OVERRIDE;
 
   private:
     Func mCallback;
 };
 
 /**
  * Participant implementation classes
  */