Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 08 Jan 2014 13:29:01 +0100
changeset 162547 2e6f5635d28c38609ddd3797ed6493ef23a57e7d
parent 162546 b524fc6b21b9da837c0ee6f0c91ae3f0b86e37bb (current diff)
parent 162508 d852bcf897cafaf88343d2a69544ab5ec7b16d99 (diff)
child 162548 cd03f802a3b9aede1c12cb7b2b116219b1738016
push idunknown
push userunknown
push dateunknown
milestone29.0a1
Merge mozilla-central to fx-team
--- 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/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "9960daf91c384990c4bbe7c1221905db7536596b", 
+    "revision": "65400ea2bb3e99ad717f4b99e24ebbfa23b05b58", 
     "repo_path": "/integration/gaia-central"
 }
--- 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/mobilemessage/src/gonk/MmsService.js
+++ b/dom/mobilemessage/src/gonk/MmsService.js
@@ -2267,17 +2267,27 @@ MmsService.prototype = {
           return;
         }
       }
 
       // Get the RIL service ID based on the saved MMS message record's ICC ID,
       // which could fail when the corresponding SIM card isn't installed.
       let serviceId;
       try {
-        serviceId = gRil.getClientIdByIccId(aMessageRecord.iccId);
+        if (aMessageRecord.iccId == null) {
+          // If the ICC ID isn't available, it means the MMS has been received
+          // during the previous version that didn't take the DSDS scenario
+          // into consideration. Tentatively, setting the service ID to be 0 by
+          // default is better than nothing. Although it might use the wrong
+          // SIM to download the desired MMS, eventually it would still fail to
+          // download due to the wrong MMSC and proxy settings.
+          serviceId = 0;
+        } else {
+          serviceId = gRil.getClientIdByIccId(aMessageRecord.iccId);
+        }
       } catch (e) {
         if (DEBUG) debug("RIL service is not available for ICC ID.");
         aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR);
         return;
       }
 
       // To support DSDS, we have to stop users retrieving MMS when the needed
       // SIM is not active, thus avoiding the data disconnection of the current
@@ -2405,17 +2415,27 @@ MmsService.prototype = {
       debug("messageID: " + messageID + " toAddress: " +
             JSON.stringify(toAddress));
     }
 
     // Get the RIL service ID based on the saved MMS message record's ICC ID,
     // which could fail when the corresponding SIM card isn't installed.
     let serviceId;
     try {
-      serviceId = gRil.getClientIdByIccId(iccId);
+      if (iccId == null) {
+        // If the ICC ID isn't available, it means the MMS has been received
+        // during the previous version that didn't take the DSDS scenario
+        // into consideration. Tentatively, setting the service ID to be 0 by
+        // default is better than nothing. Although it might use the wrong
+        // SIM to send the read report for the desired MMS, eventually it
+        // would still fail to send due to the wrong MMSC and proxy settings.
+        serviceId = 0;
+      } else {
+        serviceId = gRil.getClientIdByIccId(iccId);
+      }
     } catch (e) {
       if (DEBUG) debug("RIL service is not available for ICC ID.");
       return;
     }
 
     let mmsConnection = gMmsConnections.getConnByServiceId(serviceId);
     try {
       let transaction =
--- 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/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
  */