Bug 1371228 - Handling SteamVR process quit events to avoid crashes; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 22 Jun 2017 14:32:18 +0800
changeset 598741 4a8002c55690960f7731cb9f98ac073ed19fdeaf
parent 596219 95543bdc59bd038a3d5d084b85a4fec493c349ee
child 634568 25443a1bc5915886a1adb461c33bed5195d68ee7
push id65307
push userbmo:dmu@mozilla.com
push dateThu, 22 Jun 2017 06:33:39 +0000
reviewerskip
bugs1371228
milestone56.0a1
Bug 1371228 - Handling SteamVR process quit events to avoid crashes; r?kip MozReview-Commit-ID: DBkzz06pRSu
gfx/vr/gfxVROpenVR.cpp
gfx/vr/gfxVROpenVR.h
gfx/vr/ipc/VRLayerChild.cpp
gfx/vr/ipc/VRLayerChild.h
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -168,33 +168,44 @@ VRDisplayOpenVR::UpdateStageParameters()
 
 void
 VRDisplayOpenVR::ZeroSensor()
 {
   mVRSystem->ResetSeatedZeroPose();
   UpdateStageParameters();
 }
 
+bool
+VRDisplayOpenVR::GetIsConnected()
+{
+  return mDisplayInfo.mIsConnected;
+}
+
 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 +473,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 +551,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/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -22,16 +22,17 @@ namespace mozilla {
 namespace gfx {
 namespace impl {
 
 class VRDisplayOpenVR : public VRDisplayHost
 {
 public:
   virtual void NotifyVSync() override;
   void ZeroSensor() override;
+  bool GetIsConnected();
 
 protected:
   virtual VRHMDSensorState GetSensorState() override;
   virtual void StartPresentation() override;
   virtual void StopPresentation() override;
 #if defined(XP_WIN)
   virtual bool SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
                            const IntSize& aSize,
--- 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;
 };