Bug 1299928 - Part 5: Handle gamepad events in Vsync time; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Fri, 07 Oct 2016 17:00:45 +0800
changeset 425942 9f7ce0e6804a02aeef9b6f7147c701af499cc652
parent 425941 6a21b94110bc0a6debc3bb13d88461611e2b74a4
child 425943 8a352c8a5dabc6a737c5007910ceb4fc3417f4be
push id32537
push userbmo:dmu@mozilla.com
push dateMon, 17 Oct 2016 10:06:25 +0000
reviewerskip
bugs1299928
milestone52.0a1
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) {