Bug 1430040 - Part 2: According to VRDisplay's state to decide if spawn or shutdown VR process in VRManager. r=kip
authorDaosheng Mu <daoshengmu@gmail.com>
Fri, 28 Dec 2018 22:05:03 +0000
changeset 509580 b9639fb9f845380e41deeda4b8b14805b0aaa183
parent 509579 a18c59a93e0583f45d8367eaa11ca5fc4f842397
child 509581 2f31f4f0cad3e652f8fa9b9f14016f8bd59fa48d
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip
bugs1430040
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1430040 - Part 2: According to VRDisplay's state to decide if spawn or shutdown VR process in VRManager. r=kip Differential Revision: https://phabricator.services.mozilla.com/D15164
gfx/vr/VRManager.cpp
gfx/vr/VRManager.h
gfx/vr/service/VRServiceManager.cpp
gfx/vr/service/VRServiceManager.h
gfx/vr/service/moz.build
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -1,35 +1,34 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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/. */
 
 #include "VRManager.h"
 #include "VRManagerParent.h"
-#include "VRGPUChild.h"
 #include "VRThread.h"
 #include "gfxVR.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/VRDisplay.h"
 #include "mozilla/dom/GamepadEventTypes.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/Unused.h"
-#include "mozilla/gfx/GPUParent.h"
 
 #include "gfxPrefs.h"
 #include "gfxVR.h"
 #include "gfxVRExternal.h"
 
 #include "gfxVRPuppet.h"
 #include "ipc/VRLayerParent.h"
 #if !defined(MOZ_WIDGET_ANDROID)
 #include "service/VRService.h"
+#include "service/VRServiceManager.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 
 namespace mozilla {
@@ -75,25 +74,21 @@ VRManager::VRManager()
   MOZ_ASSERT(sVRManagerSingleton == nullptr);
 
   RefPtr<VRSystemManager> mgr;
 
 #if !defined(MOZ_WIDGET_ANDROID)
   // The VR Service accesses all hardware from a separate process
   // and replaces the other VRSystemManager when enabled.
   if (!gfxPrefs::VRProcessEnabled()) {
-    mVRService = VRService::Create();
-  } else if (gfxPrefs::VRProcessEnabled() && XRE_IsGPUProcess()) {
-    gfx::GPUParent* gpu = GPUParent::GetSingleton();
-    MOZ_ASSERT(gpu);
-    Unused << gpu->SendCreateVRProcess();
+    VRServiceManager::Get().CreateService();
   }
-  if (mVRService) {
+  if (VRServiceManager::Get().IsServiceValid()) {
     mExternalManager =
-        VRSystemManagerExternal::Create(mVRService->GetAPIShmem());
+        VRSystemManagerExternal::Create(VRServiceManager::Get().GetAPIShmem());
   }
   if (mExternalManager) {
     mManagers.AppendElement(mExternalManager);
   }
 #endif
 
   if (!mExternalManager) {
     mExternalManager = VRSystemManagerExternal::Create();
@@ -107,52 +102,53 @@ VRManager::VRManager()
   if (XRE_IsParentProcess() && gfxPrefs::VREnabled()) {
     Preferences::SetBool("dom.gamepad.extensions.enabled", true);
   }
 }
 
 VRManager::~VRManager() {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mInitialized);
+#if !defined(MOZ_WIDGET_ANDROID)
+  if (VRServiceManager::Get().IsServiceValid()) {
+    VRServiceManager::Get().Shutdown();
+  }
+#endif
   MOZ_COUNT_DTOR(VRManager);
 }
 
 void VRManager::Destroy() {
   StopTasks();
   mVRDisplays.Clear();
   mVRControllers.Clear();
   for (uint32_t i = 0; i < mManagers.Length(); ++i) {
     mManagers[i]->Destroy();
   }
 #if !defined(MOZ_WIDGET_ANDROID)
-  if (mVRService) {
-    mVRService->Stop();
-    mVRService = nullptr;
+  if (VRServiceManager::Get().IsServiceValid()) {
+    VRServiceManager::Get().Shutdown();
   }
 #endif
   mInitialized = false;
 }
 
 void VRManager::Shutdown() {
   mVRDisplays.Clear();
   mVRControllers.Clear();
   for (uint32_t i = 0; i < mManagers.Length(); ++i) {
     mManagers[i]->Shutdown();
   }
 #if !defined(MOZ_WIDGET_ANDROID)
-  if (mVRService) {
-    mVRService->Stop();
+  if (VRServiceManager::Get().IsServiceValid()) {
+    VRServiceManager::Get().Stop();
   }
-  if (gfxPrefs::VRProcessEnabled() && VRGPUChild::IsCreated()) {
-    RefPtr<Runnable> task =
-        NS_NewRunnableFunction("VRGPUChild::SendStopVRService", []() -> void {
-          VRGPUChild* vrGPUChild = VRGPUChild::Get();
-          vrGPUChild->SendStopVRService();
-        });
-
+  if (gfxPrefs::VRProcessEnabled() && mVRServiceStarted) {
+    RefPtr<Runnable> task = NS_NewRunnableFunction(
+        "VRServiceManager::ShutdownVRProcess",
+        []() -> void { VRServiceManager::Get().ShutdownVRProcess(); });
     NS_DispatchToMainThread(task.forget());
   }
 #endif
   mVRServiceStarted = false;
 }
 
 void VRManager::Init() { mInitialized = true; }
 
@@ -434,29 +430,22 @@ void VRManager::EnumerateVRDisplays() {
    * and VR Process before enumeration.
    * We don't want to start this until we will
    * actualy enumerate, to avoid continuously
    * re-launching the thread/process when
    * no hardware is found or a VR software update
    * is in progress
    */
 #if !defined(MOZ_WIDGET_ANDROID)
-  // Tell VR process to start VR service.
   if (gfxPrefs::VRProcessEnabled() && !mVRServiceStarted) {
-    RefPtr<Runnable> task =
-        NS_NewRunnableFunction("VRGPUChild::SendStartVRService", []() -> void {
-          VRGPUChild* vrGPUChild = VRGPUChild::Get();
-          vrGPUChild->SendStartVRService();
-        });
-
-    NS_DispatchToMainThread(task.forget());
+    VRServiceManager::Get().CreateVRProcess();
     mVRServiceStarted = true;
   } else if (!gfxPrefs::VRProcessEnabled()) {
-    if (mVRService) {
-      mVRService->Start();
+    if (VRServiceManager::Get().IsServiceValid()) {
+      VRServiceManager::Get().Start();
       mVRServiceStarted = true;
     }
   }
 #endif
 
   /**
    * VRSystemManagers are inserted into mManagers in
    * a strict order of priority.  The managers for the
@@ -484,19 +473,17 @@ void VRManager::RefreshVRDisplays(bool a
    * If we aren't viewing WebVR content, don't enumerate
    * new hardware, as it will cause some devices to power on
    * or interrupt other VR activities.
    */
   if (mVRDisplaysRequested || aMustDispatch) {
     EnumerateVRDisplays();
   }
 #if !defined(MOZ_WIDGET_ANDROID)
-  if (mVRService) {
-    mVRService->Refresh();
-  }
+  VRServiceManager::Get().Refresh();
 #endif
 
   /**
    * VRSystemManager::GetHMDs will not activate new hardware
    * or result in interruption of other VR activities.
    * We can call it even when suppressing enumeration to get
    * the already-enumerated displays.
    */
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -107,19 +107,16 @@ class VRManager {
 
   TimeStamp mLastControllerEnumerationTime;
   TimeStamp mLastDisplayEnumerationTime;
   TimeStamp mLastActiveTime;
   TimeStamp mLastTickTime;
   double mAccumulator100ms;
   RefPtr<VRSystemManagerPuppet> mPuppetManager;
   RefPtr<VRSystemManagerExternal> mExternalManager;
-#if !defined(MOZ_WIDGET_ANDROID)
-  RefPtr<VRService> mVRService;
-#endif
   bool mVRDisplaysRequested;
   bool mVRDisplaysRequestedNonFocus;
   bool mVRControllersRequested;
   bool mVRServiceStarted;
   uint32_t mTaskInterval;
   RefPtr<nsITimer> mTaskTimer;
 };
 
new file mode 100644
--- /dev/null
+++ b/gfx/vr/service/VRServiceManager.cpp
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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/. */
+
+#include "VRServiceManager.h"
+#include "VRGPUChild.h"
+#include "mozilla/gfx/GPUParent.h"
+
+namespace mozilla {
+namespace gfx {
+
+VRServiceManager::VRServiceManager()
+#if !defined(MOZ_WIDGET_ANDROID)
+    : mVRService(nullptr)
+#endif
+{
+}
+
+VRServiceManager& VRServiceManager::Get() {
+  static VRServiceManager instance;
+  return instance;
+}
+
+void VRServiceManager::CreateVRProcess() {
+  // Using PGPU channel to tell the main process
+  // to create VR process.
+  RefPtr<Runnable> task =
+      NS_NewRunnableFunction("GPUParent::SendCreateVRProcess", []() -> void {
+        gfx::GPUParent* gpu = GPUParent::GetSingleton();
+        MOZ_ASSERT(gpu);
+        Unused << gpu->SendCreateVRProcess();
+      });
+
+  NS_DispatchToMainThread(task.forget());
+}
+
+void VRServiceManager::ShutdownVRProcess() {
+  if (VRGPUChild::IsCreated()) {
+    VRGPUChild* vrGPUChild = VRGPUChild::Get();
+    vrGPUChild->SendStopVRService();
+    vrGPUChild->Close();
+    VRGPUChild::Shutdown();
+  }
+  if (gfxPrefs::VRProcessEnabled()) {
+    // Using PGPU channel to tell the main process
+    // to shutdown VR process.
+    gfx::GPUParent* gpu = GPUParent::GetSingleton();
+    MOZ_ASSERT(gpu);
+    Unused << gpu->SendShutdownVRProcess();
+  }
+}
+
+void VRServiceManager::CreateService() {
+  if (!gfxPrefs::VRProcessEnabled()) {
+    mVRService = VRService::Create();
+  }
+}
+
+void VRServiceManager::Start() {
+  if (mVRService) {
+    mVRService->Start();
+  }
+}
+
+void VRServiceManager::Stop() {
+  if (mVRService) {
+    mVRService->Stop();
+  }
+}
+
+void VRServiceManager::Shutdown() {
+  Stop();
+  mVRService = nullptr;
+}
+
+void VRServiceManager::Refresh() {
+  if (mVRService) {
+    mVRService->Refresh();
+  }
+}
+
+bool VRServiceManager::IsServiceValid() { return (mVRService != nullptr); }
+
+VRExternalShmem* VRServiceManager::GetAPIShmem() {
+#if !defined(MOZ_WIDGET_ANDROID)
+  return mVRService->GetAPIShmem();
+#endif
+  return nullptr;
+}
+
+}  // namespace gfx
+}  // namespace mozilla
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/vr/service/VRServiceManager.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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 GFX_VR_SERVICE_MANAGER_H
+#define GFX_VR_SERVICE_MANAGER_H
+
+namespace mozilla {
+namespace gfx {
+
+class VRServiceManager {
+ public:
+  static VRServiceManager& Get();
+
+  void Refresh();
+  void Start();
+  void Stop();
+  void Shutdown();
+  void CreateVRProcess();
+  void ShutdownVRProcess();
+  void CreateService();
+  bool IsServiceValid();
+
+  VRExternalShmem* GetAPIShmem();
+
+ protected:
+ private:
+  VRServiceManager();
+  ~VRServiceManager() = default;
+
+#if !defined(MOZ_WIDGET_ANDROID)
+  RefPtr<VRService> mVRService;
+#endif
+};
+
+}  // namespace gfx
+}  // namespace mozilla
+
+#endif  // GFX_VR_SERVICE_MANAGER_H
\ No newline at end of file
--- a/gfx/vr/service/moz.build
+++ b/gfx/vr/service/moz.build
@@ -10,16 +10,17 @@ if CONFIG['OS_TARGET'] == 'WINNT':
         'OculusSession.cpp',
     ]
 
 # Build OSVR on all platforms except Android
 if CONFIG['OS_TARGET'] != 'Android':
     UNIFIED_SOURCES += [
         'OSVRSession.cpp',
         'VRService.cpp',
+        'VRServiceManager.cpp',
         'VRSession.cpp',
     ]
     include('/ipc/chromium/chromium-config.mozbuild')
 
 # Build OpenVR on Windows, Linux, and macOS desktop targets
 if CONFIG['OS_TARGET'] in ('WINNT', 'Linux', 'Darwin'):
     DIRS += [
         'openvr',