1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef GFX_VR_OPENVR_H
8 #define GFX_VR_OPENVR_H
9 
10 #include "nsTArray.h"
11 #include "nsIScreen.h"
12 #include "nsCOMPtr.h"
13 #include "mozilla/RefPtr.h"
14 
15 #include "mozilla/gfx/2D.h"
16 #include "mozilla/EnumeratedArray.h"
17 
18 #include "openvr.h"
19 #include "gfxVR.h"
20 #include "VRDisplayHost.h"
21 
22 #if defined(XP_MACOSX)
23 class MacIOSurface;
24 #endif
25 namespace mozilla {
26 namespace gfx {
27 class VRThread;
28 
29 namespace impl {
30 
31 class VRDisplayOpenVR : public VRDisplayHost {
32  public:
33   void ZeroSensor() override;
34   bool GetIsHmdPresent();
35 
36  protected:
37   virtual VRHMDSensorState GetSensorState() override;
38   virtual void StartPresentation() override;
39   virtual void StopPresentation() override;
40 #if defined(XP_WIN)
41   virtual bool SubmitFrame(ID3D11Texture2D* aSource, const IntSize& aSize,
42                            const gfx::Rect& aLeftEyeRect,
43                            const gfx::Rect& aRightEyeRect) override;
44 #elif defined(XP_MACOSX)
45   virtual bool SubmitFrame(MacIOSurface* aMacIOSurface, const IntSize& aSize,
46                            const gfx::Rect& aLeftEyeRect,
47                            const gfx::Rect& aRightEyeRect) override;
48 #endif
49 
50  public:
51   explicit VRDisplayOpenVR(::vr::IVRSystem* aVRSystem,
52                            ::vr::IVRChaperone* aVRChaperone,
53                            ::vr::IVRCompositor* aVRCompositor);
54   void Refresh();
55 
56  protected:
57   virtual ~VRDisplayOpenVR();
58   void Destroy();
59 
60   // not owned by us; global from OpenVR
61   ::vr::IVRSystem* mVRSystem;
62   ::vr::IVRChaperone* mVRChaperone;
63   ::vr::IVRCompositor* mVRCompositor;
64 
65   VRTelemetry mTelemetry;
66   bool mIsPresenting;
67   bool mIsHmdPresent;
68 
69   void UpdateStageParameters();
70   void UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms = nullptr);
71   bool SubmitFrame(void* aTextureHandle, ::vr::ETextureType aTextureType,
72                    const IntSize& aSize, const gfx::Rect& aLeftEyeRect,
73                    const gfx::Rect& aRightEyeRect);
74 };
75 
76 class VRControllerOpenVR : public VRControllerHost {
77  public:
78   explicit VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplayID,
79                               uint32_t aNumButtons, uint32_t aNumTriggers,
80                               uint32_t aNumAxes, const nsCString& aId);
81   void SetTrackedIndex(uint32_t aTrackedIndex);
82   uint32_t GetTrackedIndex();
83   float GetAxisMove(uint32_t aAxis);
84   void SetAxisMove(uint32_t aAxis, float aValue);
85   void SetTrigger(uint32_t aButton, float aValue);
86   float GetTrigger(uint32_t aButton);
87   void SetHand(dom::GamepadHand aHand);
88   void VibrateHaptic(::vr::IVRSystem* aVRSystem, uint32_t aHapticIndex,
89                      double aIntensity, double aDuration,
90                      const VRManagerPromise& aPromise);
91   void StopVibrateHaptic();
92   void ShutdownVibrateHapticThread();
93 
94  protected:
95   virtual ~VRControllerOpenVR();
96 
97  private:
98   void UpdateVibrateHaptic(::vr::IVRSystem* aVRSystem, uint32_t aHapticIndex,
99                            double aIntensity, double aDuration,
100                            uint64_t aVibrateIndex,
101                            const VRManagerPromise& aPromise);
102   void VibrateHapticComplete(const VRManagerPromise& aPromise);
103 
104   // The index of tracked devices from ::vr::IVRSystem.
105   uint32_t mTrackedIndex;
106   nsTArray<float> mTrigger;
107   nsTArray<float> mAxisMove;
108   RefPtr<VRThread> mVibrateThread;
109   Atomic<bool> mIsVibrateStopped;
110 };
111 
112 }  // namespace impl
113 
114 class VRSystemManagerOpenVR : public VRSystemManager {
115  public:
116   static already_AddRefed<VRSystemManagerOpenVR> Create();
117 
118   virtual void Destroy() override;
119   virtual void Shutdown() override;
120   virtual void NotifyVSync() override;
121   virtual void Enumerate() override;
122   virtual bool ShouldInhibitEnumeration() override;
123   virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override;
124   virtual bool GetIsPresenting() override;
125   virtual void HandleInput() override;
126   virtual void GetControllers(
127       nsTArray<RefPtr<VRControllerHost>>& aControllerResult) override;
128   virtual void ScanForControllers() override;
129   virtual void RemoveControllers() override;
130   virtual void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
131                              double aIntensity, double aDuration,
132                              const VRManagerPromise& aPromise) override;
133   virtual void StopVibrateHaptic(uint32_t aControllerIdx) override;
134 
135  protected:
136   VRSystemManagerOpenVR();
137 
138  private:
139   void HandleButtonPress(uint32_t aControllerIdx, uint32_t aButton,
140                          uint64_t aButtonMask, uint64_t aButtonPressed,
141                          uint64_t aButtonTouched);
142   void HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
143                           uint32_t aTrigger, float aValue);
144   void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis, float aValue);
145   void HandlePoseTracking(uint32_t aControllerIdx,
146                           const dom::GamepadPoseState& aPose,
147                           VRControllerHost* aController);
148   dom::GamepadHand GetGamepadHandFromControllerRole(
149       ::vr::ETrackedControllerRole aRole);
150   void GetControllerDeviceId(::vr::ETrackedDeviceClass aDeviceType,
151                              ::vr::TrackedDeviceIndex_t aDeviceIndex,
152                              nsCString& aId);
153 
154   // there can only be one
155   RefPtr<impl::VRDisplayOpenVR> mOpenVRHMD;
156   nsTArray<RefPtr<impl::VRControllerOpenVR>> mOpenVRController;
157   ::vr::IVRSystem* mVRSystem;
158   bool mIsWindowsMR;
159 };
160 
161 }  // namespace gfx
162 }  // namespace mozilla
163 
164 #endif /* GFX_VR_OPENVR_H */
165