Bug 1299928 - Part 5: Handle gamepad events in Vsync time; r=kip
authorDaosheng Mu <daoshengmu@gmail.com>
Fri, 07 Oct 2016 17:00:45 +0800
changeset 318207 298aafb4c28cce1a45f7b0736215281b3678f58d
parent 318206 c56ec883e2f395ecdfc63437dd89d07c7b846ccd
child 318208 99eb47ffccb916c6c2ef4cef5fcb4c71dae0616c
push id33213
push usercbook@mozilla.com
push dateMon, 17 Oct 2016 10:20:25 +0000
treeherderautoland@99eb47ffccb9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip
bugs1299928
milestone52.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 1299928 - Part 5: Handle gamepad events in Vsync time; r=kip MozReview-Commit-ID: Ndt3zajkli
gfx/vr/VRManager.cpp
gfx/vr/VRManager.h
gfx/vr/gfxVROpenVR.cpp
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -180,22 +180,26 @@ VRManager::NotifyVsync(const TimeStamp& 
     // 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.
     if (mLastRefreshTime.IsNull()) {
       // This is the first vsync, must refresh VR displays
       RefreshVRDisplays();
+      RefreshVRControllers();
+      mLastRefreshTime = TimeStamp::Now();
     } else {
       // We don't have to do this every frame, so check if we
       // have refreshed recently.
       TimeDuration duration = TimeStamp::Now() - mLastRefreshTime;
       if (duration.ToMilliseconds() > kVRDisplayRefreshMaxDuration) {
         RefreshVRDisplays();
+        RefreshVRControllers();
+        mLastRefreshTime = TimeStamp::Now();
       }
     }
   }
 }
 
 void
 VRManager::NotifyVRVsync(const uint32_t& aDisplayID)
 {
@@ -247,18 +251,16 @@ VRManager::RefreshVRDisplays(bool aMustD
     for (const auto& display: displays) {
       mVRDisplays.Put(display->GetDisplayInfo().GetDisplayID(), display);
     }
   }
 
   if (displayInfoChanged || aMustDispatch) {
     DispatchVRDisplayInfoUpdate();
   }
-
-  mLastRefreshTime = TimeStamp::Now();
 }
 
 void
 VRManager::DispatchVRDisplayInfoUpdate()
 {
   nsTArray<VRDisplayInfo> update;
   GetVRDisplayInfo(update);
 
@@ -321,16 +323,54 @@ VRManager::GetVRControllerInfo(nsTArray<
   aControllerInfo.Clear();
   for (auto iter = mVRControllers.Iter(); !iter.Done(); iter.Next()) {
     gfx::VRControllerHost* controller = iter.UserData();
     aControllerInfo.AppendElement(VRControllerInfo(controller->GetControllerInfo()));
   }
 }
 
 void
+VRManager::RefreshVRControllers()
+{
+  nsTArray<RefPtr<gfx::VRControllerHost>> controllers;
+
+  for (uint32_t i = 0; i < mControllerManagers.Length()
+      && controllers.Length() == 0; ++i) {
+    mControllerManagers[i]->GetControllers(controllers);
+  }
+
+  bool controllerInfoChanged = false;
+
+  if (controllers.Length() != mVRControllers.Count()) {
+    // Catch cases where VR controllers has been removed
+    controllerInfoChanged = true;
+  }
+
+  for (const auto& controller : controllers) {
+    if (!GetController(controller->GetControllerInfo().GetControllerID())) {
+      // This is a new controller
+      controllerInfoChanged = true;
+      break;
+    }
+  }
+
+  if (controllerInfoChanged) {
+    mVRControllers.Clear();
+    for (const auto& controller : controllers) {
+      mVRControllers.Put(controller->GetControllerInfo().GetControllerID(),
+                         controller);
+    }
+  }
+
+  for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) {
+    mControllerManagers[i]->HandleInput();
+  }
+}
+
+void
 VRManager::ScanForDevices()
 {
   for (uint32_t i = 0; i < mControllerManagers.Length(); ++i) {
     mControllerManagers[i]->ScanForDevices();
   }
 }
 
 template<class T>
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -55,16 +55,17 @@ protected:
 
 private:
   RefPtr<layers::TextureHost> mLastFrame;
 
   void Init();
   void Destroy();
 
   void DispatchVRDisplayInfoUpdate();
+  void RefreshVRControllers();
 
   typedef nsTHashtable<nsRefPtrHashKey<VRManagerParent>> VRManagerParentSet;
   VRManagerParentSet mVRManagerParents;
 
   typedef nsTArray<RefPtr<VRDisplayManager>> VRDisplayManagerArray;
   VRDisplayManagerArray mManagers;
 
   typedef nsTArray<RefPtr<VRControllerManager>> VRControllerManagerArray;
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -506,16 +506,45 @@ VRControllerManagerOpenVR::Init()
 void
 VRControllerManagerOpenVR::Destroy()
 {
   mOpenVRController.Clear();
   mOpenVRInstalled = false;
 }
 
 void
+VRControllerManagerOpenVR::HandleInput()
+{
+  MOZ_ASSERT(mVRSystem);
+
+  // Process OpenVR controller state
+  for (vr::TrackedDeviceIndex_t trackedDevice = 0;
+       trackedDevice < vr::k_unMaxTrackedDeviceCount; trackedDevice++ ) {
+    vr::VRControllerState_t state;
+
+    if (mVRSystem->GetTrackedDeviceClass(trackedDevice)
+        != vr::TrackedDeviceClass_Controller) {
+      continue;
+    }
+
+    if (mVRSystem->GetControllerState(trackedDevice, &state)) {
+      if (state.ulButtonPressed) {
+        // TODO: For Bug 1299929 after landing, convert the button mask to an ID button
+        // NewButtonEvent(1,
+        //                0,
+        //                0,
+        //                true);
+      }
+    }
+  }
+
+  return;
+}
+
+void
 VRControllerManagerOpenVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
 {
   if (!mOpenVRInstalled) {
     return;
   }
 
   aControllerResult.Clear();
   for (uint32_t i = 0; i < mOpenVRController.Length(); ++i) {