Bug 1494556 - Remove VRListenerThread r=daoshengmu
authorKearwood Gilbert <kgilbert@mozilla.com>
Tue, 02 Oct 2018 21:17:05 +0000
changeset 495029 e03ce4ca0e44dd618b698fa6027733c39aea2f12
parent 495028 fa95314b2d87293cbc150662dc5eaadd73624cf0
child 495030 24a3c513ce5d2050ee3e3b4d402456ba73e7dd11
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaoshengmu
bugs1494556, 1473399
milestone64.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 1494556 - Remove VRListenerThread r=daoshengmu We are refactoring much of the code in gfx/vr, moving most of the code that runs in the VRListenerThread into it's own process. The remaining code will be non-blocking once this refactoring is complete. In order to resolve some shutdown crashes, it is simpler to remove the VRListenerThread and the related code starting and stopping this thread. If this is done prior to completion of the refactoring for Bug 1473399 (Enable VRService thread by default), there would be a regression in responsiveness during detection of VR hardware due to blocking API calls moving off the thread. Differential Revision: https://phabricator.services.mozilla.com/D7227
gfx/ipc/GPUParent.cpp
gfx/layers/ipc/CompositorVsyncScheduler.cpp
gfx/layers/ipc/CompositorVsyncScheduler.h
gfx/thebes/gfxPlatform.cpp
gfx/vr/VRDisplayHost.cpp
gfx/vr/VRManager.cpp
gfx/vr/VRManager.h
gfx/vr/VRThread.cpp
gfx/vr/VRThread.h
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
gfx/vr/gfxVROpenVR.cpp
gfx/vr/gfxVRPuppet.cpp
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerParent.cpp
gfx/vr/ipc/VRManagerParent.h
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -41,17 +41,16 @@
 #include "nsDebugImpl.h"
 #include "nsIGfxInfo.h"
 #include "nsThreadManager.h"
 #include "prenv.h"
 #include "ProcessUtils.h"
 #include "VRGPUChild.h"
 #include "VRManager.h"
 #include "VRManagerParent.h"
-#include "VRThread.h"
 #include "VsyncBridgeParent.h"
 #if defined(XP_WIN)
 # include "mozilla/gfx/DeviceManagerDx.h"
 # include <process.h>
 # include <dwrite.h>
 #endif
 #ifdef MOZ_WIDGET_GTK
 # include <gtk/gtk.h>
@@ -129,18 +128,16 @@ GPUParent::Init(base::ProcessId aParentP
   DeviceManagerDx::Init();
 #endif
 
   if (NS_FAILED(NS_InitMinimalXPCOM())) {
     return false;
   }
 
   CompositorThreadHolder::Start();
-  // TODO: Bug 1406327, Start VRListenerThreadHolder when loading VR content.
-  VRListenerThreadHolder::Start();
   APZThreadUtils::SetControllerThread(MessageLoop::current());
   apz::InitializeGlobalState();
   LayerTreeOwnerTracker::Initialize();
   mozilla::ipc::SetThisProcessName("GPU Process");
 #ifdef XP_WIN
   wmf::MFStartup();
 #endif
   return true;
@@ -528,17 +525,16 @@ GPUParent::ActorDestroy(ActorDestroyReas
 #endif
 
   if (mVsyncBridge) {
     mVsyncBridge->Shutdown();
     mVsyncBridge = nullptr;
   }
   dom::VideoDecoderManagerParent::ShutdownVideoBridge();
   CompositorThreadHolder::Shutdown();
-  VRListenerThreadHolder::Shutdown();
   // There is a case that RenderThread exists when gfxVars::UseWebRender() is false.
   // This could happen when WebRender was fallbacked to compositor.
   if (wr::RenderThread::Get()) {
     wr::RenderThread::ShutDown();
   }
 
   image::ImageMemoryReporter::ShutdownForWebRender();
 
--- a/gfx/layers/ipc/CompositorVsyncScheduler.cpp
+++ b/gfx/layers/ipc/CompositorVsyncScheduler.cpp
@@ -30,17 +30,16 @@
 #include "nsThreadUtils.h"              // for NS_IsMainThread
 #include "mozilla/Telemetry.h"
 #include "mozilla/VsyncDispatcher.h"
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
 #include "VsyncSource.h"
 #endif
 #include "mozilla/widget/CompositorWidget.h"
 #include "VRManager.h"
-#include "VRThread.h"
 
 namespace mozilla {
 
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace std;
 
@@ -77,18 +76,18 @@ CompositorVsyncScheduler::CompositorVsyn
   : mVsyncSchedulerOwner(aVsyncSchedulerOwner)
   , mLastCompose(TimeStamp::Now())
   , mIsObservingVsync(false)
   , mNeedsComposite(0)
   , mVsyncNotificationsSkipped(0)
   , mWidget(aWidget)
   , mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
   , mCurrentCompositeTask(nullptr)
-  , mCurrentVRListenerTaskMonitor("CurrentVRTaskMonitor")
-  , mCurrentVRListenerTask(nullptr)
+  , mCurrentVRTaskMonitor("CurrentVRTaskMonitor")
+  , mCurrentVRTask(nullptr)
 {
   mVsyncObserver = new Observer(this);
 
   // mAsapScheduling is set on the main thread during init,
   // but is only accessed after on the compositor thread.
   mAsapScheduling = gfxPrefs::LayersCompositionFrameRate() == 0 ||
                     gfxPlatform::IsInLayoutAsapMode() ||
                     recordreplay::IsRecordingOrReplaying();
@@ -132,25 +131,25 @@ CompositorVsyncScheduler::PostCompositeT
     mCurrentCompositeTask = task;
     ScheduleTask(task.forget());
   }
 }
 
 void
 CompositorVsyncScheduler::PostVRTask(TimeStamp aTimestamp)
 {
-  MonitorAutoLock lockVR(mCurrentVRListenerTaskMonitor);
-  if (mCurrentVRListenerTask == nullptr && VRListenerThreadHolder::Loop()) {
+  MonitorAutoLock lockVR(mCurrentVRTaskMonitor);
+  if (mCurrentVRTask == nullptr && CompositorThreadHolder::Loop()) {
     RefPtr<Runnable> task = NewRunnableMethod<TimeStamp>(
       "layers::CompositorVsyncScheduler::DispatchVREvents",
       this,
       &CompositorVsyncScheduler::DispatchVREvents,
       aTimestamp);
-    mCurrentVRListenerTask = task;
-    VRListenerThreadHolder::Loop()->PostDelayedTask(task.forget(), 0);
+    mCurrentVRTask = task;
+    CompositorThreadHolder::Loop()->PostDelayedTask(task.forget(), 0);
   }
 }
 
 void
 CompositorVsyncScheduler::ScheduleComposition()
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   if (!mVsyncObserver) {
@@ -315,23 +314,23 @@ CompositorVsyncScheduler::UnobserveVsync
   mWidget->ObserveVsync(nullptr);
   mIsObservingVsync = false;
 }
 
 void
 CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp)
 {
   {
-    MonitorAutoLock lock(mCurrentVRListenerTaskMonitor);
-    mCurrentVRListenerTask = nullptr;
+    MonitorAutoLock lock(mCurrentVRTaskMonitor);
+    mCurrentVRTask = nullptr;
   }
   // This only allows to be called by CompositorVsyncScheduler::PostVRTask()
   // When the process is going to shutdown, the runnable has chance to be executed
-  // by other threads, we only want it to be run at VRListenerThread.
-  if (!VRListenerThreadHolder::IsInVRListenerThread()) {
+  // by other threads, we only want it to be run in the compositor thread.
+  if (!CompositorThreadHolder::IsInCompositorThread()) {
     return;
   }
 
   VRManager* vm = VRManager::Get();
   vm->NotifyVsync(aVsyncTimestamp);
 }
 
 void
--- a/gfx/layers/ipc/CompositorVsyncScheduler.h
+++ b/gfx/layers/ipc/CompositorVsyncScheduler.h
@@ -144,16 +144,16 @@ private:
   uint32_t mNeedsComposite;
   int32_t mVsyncNotificationsSkipped;
   widget::CompositorWidget* mWidget;
   RefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
 
   mozilla::Monitor mCurrentCompositeTaskMonitor;
   RefPtr<CancelableRunnable> mCurrentCompositeTask;
 
-  mozilla::Monitor mCurrentVRListenerTaskMonitor;
-  RefPtr<Runnable> mCurrentVRListenerTask;
+  mozilla::Monitor mCurrentVRTaskMonitor;
+  RefPtr<Runnable> mCurrentVRTask;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_CompositorVsyncScheduler_h
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1165,17 +1165,16 @@ gfxPlatform::InitLayersIPC()
 
   if (XRE_IsParentProcess() || recordreplay::IsRecordingOrReplaying()) {
     if (!gfxConfig::IsEnabled(Feature::GPU_PROCESS) && gfxVars::UseWebRender()) {
       wr::RenderThread::Start();
       image::ImageMemoryReporter::InitForWebRender();
     }
 
     layers::CompositorThreadHolder::Start();
-    gfx::VRListenerThreadHolder::Start();
   }
 }
 
 /* static */ void
 gfxPlatform::ShutdownLayersIPC()
 {
     if (!sLayersIPCIsUp) {
       return;
@@ -1194,17 +1193,16 @@ gfxPlatform::ShutdownLayersIPC()
           layers::PaintThread::Shutdown();
         }
     } else if (XRE_IsParentProcess()) {
         gfx::VRManagerChild::ShutDown();
         layers::CompositorManagerChild::Shutdown();
         layers::ImageBridgeChild::ShutDown();
         // This has to happen after shutting down the child protocols.
         layers::CompositorThreadHolder::Shutdown();
-        gfx::VRListenerThreadHolder::Shutdown();
         image::ImageMemoryReporter::ShutdownForWebRender();
         // There is a case that RenderThread exists when gfxVars::UseWebRender() is false.
         // This could happen when WebRender was fallbacked to compositor.
         if (wr::RenderThread::Get()) {
           wr::RenderThread::ShutDown();
 
           Preferences::UnregisterCallback(WebRenderDebugPrefChangeCallback, WR_DEBUG_PREF);
         }
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -3,16 +3,17 @@
 /* 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 "VRDisplayHost.h"
 #include "gfxPrefs.h"
 #include "gfxVR.h"
 #include "ipc/VRLayerParent.h"
+#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/dom/GamepadBinding.h" // For GamepadMappingType
 #include "VRThread.h"
 
 #if defined(XP_WIN)
 
 #include <d3d11.h>
 #include "gfxWindowsPlatform.h"
@@ -337,17 +338,17 @@ VRDisplayHost::SubmitFrameInternal(const
    * the render loop, if we don't successfully call it, we shouldn't trigger
    * NotifyVRVsync immediately, as it will run unbounded.
    * If NotifyVRVsync is not called here due to SubmitFrame failing, the
    * fallback "watchdog" code in VRDisplayHost::NotifyVSync() will cause
    * frames to continue at a lower refresh rate until frame submission
    * succeeds again.
    */
   VRManager* vm = VRManager::Get();
-  MessageLoop* loop = VRListenerThreadHolder::Loop();
+  MessageLoop* loop = CompositorThreadHolder::Loop();
 
   loop->PostTask(NewRunnableMethod<const uint32_t>(
     "gfx::VRManager::NotifyVRVsync",
     vm, &VRManager::NotifyVRVsync, mDisplayInfo.mDisplayID
   ));
 #endif
 }
 
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -258,82 +258,63 @@ VRManager::UpdateRequestedDevices()
  * VRManager::NotifyVsync must be called on every 2d vsync (usually at 60hz).
  * This must be called even when no WebVR site is active.
  * If we don't have a 2d display attached to the system, we can call this
  * at the VR display's native refresh rate.
  **/
 void
 VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp)
 {
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
-
   for (const auto& manager : mManagers) {
     manager->NotifyVSync();
   }
 }
 
 void
 VRManager::StartTasks()
 {
-  MOZ_ASSERT(VRListenerThread());
   if (!mTaskTimer) {
     mTaskInterval = GetOptimalTaskInterval();
     mTaskTimer = NS_NewTimer();
-    mTaskTimer->SetTarget(VRListenerThreadHolder::Loop()->SerialEventTarget());
+    mTaskTimer->SetTarget(CompositorThreadHolder::Loop()->SerialEventTarget());
     mTaskTimer->InitWithNamedFuncCallback(
       TaskTimerCallback,
       this,
       mTaskInterval,
       nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP,
       "VRManager::TaskTimerCallback");
   }
 }
 
 void
 VRManager::StopTasks()
 {
   if (mTaskTimer) {
-    MOZ_ASSERT(VRListenerThread());
     mTaskTimer->Cancel();
     mTaskTimer = nullptr;
   }
 }
 
 /*static*/ void
-VRManager::StopVRListenerThreadTasks()
-{
-  if (sVRManagerSingleton) {
-    sVRManagerSingleton->StopTasks();
-  }
-}
-
-/*static*/ void
 VRManager::TaskTimerCallback(nsITimer* aTimer, void* aClosure)
 {
   /**
    * It is safe to use the pointer passed in aClosure to reference the
    * VRManager object as the timer is canceled in VRManager::Destroy.
    * VRManager::Destroy set mInitialized to false, which is asserted
    * in the VRManager destructor, guaranteeing that this functions
    * runs if and only if the VRManager object is valid.
    */
   VRManager* self = static_cast<VRManager*>(aClosure);
   self->RunTasks();
 }
 
 void
 VRManager::RunTasks()
 {
-  // During shutdown, this might be called outside of the
-  // VR Listener Thread; however, we no longer need to
-  // execute any tasks during this time.
-  if (!VRListenerThreadHolder::IsInVRListenerThread()) {
-    return;
-  }
-
   // Will be called once every 1ms when a VR presentation
   // is active or once per vsync when a VR presentation is
   // not active.
 
   TimeStamp now = TimeStamp::Now();
   double lastTickMs = mAccumulator100ms;
   double deltaTime = 0.0f;
   if (!mLastTickTime.IsNull()) {
@@ -392,18 +373,16 @@ VRManager::GetOptimalTaskInterval()
  * called more than once within 1ms.
  * When VR is not active, this will be
  * called once per VSync if it wasn't
  * called within the last 1ms.
  */
 void
 VRManager::Run1msTasks(double aDeltaTime)
 {
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
-
   for (const auto& manager : mManagers) {
     manager->Run1msTasks(aDeltaTime);
   }
 
   for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) {
     gfx::VRDisplayHost* display = iter.UserData();
     display->Run1msTasks(aDeltaTime);
   }
@@ -414,18 +393,16 @@ VRManager::Run1msTasks(double aDeltaTime
  * called more than once within 10ms.
  * When VR is not active, this will be
  * called once per VSync if it wasn't
  * called within the last 10ms.
  */
 void
 VRManager::Run10msTasks()
 {
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
-
   UpdateRequestedDevices();
 
   for (const auto& manager : mManagers) {
     manager->Run10msTasks();
   }
 
   for (auto iter = mVRDisplays.Iter(); !iter.Done(); iter.Next()) {
     gfx::VRDisplayHost* display = iter.UserData();
@@ -438,18 +415,16 @@ VRManager::Run10msTasks()
  * called more than once within 100ms.
  * When VR is not active, this will be
  * called once per VSync if it wasn't
  * called within the last 100ms.
  */
 void
 VRManager::Run100msTasks()
 {
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
-
   // We must continually refresh the VR display enumeration to check
   // for events that we must fire such as Window.onvrdisplayconnect
   // Note that enumeration itself may activate display hardware, such
   // as Oculus, so we only do this when we know we are displaying content
   // that is looking for VR displays.
   RefreshVRDisplays();
 
   // Update state and enumeration of VR controllers
@@ -490,17 +465,16 @@ VRManager::CheckForInactiveTimeout()
       mLastDisplayEnumerationTime = TimeStamp();
     }
   }
 }
 
 void
 VRManager::NotifyVRVsync(const uint32_t& aDisplayID)
 {
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
   for (const auto& manager: mManagers) {
     if (manager->GetIsPresenting()) {
       manager->HandleInput();
     }
   }
 
   RefPtr<VRDisplayHost> display = GetDisplay(aDisplayID);
   if (display) {
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -58,17 +58,16 @@ public:
 
   void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
                      double aIntensity, double aDuration, const VRManagerPromise& aPromise);
   void StopVibrateHaptic(uint32_t aControllerIdx);
   void NotifyVibrateHapticCompleted(const VRManagerPromise& aPromise);
   void DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameResultInfo& aResult);
   void StartVRNavigation(const uint32_t& aDisplayID);
   void StopVRNavigation(const uint32_t& aDisplayID, const TimeDuration& aTimeout);
-  static void StopVRListenerThreadTasks();
 
 protected:
   VRManager();
   ~VRManager();
 
 private:
 
   void Init();
--- a/gfx/vr/VRThread.cpp
+++ b/gfx/vr/VRThread.cpp
@@ -9,151 +9,35 @@
 #include "nsThreadManager.h"
 #include "nsThreadUtils.h"
 #include "VRManager.h"
 
 namespace mozilla {
 
 namespace gfx {
 
-static StaticRefPtr<VRListenerThreadHolder> sVRListenerThreadHolder;
-static bool sFinishedVRListenerShutDown = true;
 static const uint32_t kDefaultThreadLifeTime = 60; // in 60 seconds.
 static const uint32_t kDelayPostTaskTime = 20000; // in 20000 ms.
 
-VRListenerThreadHolder* GetVRListenerThreadHolder()
-{
-  return sVRListenerThreadHolder;
-}
-
-base::Thread*
-VRListenerThread()
-{
-  return sVRListenerThreadHolder
-         ? sVRListenerThreadHolder->GetThread()
-         : nullptr;
-}
-
-/* static */ MessageLoop*
-VRListenerThreadHolder::Loop()
-{
-  return VRListenerThread() ? VRListenerThread()->message_loop() : nullptr;
-}
-
-VRListenerThreadHolder*
-VRListenerThreadHolder::GetSingleton()
-{
-  return sVRListenerThreadHolder;
-}
-
-VRListenerThreadHolder::VRListenerThreadHolder()
- : mThread(CreateThread())
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
-VRListenerThreadHolder::~VRListenerThreadHolder()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mThread) {
-    DestroyThread(mThread);
-  }
-}
-
-/* static */ void
-VRListenerThreadHolder::DestroyThread(base::Thread* aThread)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!sVRListenerThreadHolder,
-             "We shouldn't be destroying the VR listener thread yet.");
-  delete aThread;
-  sFinishedVRListenerShutDown = true;
-}
-
-/* static */ base::Thread*
-VRListenerThreadHolder::CreateThread()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!sVRListenerThreadHolder, "The VR listener thread has already been started!");
-
-  base::Thread* vrThread = new base::Thread("VRListener");
-  base::Thread::Options options;
-  /* Timeout values are powers-of-two to enable us get better data.
-     128ms is chosen for transient hangs because 8Hz should be the minimally
-     acceptable goal for Compositor responsiveness (normal goal is 60Hz). */
-  options.transient_hang_timeout = 128; // milliseconds
-  /* 2048ms is chosen for permanent hangs because it's longer than most
-   * Compositor hangs seen in the wild, but is short enough to not miss getting
-   * native hang stacks. */
-  options.permanent_hang_timeout = 2048; // milliseconds
-
-  if (!vrThread->StartWithOptions(options)) {
-    delete vrThread;
-    return nullptr;
-  }
-
-  return vrThread;
-}
-
-void
-VRListenerThreadHolder::Start()
-{
-  MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread!");
-  MOZ_ASSERT(!sVRListenerThreadHolder, "The VR listener thread has already been started!");
-  sFinishedVRListenerShutDown = false;
-  sVRListenerThreadHolder = new VRListenerThreadHolder();
-
-  if (!sVRListenerThreadHolder->GetThread()) {
-    MOZ_ASSERT(false, "VR listener thread not started.");
-    sVRListenerThreadHolder = nullptr;
-  }
-}
-
-void
-VRListenerThreadHolder::Shutdown()
-{
-  MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread!");
-  VRManager::StopVRListenerThreadTasks();
-
-  if (!sVRListenerThreadHolder) {
-    // We've already shutdown or never started.
-    return;
-  }
-
-  sVRListenerThreadHolder = nullptr;
-
-  SpinEventLoopUntil([&]() { return sFinishedVRListenerShutDown; });
-}
-
-/* static */ bool
-VRListenerThreadHolder::IsInVRListenerThread()
-{
-  return VRListenerThread() &&
-		 VRListenerThread()->thread_id() == PlatformThread::CurrentId();
-}
-
 VRThread::VRThread(const nsCString& aName)
  : mThread(nullptr)
  , mLifeTime(kDefaultThreadLifeTime)
  , mStarted(false)
 {
   mName = aName;
 }
 
 VRThread::~VRThread()
 {
   Shutdown();
 }
 
 void
 VRThread::Start()
 {
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
-
   if (!mThread) {
     nsresult rv = NS_NewNamedThread(mName, getter_AddRefs(mThread));
     MOZ_ASSERT(mThread);
 
     if (NS_FAILED(rv)) {
       MOZ_ASSERT(false, "Failed to create a vr thread.");
     }
     RefPtr<Runnable> runnable =
--- a/gfx/vr/VRThread.h
+++ b/gfx/vr/VRThread.h
@@ -8,49 +8,16 @@
  #define GFX_VR_THREAD_H
 
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "base/thread.h"                // for Thread
 
 namespace mozilla {
 namespace gfx {
 
-class VRListenerThreadHolder final
-{
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRListenerThreadHolder)
-
-public:
-  VRListenerThreadHolder();
-
-  base::Thread* GetThread() const {
-    return mThread;
-  }
-
-  static VRListenerThreadHolder* GetSingleton();
-
-  static bool IsActive() {
-    return GetSingleton() && Loop();
-  }
-
-  static void Start();
-  static void Shutdown();
-  static MessageLoop* Loop();
-  static bool IsInVRListenerThread();
-
-private:
-  ~VRListenerThreadHolder();
-
-  base::Thread* const mThread;
-
-  static base::Thread* CreateThread();
-  static void DestroyThread(base::Thread* aThread);
-};
-
-base::Thread* VRListenerThread();
-
 class VRThread final
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRThread)
 
 public:
   explicit VRThread(const nsCString& aName);
 
   void Start();
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -1487,17 +1487,17 @@ VRControllerOculus::VibrateHapticComplet
       printf_stderr("%s Haptics skipped.\n",
                     GamepadHandValues::strings[uint32_t(GetHand())].value);
     }
   }
 
   VRManager *vm = VRManager::Get();
   MOZ_ASSERT(vm);
 
-  VRListenerThreadHolder::Loop()->PostTask(
+  CompositorThreadHolder::Loop()->PostTask(
     NewRunnableMethod<StoreCopyPassByConstLRef<VRManagerPromise>>(
       "VRManager::NotifyVibrateHapticCompleted",
       vm, &VRManager::NotifyVibrateHapticCompleted, aPromise));
 }
 
 void
 VRControllerOculus::VibrateHaptic(ovrSession aSession,
                                   uint32_t aHapticIndex,
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -67,17 +67,16 @@ private:
   RefPtr<VRThread> mSubmitThread;
   // The timestamp of the last time Oculus set ShouldQuit to true.
   TimeStamp mLastShouldQuit;
   // The timestamp of the last ending presentation
   TimeStamp mLastPresentationEnd;
   VRTelemetry mTelemetry;
   bool mRequestPresentation;
   bool mRequestTracking;
-  bool mTracking;
   bool mDrawBlack;
   bool mIsConnected;
   bool mIsMounted;
 
   ~VROculusSession();
   void Uninitialize();
   bool Initialize(ovrInitFlags aFlags);
   bool LoadOvrLib();
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -541,17 +541,17 @@ VRControllerOpenVR::UpdateVibrateHaptic(
     VibrateHapticComplete(aPromise);
   }
 }
 
 void
 VRControllerOpenVR::VibrateHapticComplete(const VRManagerPromise& aPromise)
 {
   VRManager *vm = VRManager::Get();
-  VRListenerThreadHolder::Loop()->PostTask(
+  CompositorThreadHolder::Loop()->PostTask(
     NewRunnableMethod<StoreCopyPassByConstLRef<VRManagerPromise>>(
       "VRManager::NotifyVibrateHapticCompleted",
       vm, &VRManager::NotifyVibrateHapticCompleted, aPromise));
 }
 
 void
 VRControllerOpenVR::VibrateHaptic(::vr::IVRSystem* aVRSystem,
                                   uint32_t aHapticIndex,
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -9,16 +9,17 @@
 #include "TextureD3D11.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #elif defined(XP_MACOSX)
 #include "mozilla/gfx/MacIOSurface.h"
 #endif
 
 #include "mozilla/Base64.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
+#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
 #include "gfxPrefs.h"
 #include "gfxUtils.h"
 #include "gfxVRPuppet.h"
 #include "VRManager.h"
 #include "VRThread.h"
 
 #include "mozilla/dom/GamepadEventTypes.h"
 #include "mozilla/dom/GamepadBinding.h"
@@ -389,17 +390,17 @@ VRDisplayPuppet::SubmitFrame(ID3D11Textu
       }
       mContext->Unmap(mappedTexture, 0);
 
       if (Base64Encode(rawString, result.mBase64Image) != NS_OK) {
         MOZ_ASSERT(false, "Failed to encode base64 images.");
       }
       // Dispatch the base64 encoded string to the DOM side. Then, it will be decoded
       // and convert to a PNG image there.
-      MessageLoop* loop = VRListenerThreadHolder::Loop();
+      MessageLoop* loop = CompositorThreadHolder::Loop();
       loop->PostTask(NewRunnableMethod<const uint32_t, VRSubmitFrameResultInfo>(
         "VRManager::DispatchSubmitFrameResult",
         vm, &VRManager::DispatchSubmitFrameResult, mDisplayInfo.mDisplayID, result
       ));
       break;
     }
     case 2:
     {
@@ -535,17 +536,17 @@ VRDisplayPuppet::SubmitFrame(MacIOSurfac
         }
         dataSurf->Unmap();
 
         if (Base64Encode(rawString, result.mBase64Image) != NS_OK) {
           MOZ_ASSERT(false, "Failed to encode base64 images.");
         }
         // Dispatch the base64 encoded string to the DOM side. Then, it will be decoded
         // and convert to a PNG image there.
-        MessageLoop* loop = VRListenerThreadHolder::Loop();
+        MessageLoop* loop = CompositorThreadHolder::Loop();
         loop->PostTask(NewRunnableMethod<const uint32_t, VRSubmitFrameResultInfo>(
           "VRManager::DispatchSubmitFrameResult",
           vm, &VRManager::DispatchSubmitFrameResult, mDisplayInfo.mDisplayID, result
         ));
       }
       break;
     }
     case 2:
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -113,17 +113,17 @@ VRManagerChild::ReinitForContent(Endpoin
 VRManagerChild::InitSameProcess()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!sVRManagerChildSingleton);
 
   sVRManagerChildSingleton = new VRManagerChild();
   sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
   sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
-                                 VRListenerThreadHolder::Loop(),
+                                 CompositorThreadHolder::Loop(),
                                  mozilla::ipc::ChildSide);
 }
 
 /* static */ void
 VRManagerChild::InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!sVRManagerChildSingleton);
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -80,17 +80,17 @@ VRManagerParent::UnregisterFromManager()
   VRManager* vm = VRManager::Get();
   vm->RemoveVRManagerParent(this);
   mVRManagerHolder = nullptr;
 }
 
 /* static */ bool
 VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint)
 {
-  MessageLoop* loop = VRListenerThreadHolder::Loop();
+  MessageLoop* loop = CompositorThreadHolder::Loop();
 
   RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), true);
   loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
     "gfx::VRManagerParent::Bind",
     vmp,
     &VRManagerParent::Bind,
     std::move(aEndpoint)));
 
@@ -104,78 +104,75 @@ VRManagerParent::Bind(Endpoint<PVRManage
     return;
   }
   mSelfRef = this;
 
   RegisterWithManager();
 }
 
 /*static*/ void
-VRManagerParent::RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager)
+VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
 {
   aVRManager->RegisterWithManager();
 }
 
 /*static*/ VRManagerParent*
 VRManagerParent::CreateSameProcess()
 {
-  MessageLoop* loop = VRListenerThreadHolder::Loop();
+  MessageLoop* loop = CompositorThreadHolder::Loop();
   RefPtr<VRManagerParent> vmp = new VRManagerParent(base::GetCurrentProcId(), false);
-  vmp->mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
+  vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
   vmp->mSelfRef = vmp;
-  loop->PostTask(NewRunnableFunction("RegisterVRManagerInVRListenerThreadRunnable",
-                                     RegisterVRManagerInVRListenerThread, vmp.get()));
+  loop->PostTask(NewRunnableFunction("RegisterVRManagerIncompositorThreadRunnable",
+                                     RegisterVRManagerInCompositorThread, vmp.get()));
   return vmp.get();
 }
 
 bool
 VRManagerParent::CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint)
 {
-  MessageLoop* loop = VRListenerThreadHolder::Loop();
+  MessageLoop* loop = CompositorThreadHolder::Loop();
 
   RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), false);
-  vmp->mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
+  vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
   vmp->mSelfRef = vmp;
   loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
     "gfx::VRManagerParent::Bind",
     vmp,
     &VRManagerParent::Bind,
     std::move(aEndpoint)));
   return true;
 }
 
 void
 VRManagerParent::DeferredDestroy()
 {
-  mVRListenerThreadHolder = nullptr;
+  mCompositorThreadHolder = nullptr;
   mSelfRef = nullptr;
 }
 
 void
 VRManagerParent::ActorDestroy(ActorDestroyReason why)
 {
   UnregisterFromManager();
   MessageLoop::current()->PostTask(
     NewRunnableMethod("gfx::VRManagerParent::DeferredDestroy",
                       this,
                       &VRManagerParent::DeferredDestroy));
 }
 
 void
 VRManagerParent::OnChannelConnected(int32_t aPid)
 {
-  mVRListenerThreadHolder = VRListenerThreadHolder::GetSingleton();
+  mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
 }
 
 mozilla::ipc::IPCResult
 VRManagerParent::RecvRefreshDisplays()
 {
-  // TODO: Bug 1406327, Launch VR listener thread here.
-  MOZ_ASSERT(VRListenerThreadHolder::IsInVRListenerThread());
-
   // This is called to refresh the VR Displays for Navigator.GetVRDevices().
   // We must pass "true" to VRManager::RefreshVRDisplays()
   // to ensure that the promise returned by Navigator.GetVRDevices
   // can resolve even if there are no changes to the VR Displays.
   VRManager* vm = VRManager::Get();
   vm->RefreshVRDisplays(true);
 
   return IPC_OK();
@@ -271,17 +268,17 @@ mozilla::ipc::IPCResult
 VRManagerParent::RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID)
 {
   uint32_t controllerIdx = 1; // ID's are 1 based
   nsTArray<VRControllerInfo> controllerInfoArray;
   impl::VRControllerPuppet* controllerPuppet = nullptr;
   VRManager* vm = VRManager::Get();
 
   /**
-   * The controller is created asynchronously in the VRListener thread.
+   * The controller is created asynchronously.
    * We will wait up to kMaxControllerCreationTime milliseconds before
    * assuming that the controller will never be created.
    */
   const int kMaxControllerCreationTime = 1000;
   /**
    * min(100ms, kVRIdleTaskInterval) * 10 as a very
    * pessimistic estimation of the maximum duration possible.
    * It's possible that the IPC message queues could be so busy
--- a/gfx/vr/ipc/VRManagerParent.h
+++ b/gfx/vr/ipc/VRManagerParent.h
@@ -2,23 +2,23 @@
 /* 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 MOZILLA_GFX_VR_VRMANAGERPARENT_H
 #define MOZILLA_GFX_VR_VRMANAGERPARENT_H
 
+#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
 #include "mozilla/layers/CompositableTransactionParent.h"  // need?
 #include "mozilla/gfx/PVRManagerParent.h" // for PVRManagerParent
 #include "mozilla/gfx/PVRLayerParent.h"   // for PVRLayerParent
 #include "mozilla/ipc/ProtocolUtils.h"    // for IToplevelProtocol
 #include "mozilla/TimeStamp.h"            // for TimeStamp
 #include "gfxVR.h"                        // for VRFieldOfView
-#include "VRThread.h"                     // for VRListenerThreadHolder
 
 namespace mozilla {
 using namespace layers;
 namespace gfx {
 
 class VRManager;
 
 namespace impl {
@@ -76,25 +76,26 @@ protected:
   virtual mozilla::ipc::IPCResult RecvStartVRNavigation(const uint32_t& aDeviceID) override;
   virtual mozilla::ipc::IPCResult RecvStopVRNavigation(const uint32_t& aDeviceID, const TimeDuration& aTimeout) override;
 private:
   void RegisterWithManager();
   void UnregisterFromManager();
 
   void Bind(Endpoint<PVRManagerParent>&& aEndpoint);
 
-  static void RegisterVRManagerInVRListenerThread(VRManagerParent* aVRManager);
+  static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager);
 
   void DeferredDestroy();
   already_AddRefed<impl::VRControllerPuppet> GetControllerPuppet(uint32_t aDeviceID);
 
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   RefPtr<VRManagerParent> mSelfRef;
-  RefPtr<VRListenerThreadHolder> mVRListenerThreadHolder;
+  // Keep the compositor thread alive, until we have destroyed ourselves.
+  RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
 
   // Keep the VRManager alive, until we have destroyed ourselves.
   RefPtr<VRManager> mVRManagerHolder;
   nsRefPtrHashtable<nsUint32HashKey, impl::VRControllerPuppet> mVRControllerTests;
   uint32_t mControllerTestID;
   bool mHaveEventListener;
   bool mHaveControllerListener;
   bool mIsContentChild;