Bug 1316221 - Force VideoBridge shutdown to happen before the compositor thread is destroyed. r=dvander
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 11 Nov 2016 15:02:32 +1300
changeset 352405 474aa8db322324a478fa8d2c363f2e6d7feca874
parent 352404 46ce017b754c9ec763c525f322bfa9dfd533e7e8
child 352406 51c6779de012f965debbc81f2d1885ed29375290
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs1316221
milestone52.0a1
Bug 1316221 - Force VideoBridge shutdown to happen before the compositor thread is destroyed. r=dvander
dom/media/ipc/VideoDecoderManagerParent.cpp
dom/media/ipc/VideoDecoderManagerParent.h
gfx/ipc/GPUParent.cpp
gfx/layers/ipc/VideoBridgeChild.cpp
--- a/dom/media/ipc/VideoDecoderManagerParent.cpp
+++ b/dom/media/ipc/VideoDecoderManagerParent.cpp
@@ -12,16 +12,17 @@
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsIEventTarget.h"
 #include "nsThreadUtils.h"
 #include "ImageContainer.h"
 #include "mozilla/layers/VideoBridgeChild.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/layers/ImageDataSerializer.h"
+#include "mozilla/SyncRunnable.h"
 
 #if XP_WIN
 #include <objbase.h>
 #endif
 
 namespace mozilla {
 namespace dom {
 
@@ -98,23 +99,31 @@ VideoDecoderManagerParent::StartupThread
 
 void
 VideoDecoderManagerParent::ShutdownThreads()
 {
   sManagerTaskQueue->BeginShutdown();
   sManagerTaskQueue->AwaitShutdownAndIdle();
   sManagerTaskQueue = nullptr;
 
-  sVideoDecoderManagerThread->Dispatch(NS_NewRunnableFunction([]() {
-    layers::VideoBridgeChild::Shutdown();
-  }), NS_DISPATCH_SYNC);
   sVideoDecoderManagerThread->Shutdown();
   sVideoDecoderManagerThread = nullptr;
 }
 
+void
+VideoDecoderManagerParent::ShutdownVideoBridge()
+{
+  if (sVideoDecoderManagerThread) {
+    RefPtr<Runnable> task = NS_NewRunnableFunction([]() {
+      VideoBridgeChild::Shutdown();
+    });
+    SyncRunnable::DispatchToThread(sVideoDecoderManagerThread, task);
+  }
+}
+
 bool
 VideoDecoderManagerParent::OnManagerThread()
 {
   return NS_GetCurrentThread() == sVideoDecoderManagerThread;
 }
 
 bool
 VideoDecoderManagerParent::CreateForContent(Endpoint<PVideoDecoderManagerParent>&& aEndpoint)
--- a/dom/media/ipc/VideoDecoderManagerParent.h
+++ b/dom/media/ipc/VideoDecoderManagerParent.h
@@ -19,16 +19,18 @@ public:
   static bool CreateForContent(Endpoint<PVideoDecoderManagerParent>&& aEndpoint);
 
   // Can be called from any thread
   SurfaceDescriptorGPUVideo StoreImage(layers::Image* aImage, layers::TextureClient* aTexture);
 
   static void StartupThreads();
   static void ShutdownThreads();
 
+  static void ShutdownVideoBridge();
+
   bool OnManagerThread();
 
 protected:
   PVideoDecoderParent* AllocPVideoDecoderParent() override;
   bool DeallocPVideoDecoderParent(PVideoDecoderParent* actor) override;
 
   bool RecvReadback(const SurfaceDescriptorGPUVideo& aSD, SurfaceDescriptor* aResult) override;
   bool RecvDeallocateSurfaceDescriptorGPUVideo(const SurfaceDescriptorGPUVideo& aSD) override;
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/ipc/CrashReporterClient.h"
 #include "mozilla/ipc/ProcessChild.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/dom/VideoDecoderManagerParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/ImageBridgeParent.h"
+#include "mozilla/dom/VideoDecoderManagerChild.h"
 #include "mozilla/layers/LayerTreeOwnerTracker.h"
 #include "nsDebugImpl.h"
 #include "nsExceptionHandler.h"
 #include "nsThreadManager.h"
 #include "prenv.h"
 #include "ProcessUtils.h"
 #include "VRManager.h"
 #include "VRManagerParent.h"
@@ -363,16 +364,17 @@ GPUParent::ActorDestroy(ActorDestroyReas
   // state.
   ProcessChild::QuickExit();
 #endif
 
   if (mVsyncBridge) {
     mVsyncBridge->Shutdown();
     mVsyncBridge = nullptr;
   }
+  dom::VideoDecoderManagerParent::ShutdownVideoBridge();
   CompositorThreadHolder::Shutdown();
   Factory::ShutDown();
 #if defined(XP_WIN)
   DeviceManagerDx::Shutdown();
   DeviceManagerD3D9::Shutdown();
 #endif
   LayerTreeOwnerTracker::Shutdown();
   gfxVars::Shutdown();
--- a/gfx/layers/ipc/VideoBridgeChild.cpp
+++ b/gfx/layers/ipc/VideoBridgeChild.cpp
@@ -25,19 +25,20 @@ VideoBridgeChild::Startup()
                                    ipc::ChildSide);
   sVideoBridgeChildSingleton->mIPDLSelfRef = sVideoBridgeChildSingleton;
   parent->SetOtherProcessId(base::GetCurrentProcId());
 }
 
 /* static */ void
 VideoBridgeChild::Shutdown()
 {
-  sVideoBridgeChildSingleton->Close();
-  sVideoBridgeChildSingleton = nullptr;
-
+  if (sVideoBridgeChildSingleton) {
+    sVideoBridgeChildSingleton->Close();
+    sVideoBridgeChildSingleton = nullptr;
+  }
 }
 
 VideoBridgeChild::VideoBridgeChild()
   : mMessageLoop(MessageLoop::current())
   , mCanSend(true)
 {
 }