Bug 1336003 - Oculus Touch button touched support; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 13 Apr 2017 14:06:07 +0800
changeset 561987 8e041a1efc3001f49a6a7e8084daf27d6a73b4ad
parent 561690 aca6b2a5a2ab3338436c9e819dc2244a022b6425
child 624150 95f431aef06e4e26c8353cce8678fd1ae18b64e9
push id53932
push userbmo:dmu@mozilla.com
push dateThu, 13 Apr 2017 10:54:41 +0000
reviewerskip
bugs1336003
milestone55.0a1
Bug 1336003 - Oculus Touch button touched support; r?kip MozReview-Commit-ID: 95RViosiVXO
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -1192,60 +1192,69 @@ VRSystemManagerOculus::HandleInput()
   for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
     controller = mOculusController[i];
     const GamepadHand hand = controller->GetHand();
     const uint32_t handIdx = static_cast<uint32_t>(hand) - 1;
     uint32_t buttonIdx = 0;
 
     switch (hand) {
       case dom::GamepadHand::Left:
-        HandleButtonPress(i, buttonIdx, ovrButton_LThumb, inputState.Buttons);
+        HandleButtonPress(i, buttonIdx, ovrButton_LThumb, inputState.Buttons,
+                          inputState.Touches);
         ++buttonIdx;
-        HandleTriggerPress(i, buttonIdx, inputState.IndexTrigger[handIdx]);
+        HandleIndexTriggerPress(i, buttonIdx, ovrTouch_LIndexTrigger,
+                                inputState.IndexTrigger[handIdx], inputState.Touches);
         ++buttonIdx;
-        HandleTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
+        HandleHandTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
         ++buttonIdx;
-        HandleButtonPress(i, buttonIdx, ovrButton_X, inputState.Buttons);
+        HandleButtonPress(i, buttonIdx, ovrButton_X, inputState.Buttons,
+                          inputState.Touches);
         ++buttonIdx;
-        HandleButtonPress(i, buttonIdx, ovrButton_Y, inputState.Buttons);
+        HandleButtonPress(i, buttonIdx, ovrButton_Y, inputState.Buttons,
+                          inputState.Touches);
         ++buttonIdx;
         HandleTouchEvent(i, buttonIdx, ovrTouch_LThumbRest, inputState.Touches);
         ++buttonIdx;
         break;
       case dom::GamepadHand::Right:
-        HandleButtonPress(i, buttonIdx, ovrButton_RThumb, inputState.Buttons);
+        HandleButtonPress(i, buttonIdx, ovrButton_RThumb, inputState.Buttons,
+                          inputState.Touches);
         ++buttonIdx;
-        HandleTriggerPress(i, buttonIdx, inputState.IndexTrigger[handIdx]);
+        HandleIndexTriggerPress(i, buttonIdx, ovrTouch_RIndexTrigger,
+                                inputState.IndexTrigger[handIdx], inputState.Touches);
         ++buttonIdx;
-        HandleTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
+        HandleHandTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
         ++buttonIdx;
-        HandleButtonPress(i, buttonIdx, ovrButton_A, inputState.Buttons);
+        HandleButtonPress(i, buttonIdx, ovrButton_A, inputState.Buttons,
+                          inputState.Touches);
         ++buttonIdx;
-        HandleButtonPress(i, buttonIdx, ovrButton_B, inputState.Buttons);
+        HandleButtonPress(i, buttonIdx, ovrButton_B, inputState.Buttons,
+                          inputState.Touches);
         ++buttonIdx;
         HandleTouchEvent(i, buttonIdx, ovrTouch_RThumbRest, inputState.Touches);
         ++buttonIdx;
         break;
       default:
         MOZ_ASSERT(false);
         break;
     }
     controller->SetButtonPressed(inputState.Buttons);
+    controller->SetButtonTouched(inputState.Touches);
 
     axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickXAxis);
     HandleAxisMove(i, axis, inputState.Thumbstick[i].x);
 
     axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickYAxis);
     HandleAxisMove(i, axis, -inputState.Thumbstick[i].y);
 
     // Start to process pose
     ovrTrackingState state = ovr_GetTrackingState(mSession, 0.0, false);
+
     // HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch,
     // therefore, we can't get its state by the index of mOculusController.
-
     ovrPoseStatef& pose(state.HandPoses[handIdx]);
     GamepadPoseState poseState;
 
     if (state.HandStatusFlags[handIdx] & ovrStatus_OrientationTracked) {
       poseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
       poseState.orientation[0] = pose.ThePose.Orientation.x;
       poseState.orientation[1] = pose.ThePose.Orientation.y;
       poseState.orientation[2] = pose.ThePose.Orientation.z;
@@ -1279,68 +1288,86 @@ VRSystemManagerOculus::HandleInput()
     HandlePoseTracking(i, poseState, controller);
   }
 }
 
 void
 VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
                                          uint32_t aButton,
                                          uint64_t aButtonMask,
-                                         uint64_t aButtonPressed)
+                                         uint64_t aButtonPressed,
+                                         uint64_t aButtonTouched)
 {
   RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
   MOZ_ASSERT(controller);
-  const uint64_t diff = (controller->GetButtonPressed() ^ aButtonPressed);
+  const uint64_t pressedDiff = (controller->GetButtonPressed() ^ aButtonPressed);
+  const uint64_t touchedDiff = (controller->GetButtonTouched() ^ aButtonTouched);
+
+  if (!pressedDiff && !touchedDiff) {
+    return;
+  }
 
-  if (diff & aButtonMask) {
-    // TODO: Bug 1336003 for button touched support.
+  if (pressedDiff & aButtonMask ||
+      touchedDiff & aButtonMask) {
+    // diff & (aButtonPressed, aButtonTouched) would be true while a new button pressed or
+    // touched event, otherwise it is an old event and needs to notify
+    // the button has been released.
     NewButtonEvent(aControllerIdx, aButton, aButtonMask & aButtonPressed,
-                   aButtonMask & aButtonPressed,
+                   aButtonMask & aButtonTouched,
                    (aButtonMask & aButtonPressed) ? 1.0L : 0.0L);
   }
 }
 
 void
-VRSystemManagerOculus::HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
-                                          float aValue)
+VRSystemManagerOculus::HandleIndexTriggerPress(uint32_t aControllerIdx,
+                                               uint32_t aButton,
+                                               uint64_t aTouchMask,
+                                               float aValue,
+                                               uint64_t aButtonTouched)
 {
   RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
   MOZ_ASSERT(controller);
-  const uint32_t indexTrigger = static_cast<const uint32_t>
-                                (OculusLeftControllerButtonType::IndexTrigger);
-  const uint32_t handTrigger =  static_cast<const uint32_t>
-                                (OculusLeftControllerButtonType::HandTrigger);
-  float oldValue = 0.0f;
+  const uint64_t touchedDiff = (controller->GetButtonTouched() ^ aButtonTouched);
+  const float oldValue = controller->GetIndexTrigger();
 
   // Avoid sending duplicated events in IPC channels.
-  if (aButton == indexTrigger) {
-    oldValue = controller->GetIndexTrigger();
-    if (oldValue == aValue) {
-      return;
-    }
+  if ((oldValue != aValue) ||
+      (touchedDiff & aTouchMask)) {
+    NewButtonEvent(aControllerIdx, aButton, aValue > 0.1f, aTouchMask & aButtonTouched, aValue);
     controller->SetIndexTrigger(aValue);
-  } else if (aButton == handTrigger) {
-    oldValue = controller->GetHandTrigger();
-    if (oldValue == aValue) {
-      return;
-    }
+  }
+}
+
+void
+VRSystemManagerOculus::HandleHandTriggerPress(uint32_t aControllerIdx,
+                                              uint32_t aButton,
+                                              float aValue)
+{
+  RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
+  MOZ_ASSERT(controller);
+  const float oldValue = controller->GetHandTrigger();
+
+  // Avoid sending duplicated events in IPC channels.
+  if (oldValue != aValue) {
+    NewButtonEvent(aControllerIdx, aButton, aValue > 0.1f, aValue > 0.1f, aValue);
     controller->SetHandTrigger(aValue);
-  } else {
-    MOZ_ASSERT(false, "We only support indexTrigger and handTrigger in Oculus.");
   }
-
-  // TODO: Bug 1336003 for button touched support.
-  NewButtonEvent(aControllerIdx, aButton, aValue > 0.1f, aValue > 0.1f, aValue);
 }
 
 void
 VRSystemManagerOculus::HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
-                                        uint64_t aTouchMask, uint64_t aTouched)
+                                        uint64_t aTouchMask, uint64_t aButtonTouched)
 {
-  // TODO: Bug 1336003
+  RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
+  MOZ_ASSERT(controller);
+  const uint64_t touchedDiff = (controller->GetButtonTouched() ^ aButtonTouched);
+
+  if (touchedDiff & aTouchMask) {
+    NewButtonEvent(aControllerIdx, aButton, false, aTouchMask & aButtonTouched, 0.0f);
+  }
 }
 
 void
 VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
                                       float aValue)
 {
   RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
   MOZ_ASSERT(controller);
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -147,34 +147,37 @@ public:
   virtual void RemoveControllers() override;
   virtual void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
                              double aIntensity, double aDuration, uint32_t aPromiseID) override;
   virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
 
 protected:
   VRSystemManagerOculus()
     : mOvrLib(nullptr), mSession(nullptr), mStarted(false)
-  { }
+  {}
 
   bool Startup();
   bool LoadOvrLib();
   void UnloadOvrLib();
 
 private:
   void HandleButtonPress(uint32_t aControllerIdx,
                          uint32_t aButton,
                          uint64_t aButtonMask,
-                         uint64_t aButtonPressed);
+                         uint64_t aButtonPressed,
+                         uint64_t aButtonTouched);
   void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
                       float aValue);
   void HandlePoseTracking(uint32_t aControllerIdx,
                           const dom::GamepadPoseState& aPose,
                           VRControllerHost* aController);
-  void HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
-                          float aValue);
+  void HandleIndexTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
+                               uint64_t aTouchMask, float aValue, uint64_t aButtonTouched);
+  void HandleHandTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
+                              float aValue);
   void HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
                         uint64_t aTouchMask, uint64_t aTouched);
   PRLibrary* mOvrLib;
   RefPtr<impl::VRDisplayOculus> mHMDInfo;
   nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
   RefPtr<nsIThread> mOculusThread;
   ovrSession mSession;
   bool mStarted;