merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 19 Sep 2017 11:12:14 +0200
changeset 381591 e4261f5b96ebfd63e7cb8af3035ff9fea90c74a5
parent 381586 7c12af6fd620adc74e9dfb622d17966bdebdf2ac (current diff)
parent 381590 7742383e9492e747b2b79757a969b51770c0fba7 (diff)
child 381592 44f69e2140e214353c040fc0846da0b346dbd4b5
child 381604 25a9fbed058272223cbf45e2240c5e12474175b5
child 381697 db7b879601c6f7a4666c3f3be2dd2dd863fd92a2
push id32533
push userarchaeopteryx@coole-files.de
push dateTue, 19 Sep 2017 09:12:30 +0000
treeherdermozilla-central@e4261f5b96eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone57.0a1
first release with
nightly linux64
e4261f5b96eb / 57.0a1 / 20170919100405 / files
nightly mac
e4261f5b96eb / 57.0a1 / 20170919100405 / files
nightly win32
e4261f5b96eb / 57.0a1 / 20170919100405 / files
nightly win64
e4261f5b96eb / 57.0a1 / 20170919100405 / files
nightly linux32
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central. r=merge a=merge MozReview-Commit-ID: gZsJeZjJjm
--- a/accessible/tests/browser/tree/browser_aria_owns.js
+++ b/accessible/tests/browser/tree/browser_aria_owns.js
@@ -153,16 +153,24 @@ addAccessibleTask(`
     await contentSpawnMutation(browser, NO_MOVE, function() {
       document.getElementById("container").setAttribute("aria-owns", "a c b");
     });
 
     testChildrenIds(containerAcc.firstChild, ["a", "b", "c"]);
   }
 );
 
+// Don't crash if ID in aria-owns does not exist
+addAccessibleTask(`
+  <select id="container" aria-owns="boom" multiple></select>`,
+  async function(browser, accDoc) {
+    ok(true, "Did not crash");
+  }
+);
+
 addAccessibleTask(`
   <ul id="one">
     <li id="a">Test</li>
     <li id="b">Test 2</li>
     <li id="c">Test 3</li>
   </ul>
   <ul id="two"></ul>`,
   async function(browser, accDoc) {
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -391,21 +391,16 @@ GLBlitHelper::GLBlitHelper(GLContext* co
     : mGL(gl)
     , mQuadVAO(0)
     , mQuadVBO(0)
     , mDrawBlitProg_VertShader(mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER))
     , mYuvUploads{0}
     , mYuvUploads_YSize(0, 0)
     , mYuvUploads_UVSize(0, 0)
 {
-    if (!mGL->IsSupported(GLFeature::vertex_array_object)) {
-        gfxCriticalError() << "GLBlitHelper requires vertex_array_object.";
-        return;
-    }
-
     mGL->fGenBuffers(1, &mQuadVBO);
     {
         const ScopedBindArrayBuffer bindVBO(mGL, mQuadVBO);
 
         const float quadData[] = {
             0, 0,
             1, 0,
             0, 1,
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -134,40 +134,40 @@ CompositorBridgeChild::Destroy()
   // This must not be called from the destructor!
   mTexturesWaitingRecycled.Clear();
 
   // Destroying the layer manager may cause all sorts of things to happen, so
   // let's make sure there is still a reference to keep this alive whatever
   // happens.
   RefPtr<CompositorBridgeChild> selfRef = this;
 
-  if (!mCanSend) {
-    // We may have already called destroy but still have lingering references
-    // or CompositorBridgeChild::ActorDestroy was called. Ensure that we do our
-    // post destroy clean up no matter what. It is safe to call multiple times.
-    MessageLoop::current()->PostTask(NewRunnableMethod(
-      "CompositorBridgeChild::AfterDestroy",
-      selfRef, &CompositorBridgeChild::AfterDestroy));
-    return;
-  }
-
   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     mTexturePools[i]->Destroy();
   }
 
   if (mSectionAllocator) {
     delete mSectionAllocator;
     mSectionAllocator = nullptr;
   }
 
   if (mLayerManager) {
     mLayerManager->Destroy();
     mLayerManager = nullptr;
   }
 
+  if (!mCanSend) {
+    // We may have already called destroy but still have lingering references
+    // or CompositorBridgeChild::ActorDestroy was called. Ensure that we do our
+    // post destroy clean up no matter what. It is safe to call multiple times.
+    MessageLoop::current()->PostTask(NewRunnableMethod(
+      "CompositorBridgeChild::AfterDestroy",
+      selfRef, &CompositorBridgeChild::AfterDestroy));
+    return;
+  }
+
   AutoTArray<PLayerTransactionChild*, 16> transactions;
   ManagedPLayerTransactionChild(transactions);
   for (int i = transactions.Length() - 1; i >= 0; --i) {
     RefPtr<LayerTransactionChild> layers =
       static_cast<LayerTransactionChild*>(transactions[i]);
     layers->Destroy();
   }
 
--- a/gfx/layers/ipc/CompositorManagerParent.cpp
+++ b/gfx/layers/ipc/CompositorManagerParent.cpp
@@ -4,24 +4,29 @@
  * 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/layers/CompositorManagerParent.h"
 #include "mozilla/gfx/GPUParent.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
+#include "nsAutoPtr.h"
 #include "VsyncSource.h"
 
 namespace mozilla {
 namespace layers {
 
 StaticRefPtr<CompositorManagerParent> CompositorManagerParent::sInstance;
 StaticMutex CompositorManagerParent::sMutex;
 
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+StaticAutoPtr<nsTArray<CompositorManagerParent*>> CompositorManagerParent::sActiveActors;
+#endif
+
 /* static */ already_AddRefed<CompositorManagerParent>
 CompositorManagerParent::CreateSameProcess()
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
   StaticMutexAutoLock lock(sMutex);
 
   // We are creating a manager for the UI process, inside the combined GPU/UI
@@ -37,16 +42,23 @@ CompositorManagerParent::CreateSameProce
   // on the main thread and complete before we return the manager handles.
   RefPtr<CompositorManagerParent> parent = new CompositorManagerParent();
   parent->SetOtherProcessId(base::GetCurrentProcId());
 
   // CompositorManagerParent::Bind would normally add a reference for IPDL but
   // we don't use that in the same process case.
   parent.get()->AddRef();
   sInstance = parent;
+
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+  if (!sActiveActors) {
+    sActiveActors = new nsTArray<CompositorManagerParent*>();
+  }
+  sActiveActors->AppendElement(parent);
+#endif
   return parent.forget();
 }
 
 /* static */ void
 CompositorManagerParent::Create(Endpoint<PCompositorManagerParent>&& aEndpoint)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -119,16 +131,24 @@ CompositorManagerParent::Bind(Endpoint<P
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   if (NS_WARN_IF(!aEndpoint.Bind(this))) {
     return;
   }
 
   // Add the IPDL reference to ourself, so we can't get freed until IPDL is
   // done with us.
   AddRef();
+
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+  StaticMutexAutoLock lock(sMutex);
+  if (!sActiveActors) {
+    sActiveActors = new nsTArray<CompositorManagerParent*>();
+  }
+  sActiveActors->AppendElement(this);
+#endif
 }
 
 void
 CompositorManagerParent::ActorDestroy(ActorDestroyReason aReason)
 {
   StaticMutexAutoLock lock(sMutex);
   if (sInstance == this) {
     sInstance = nullptr;
@@ -138,25 +158,65 @@ CompositorManagerParent::ActorDestroy(Ac
 void
 CompositorManagerParent::DeallocPCompositorManagerParent()
 {
   MessageLoop::current()->PostTask(
           NewRunnableMethod("layers::CompositorManagerParent::DeferredDestroy",
                             this,
                             &CompositorManagerParent::DeferredDestroy));
 
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+  StaticMutexAutoLock lock(sMutex);
+  if (sActiveActors) {
+    sActiveActors->RemoveElement(this);
+  }
+#endif
   Release();
 }
 
 void
 CompositorManagerParent::DeferredDestroy()
 {
   mCompositorThreadHolder = nullptr;
 }
 
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+/* static */ void
+CompositorManagerParent::ShutdownInternal()
+{
+  nsAutoPtr<nsTArray<CompositorManagerParent*>> actors;
+
+  // We move here because we may attempt to acquire the same lock during the
+  // destroy to remove the reference in sActiveActors.
+  {
+    StaticMutexAutoLock lock(sMutex);
+    actors = sActiveActors.forget();
+  }
+
+  if (actors) {
+    for (auto& actor : *actors) {
+      actor->Close();
+    }
+  }
+}
+#endif // COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+
+/* static */ void
+CompositorManagerParent::Shutdown()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+  CompositorThreadHolder::Loop()->PostTask(
+      NS_NewRunnableFunction("layers::CompositorManagerParent::Shutdown", []() -> void {
+        CompositorManagerParent::ShutdownInternal();
+      }));
+#endif
+}
+
 PCompositorBridgeParent*
 CompositorManagerParent::AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt)
 {
   switch (aOpt.type()) {
     case CompositorBridgeOptions::TContentCompositorOptions: {
       CrossProcessCompositorBridgeParent* bridge =
         new CrossProcessCompositorBridgeParent(this);
       bridge->AddRef();
--- a/gfx/layers/ipc/CompositorManagerParent.h
+++ b/gfx/layers/ipc/CompositorManagerParent.h
@@ -15,39 +15,49 @@
 #include "nsTArray.h"                   // for AutoTArray
 
 namespace mozilla {
 namespace layers {
 
 class CompositorBridgeParent;
 class CompositorThreadHolder;
 
+#ifndef DEBUG
+#define COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+#endif
+
 class CompositorManagerParent final : public PCompositorManagerParent
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorManagerParent)
 
 public:
   static already_AddRefed<CompositorManagerParent> CreateSameProcess();
   static void Create(Endpoint<PCompositorManagerParent>&& aEndpoint);
+  static void Shutdown();
 
   static already_AddRefed<CompositorBridgeParent>
   CreateSameProcessWidgetCompositorBridge(CSSToLayoutDeviceScale aScale,
                                           const CompositorOptions& aOptions,
                                           bool aUseExternalSurfaceSize,
                                           const gfx::IntSize& aSurfaceSize);
 
   void ActorDestroy(ActorDestroyReason aReason) override;
 
   bool DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor) override;
   PCompositorBridgeParent* AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt) override;
 
 private:
   static StaticRefPtr<CompositorManagerParent> sInstance;
   static StaticMutex sMutex;
 
+#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
+  static StaticAutoPtr<nsTArray<CompositorManagerParent*>> sActiveActors;
+  static void ShutdownInternal();
+#endif
+
   CompositorManagerParent();
   ~CompositorManagerParent() override;
 
   void Bind(Endpoint<PCompositorManagerParent>&& aEndpoint);
 
   void DeallocPCompositorManagerParent() override;
 
   void DeferredDestroy();
--- a/gfx/layers/ipc/CompositorThread.cpp
+++ b/gfx/layers/ipc/CompositorThread.cpp
@@ -124,16 +124,17 @@ void
 CompositorThreadHolder::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
   MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!");
 
   ReleaseImageBridgeParentSingleton();
   gfx::ReleaseVRManagerParentSingleton();
   MediaSystemResourceService::Shutdown();
+  CompositorManagerParent::Shutdown();
 
   sCompositorThreadHolder = nullptr;
 
   // No locking is needed around sFinishedCompositorShutDown because it is only
   // ever accessed on the main thread.
   SpinEventLoopUntil([&]() { return sFinishedCompositorShutDown; });
 
   CompositorBridgeParent::FinishShutdown();