Bug 1305889 - Part 3: Enumerate Oculus Touch Controllers; r=kip
authorDaosheng Mu <daoshengmu@gmail.com>
Mon, 06 Feb 2017 16:13:33 +0800
changeset 341028 7ec2ddd042e65ee9e48445fd0bd342b86922192e
parent 341027 595bbe23999f3d935c17fe77e50313ff1bb3c149
child 341029 b4b02af50299e17ac657fff1c9399420c30885f0
push id36985
push userdmu@mozilla.com
push dateTue, 07 Feb 2017 01:55:16 +0000
treeherderautoland@7ec2ddd042e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip
bugs1305889
milestone54.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 1305889 - Part 3: Enumerate Oculus Touch Controllers; r=kip MozReview-Commit-ID: Ep57r4hxrRt
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
gfx/vr/gfxVROpenVR.cpp
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -116,16 +116,33 @@ static pfn_ovr_GetMirrorTextureBufferGL 
 #else
 #define BUILD_BITS 32
 #endif
 
 #define OVR_PRODUCT_VERSION 1
 #define OVR_MAJOR_VERSION   1
 #define OVR_MINOR_VERSION   10
 
+static const ovrButton kOculusTouchLButton[] = {
+  ovrButton_X,
+  ovrButton_Y,
+  ovrButton_LThumb
+};
+
+static const ovrButton kOculusTouchRButton[] = {
+  ovrButton_A,
+  ovrButton_B,
+  ovrButton_RThumb
+};
+
+static const uint32_t kNumOculusButton = sizeof(kOculusTouchLButton) /
+                                         sizeof(ovrButton);
+static const uint32_t kNumOculusAxis = 2;
+static const uint32_t kNumOculusHaptcs = 0;  // TODO: Bug 1305892
+
 static bool
 InitializeOculusCAPI()
 {
   static PRLibrary *ovrlib = nullptr;
 
   if (!ovrlib) {
     nsTArray<nsCString> libSearchPaths;
     nsCString libName;
@@ -620,142 +637,16 @@ VRDisplayOculus::StopPresentation()
   ovr_SubmitFrame(mSession, 0, nullptr, nullptr, 0);
 
   if (mTextureSet) {
     ovr_DestroyTextureSwapChain(mSession, mTextureSet);
     mTextureSet = nullptr;
   }
 }
 
-/*static*/ already_AddRefed<VRSystemManagerOculus>
-VRSystemManagerOculus::Create()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculusEnabled())
-  {
-    return nullptr;
-  }
-
-  if (!InitializeOculusCAPI()) {
-    return nullptr;
-  }
-
-  RefPtr<VRSystemManagerOculus> manager = new VRSystemManagerOculus();
-  return manager.forget();
-}
-
-bool
-VRSystemManagerOculus::Init()
-{
-  if (!mOculusInitialized) {
-    nsIThread* thread = nullptr;
-    NS_GetCurrentThread(&thread);
-    mOculusThread = already_AddRefed<nsIThread>(thread);
-
-    ovrInitParams params;
-    memset(&params, 0, sizeof(params));
-    params.Flags = ovrInit_RequestVersion;
-    params.RequestedMinorVersion = OVR_MINOR_VERSION;
-    params.LogCallback = nullptr;
-    params.ConnectionTimeoutMS = 0;
-
-    ovrResult orv = ovr_Initialize(&params);
-
-    if (orv == ovrSuccess) {
-      mOculusInitialized = true;
-    }
-  }
-
-  return mOculusInitialized;
-}
-
-void
-VRSystemManagerOculus::Destroy()
-{
-  if (mOculusInitialized) {
-    MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread);
-    mOculusThread = nullptr;
-
-    mHMDInfo = nullptr;
-
-    ovr_Shutdown();
-    mOculusInitialized = false;
-  }
-}
-
-void
-VRSystemManagerOculus::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
-{
-  if (!mOculusInitialized) {
-    return;
-  }
-
-  // ovr_Create can be slow when no HMD is present and we wish
-  // to keep the same oculus session when possible, so we detect
-  // presence of an HMD with ovr_GetHmdDesc before calling ovr_Create
-  ovrHmdDesc desc = ovr_GetHmdDesc(NULL);
-  if (desc.Type == ovrHmd_None) {
-    // No HMD connected.
-    mHMDInfo = nullptr;
-  } else if (mHMDInfo == nullptr) {
-    // HMD Detected
-    ovrSession session;
-    ovrGraphicsLuid luid;
-    ovrResult orv = ovr_Create(&session, &luid);
-    if (orv == ovrSuccess) {
-      mSession = session;
-      mHMDInfo = new VRDisplayOculus(session);
-    }
-  }
-
-  if (mHMDInfo) {
-    aHMDResult.AppendElement(mHMDInfo);
-  }
-}
-
-void
-VRSystemManagerOculus::HandleInput()
-{
-}
-
-void
-VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
-                                         uint64_t aButtonPressed)
-{
-}
-
-void
-VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
-                                      float aValue)
-{
-}
-
-void
-VRSystemManagerOculus::HandlePoseTracking(uint32_t aControllerIdx,
-                                          const GamepadPoseState& aPose,
-                                          VRControllerHost* aController)
-{
-}
-
-void
-VRSystemManagerOculus::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
-{
-}
-
-void
-VRSystemManagerOculus::ScanForControllers()
-{
-}
-
-void
-VRSystemManagerOculus::RemoveControllers()
-{
-}
-
 already_AddRefed<CompositingRenderTargetD3D11>
 VRDisplayOculus::GetNextRenderTarget()
 {
   int currentRenderTarget = 0;
   DebugOnly<ovrResult> orv = ovr_GetTextureSwapChainCurrentIndex(mSession, mTextureSet, &currentRenderTarget);
   MOZ_ASSERT(orv == ovrSuccess, "ovr_GetTextureSwapChainCurrentIndex failed.");
 
   mRenderTargets[currentRenderTarget]->ClearOnBind();
@@ -935,10 +826,237 @@ VRDisplayOculus::SubmitFrame(TextureSour
 }
 
 void
 VRDisplayOculus::NotifyVSync()
 {
   ovrSessionStatus sessionStatus;
   ovrResult ovr = ovr_GetSessionStatus(mSession, &sessionStatus);
   mDisplayInfo.mIsConnected = (ovr == ovrSuccess && sessionStatus.HmdPresent);
-  mDisplayInfo.mIsMounted = (ovr == ovrSuccess && sessionStatus.HmdMounted);
+}
+
+VRControllerOculus::VRControllerOculus()
+  : VRControllerHost(VRDeviceType::Oculus)
+{
+  MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
+  mControllerInfo.mControllerName.AssignLiteral("Oculus Touch Controller");
+  mControllerInfo.mMappingType = GamepadMappingType::_empty;
+  mControllerInfo.mHand = GamepadHand::_empty;
+  mControllerInfo.mNumButtons = kNumOculusButton;
+  mControllerInfo.mNumAxes = kNumOculusAxis;
+}
+
+VRControllerOculus::~VRControllerOculus()
+{
+  MOZ_COUNT_DTOR_INHERITED(VRControllerOculus, VRControllerHost);
+}
+
+/*static*/ already_AddRefed<VRSystemManagerOculus>
+VRSystemManagerOculus::Create()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculusEnabled())
+  {
+    return nullptr;
+  }
+
+  if (!InitializeOculusCAPI()) {
+    return nullptr;
+  }
+
+  RefPtr<VRSystemManagerOculus> manager = new VRSystemManagerOculus();
+  return manager.forget();
+}
+
+bool
+VRSystemManagerOculus::Init()
+{
+  if (!mOculusInitialized) {
+    nsIThread* thread = nullptr;
+    NS_GetCurrentThread(&thread);
+    mOculusThread = already_AddRefed<nsIThread>(thread);
+
+    ovrInitParams params;
+    memset(&params, 0, sizeof(params));
+    params.Flags = ovrInit_RequestVersion;
+    params.RequestedMinorVersion = OVR_MINOR_VERSION;
+    params.LogCallback = nullptr;
+    params.ConnectionTimeoutMS = 0;
+
+    ovrResult orv = ovr_Initialize(&params);
+
+    if (orv == ovrSuccess) {
+      mOculusInitialized = true;
+    }
+  }
+
+  return mOculusInitialized;
+}
+
+void
+VRSystemManagerOculus::Destroy()
+{
+  if (mOculusInitialized) {
+    MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread);
+    mOculusThread = nullptr;
+    mSession = nullptr;
+    mHMDInfo = nullptr;
+
+    ovr_Shutdown();
+    mOculusInitialized = false;
+  }
+}
+
+void
+VRSystemManagerOculus::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
+{
+  if (!mOculusInitialized) {
+    return;
+  }
+
+  // ovr_Create can be slow when no HMD is present and we wish
+  // to keep the same oculus session when possible, so we detect
+  // presence of an HMD with ovr_GetHmdDesc before calling ovr_Create
+  ovrHmdDesc desc = ovr_GetHmdDesc(NULL);
+  if (desc.Type == ovrHmd_None) {
+    // No HMD connected.
+    mHMDInfo = nullptr;
+  } else if (mHMDInfo == nullptr) {
+    // HMD Detected
+    ovrSession session;
+    ovrGraphicsLuid luid;
+    ovrResult orv = ovr_Create(&session, &luid);
+    if (orv == ovrSuccess) {
+      mSession = session;
+      mHMDInfo = new VRDisplayOculus(session);
+    }
+  }
+
+  if (mHMDInfo) {
+    aHMDResult.AppendElement(mHMDInfo);
+  }
 }
+
+void
+VRSystemManagerOculus::HandleInput()
+{
+   // mSession is available after VRDisplay is created
+  // at GetHMDs().
+  if (!mSession) {
+    return;
+  }
+
+  RefPtr<impl::VRControllerOculus> controller;
+  ovrInputState inputState;
+  bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
+                                         &inputState) == ovrSuccess;
+
+  if (!hasInputState) {
+    return;
+  }
+
+  for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
+    controller = mOculusController[i];
+    HandleButtonPress(controller->GetIndex(), inputState.Buttons);
+  }
+}
+
+void
+VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
+                                         uint64_t aButtonPressed)
+{
+  // TODO: Bug 1305890
+}
+
+void
+VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+                                      float aValue)
+{
+  // TODO: Bug 1305890
+}
+
+void
+VRSystemManagerOculus::HandlePoseTracking(uint32_t aControllerIdx,
+                                          const GamepadPoseState& aPose,
+                                          VRControllerHost* aController)
+{
+  // TODO: Bug 1305891
+}
+
+void
+VRSystemManagerOculus::GetControllers(nsTArray<RefPtr<VRControllerHost>>&
+                                      aControllerResult)
+{
+  if (!mOculusInitialized) {
+    return;
+  }
+
+  aControllerResult.Clear();
+  for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
+    aControllerResult.AppendElement(mOculusController[i]);
+  }
+}
+
+void
+VRSystemManagerOculus::ScanForControllers()
+{
+  // mSession is available after VRDisplay is created
+  // at GetHMDs().
+  if (!mSession) {
+    return;
+  }
+
+  ovrInputState inputState;
+  bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
+                                         &inputState) == ovrSuccess;
+  ovrControllerType activeControllerArray[2];
+  uint32_t newControllerCount = 0;
+
+  if (inputState.ControllerType & ovrControllerType_LTouch) {
+    activeControllerArray[newControllerCount] = ovrControllerType_LTouch;
+    ++newControllerCount;
+  }
+
+  if (inputState.ControllerType & ovrControllerType_RTouch) {
+    activeControllerArray[newControllerCount] = ovrControllerType_RTouch;
+    ++newControllerCount;
+  }
+
+  if (newControllerCount != mControllerCount) {
+    // controller count is changed, removing the existing gamepads first.
+    for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
+      RemoveGamepad(mOculusController[i]->GetIndex());
+    }
+
+    mControllerCount = 0;
+    mOculusController.Clear();
+
+    // Re-adding controllers to VRControllerManager.
+    for (uint32_t i = 0; i < newControllerCount; ++i) {
+      GamepadHand hand;
+
+      switch (activeControllerArray[i]) {
+        case ovrControllerType::ovrControllerType_LTouch:
+          hand = GamepadHand::Left;
+          break;
+        case ovrControllerType::ovrControllerType_RTouch:
+          hand = GamepadHand::Right;
+          break;
+      }
+      RefPtr<VRControllerOculus> oculusController = new VRControllerOculus();
+      oculusController->SetIndex(mControllerCount);
+      oculusController->SetHand(hand);
+      mOculusController.AppendElement(oculusController);
+
+      // Not already present, add it.
+      AddGamepad(oculusController->GetControllerInfo());
+      ++mControllerCount;
+    }
+  }
+}
+
+void
+VRSystemManagerOculus::RemoveControllers()
+{
+  mOculusController.Clear();
+  mControllerCount = 0;
+}
\ No newline at end of file
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -81,16 +81,25 @@ protected:
   bool UpdateConstantBuffers();
 
   struct Vertex
   {
     float position[2];
   };
 };
 
+class VRControllerOculus : public VRControllerHost
+{
+public:
+  explicit VRControllerOculus();
+
+protected:
+  virtual ~VRControllerOculus();
+};
+
 } // namespace impl
 
 class VRSystemManagerOculus : public VRSystemManager
 {
 public:
   static already_AddRefed<VRSystemManagerOculus> Create();
   virtual bool Init() override;
   virtual void Destroy() override;
@@ -98,29 +107,30 @@ public:
   virtual void HandleInput() override;
   virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>&
                               aControllerResult) override;
   virtual void ScanForControllers() override;
   virtual void RemoveControllers() override;
 
 protected:
   VRSystemManagerOculus()
-    : mOculusInitialized(false)
+    : mSession(nullptr), mOculusInitialized(false)
   { }
 
 private:
   virtual void HandleButtonPress(uint32_t aControllerIdx,
                                  uint64_t aButtonPressed) override;
   virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
                               float aValue) override;
   virtual void HandlePoseTracking(uint32_t aControllerIdx,
                                   const dom::GamepadPoseState& aPose,
                                   VRControllerHost* aController) override;
 
   RefPtr<impl::VRDisplayOculus> mHMDInfo;
+  nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
   RefPtr<nsIThread> mOculusThread;
   ovrSession mSession;
   bool mOculusInitialized;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -419,17 +419,17 @@ VRDisplayOpenVR::NotifyVSync()
   // Make sure we respond to OpenVR events even when not presenting
   PollEvents();
 }
 
 VRControllerOpenVR::VRControllerOpenVR()
   : VRControllerHost(VRDeviceType::OpenVR)
 {
   MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
-  mControllerInfo.mControllerName.AssignLiteral("OpenVR Gamepad");
+  mControllerInfo.mControllerName.AssignLiteral("OpenVR Controller");
   mControllerInfo.mMappingType = GamepadMappingType::_empty;
   mControllerInfo.mHand = GamepadHand::_empty;
   mControllerInfo.mNumButtons = gNumOpenVRButtonMask;
   mControllerInfo.mNumAxes = gNumOpenVRAxis;
 }
 
 VRControllerOpenVR::~VRControllerOpenVR()
 {