Bug 1371228 - Handling SteamVR process quit events to avoid crashes. r=kip, a=jcristau
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 22 Jun 2017 14:32:18 +0800
changeset 414114 8678aff96ccbd53e80137cc5951916b3b3cab26e
parent 414113 017218b8ecdc2646ae6c12ed7e14b588fcb6d080
child 414115 34751b9bda2b7e2fe0c6f6e0d44cff079e604919
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip, jcristau
bugs1371228
milestone55.0
Bug 1371228 - Handling SteamVR process quit events to avoid crashes. r=kip, a=jcristau MozReview-Commit-ID: DBkzz06pRSu
gfx/vr/VRDisplayHost.cpp
gfx/vr/VRDisplayHost.h
gfx/vr/gfxVROpenVR.cpp
gfx/vr/ipc/VRLayerChild.cpp
gfx/vr/ipc/VRLayerChild.h
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -36,16 +36,22 @@ VRDisplayHost::~VRDisplayHost()
 }
 
 void
 VRDisplayHost::SetGroupMask(uint32_t aGroupMask)
 {
   mDisplayInfo.mGroupMask = aGroupMask;
 }
 
+bool
+VRDisplayHost::GetIsConnected()
+{
+  return mDisplayInfo.mIsConnected;
+}
+
 void
 VRDisplayHost::AddLayer(VRLayerParent *aLayer)
 {
   mLayers.AppendElement(aLayer);
   mDisplayInfo.mPresentingGroups |= aLayer->GetGroup();
   if (mLayers.Length() == 1) {
     StartPresentation();
   }
--- a/gfx/vr/VRDisplayHost.h
+++ b/gfx/vr/VRDisplayHost.h
@@ -45,16 +45,17 @@ public:
   void StartFrame();
   void SubmitFrame(VRLayerParent* aLayer,
                    mozilla::layers::PTextureParent* aTexture,
                    const gfx::Rect& aLeftEyeRect,
                    const gfx::Rect& aRightEyeRect);
 
   bool CheckClearDisplayInfoDirty();
   void SetGroupMask(uint32_t aGroupMask);
+  bool GetIsConnected();
 
 protected:
   explicit VRDisplayHost(VRDeviceType aType);
   virtual ~VRDisplayHost();
 
 #if defined(XP_WIN)
   // Subclasses should override this SubmitFrame function.
   // Returns true if the SubmitFrame call will block as necessary
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -173,28 +173,33 @@ VRDisplayOpenVR::ZeroSensor()
   UpdateStageParameters();
 }
 
 void
 VRDisplayOpenVR::PollEvents()
 {
   ::vr::VREvent_t event;
   while (mVRSystem->PollNextEvent(&event, sizeof(event))) {
-    if (event.trackedDeviceIndex == ::vr::k_unTrackedDeviceIndex_Hmd) {
-      switch (event.eventType) {
+    switch (event.eventType) {
       case ::vr::VREvent_TrackedDeviceUserInteractionStarted:
         mDisplayInfo.mIsMounted = true;
         break;
       case ::vr::VREvent_TrackedDeviceUserInteractionEnded:
         mDisplayInfo.mIsMounted = false;
         break;
+      case ::vr::EVREventType::VREvent_DriverRequestedQuit:
+      case ::vr::EVREventType::VREvent_Quit:
+      case ::vr::EVREventType::VREvent_ProcessQuit:
+      case ::vr::EVREventType::VREvent_QuitAcknowledged:
+      case ::vr::EVREventType::VREvent_QuitAborted_UserPrompt:
+        mDisplayInfo.mIsConnected = false;
+        break;
       default:
         // ignore
         break;
-      }
     }
   }
 }
 
 VRHMDSensorState
 VRDisplayOpenVR::GetSensorState()
 {
   PollEvents();
@@ -462,17 +467,16 @@ VRControllerOpenVR::UpdateVibrateHaptic(
     VibrateHapticComplete(aPromiseID);
   }
 }
 
 void
 VRControllerOpenVR::VibrateHapticComplete(uint32_t aPromiseID)
 {
   VRManager *vm = VRManager::Get();
-  MOZ_ASSERT(vm);
 
   CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod<uint32_t>
     (vm, &VRManager::NotifyVibrateHapticCompleted, aPromiseID));
 }
 
 void
 VRControllerOpenVR::VibrateHaptic(::vr::IVRSystem* aVRSystem,
                                   uint32_t aHapticIndex,
@@ -541,20 +545,22 @@ VRSystemManagerOpenVR::Shutdown()
   }
   RemoveControllers();
   mVRSystem = nullptr;
 }
 
 void
 VRSystemManagerOpenVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
 {
-  if (!::vr::VR_IsHmdPresent()) {
-    if (mOpenVRHMD) {
-      mOpenVRHMD = nullptr;
-    }
+  if (!::vr::VR_IsHmdPresent() ||
+      (mOpenVRHMD && !mOpenVRHMD->GetIsConnected())) {
+    // OpenVR runtime could be quit accidentally,
+    // and we make it re-initialize.
+    mOpenVRHMD = nullptr;
+    mVRSystem = nullptr;
   } else if (mOpenVRHMD == nullptr) {
     ::vr::HmdError err;
 
     ::vr::VR_Init(&err, ::vr::EVRApplicationType::VRApplication_Scene);
     if (err) {
       return;
     }
 
--- a/gfx/vr/ipc/VRLayerChild.cpp
+++ b/gfx/vr/ipc/VRLayerChild.cpp
@@ -83,17 +83,16 @@ VRLayerChild::IsIPCOpen()
 
 void
 VRLayerChild::ClearSurfaces()
 {
   mFront = nullptr;
   mShSurfClient = nullptr;
 }
 
-mozilla::ipc::IPCResult
-VRLayerChild::Recv__delete__()
+void
+VRLayerChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   mIPCOpen = false;
-  return IPC_OK();
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/vr/ipc/VRLayerChild.h
+++ b/gfx/vr/ipc/VRLayerChild.h
@@ -35,17 +35,17 @@ public:
   VRLayerChild(uint32_t aVRDisplayID, VRManagerChild* aVRManagerChild);
   void Initialize(dom::HTMLCanvasElement* aCanvasElement);
   void SubmitFrame();
   bool IsIPCOpen();
 
 protected:
   virtual ~VRLayerChild();
   void ClearSurfaces();
-  virtual mozilla::ipc::IPCResult Recv__delete__() override;
+  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   uint32_t mVRDisplayID;
 
   RefPtr<dom::HTMLCanvasElement> mCanvasElement;
   RefPtr<layers::SharedSurfaceTextureClient> mShSurfClient;
   RefPtr<layers::TextureClient> mFront;
   bool mIPCOpen;
 };