Monado OpenXR Runtime
Loading...
Searching...
No Matches
context.hpp
Go to the documentation of this file.
1// Copyright 2023, Shawn Wallace
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief SteamVR driver context - implements xrt_tracking_origin and IVRDriverContext.
6 * @author Shawn Wallace <yungwallace@live.com>
7 * @ingroup drv_steamvr_lh
8 */
9
10#pragma once
11
12#include <condition_variable>
13#include <unordered_map>
14#include <memory>
15#include <optional>
16#include <chrono>
17#include <deque>
18#include <mutex>
19#include <thread>
20
21#include "openvr_driver.h"
22
23#include "settings.hpp"
24#include "resources.hpp"
25#include "iobuffer.hpp"
26#include "driver_manager.hpp"
27#include "server.hpp"
28#include "blockqueue.hpp"
29#include "paths.hpp"
30
31#include "xrt/xrt_tracking.h"
32
33struct xrt_input;
34class Device;
36class Context final : public xrt_tracking_origin,
37 public vr::IVRDriverContext,
38 public vr::IVRServerDriverHost,
39 public vr::IVRDriverInput,
40 public vr::IVRProperties,
41 public vr::IVRDriverLog,
42 public std::enable_shared_from_this<Context>
43
44{
45public:
46 Settings settings;
47
49 {
50 vr::VRInputComponentHandle_t x;
51 vr::VRInputComponentHandle_t y;
52 };
53
54 /*
55 * All data types are are locked by `devices_mut`
56 */
57 struct
58 {
59 vr::VRInputComponentHandle_t next_handle;
60 std::unordered_map<vr::VRInputComponentHandle_t, xrt_input *> handle_to_input;
61 std::unordered_map<vr::VRInputComponentHandle_t, Vec2Components *> vec2_inputs;
62 std::unordered_map<xrt_input *, std::unique_ptr<Vec2Components>> vec2_input_to_components;
63 std::unordered_map<vr::VRInputComponentHandle_t, ControllerDevice *> skeleton_to_controller;
64 } input;
65
66private:
67 Resources resources;
68 IOBuffer iobuf;
69 DriverManager man;
70 Server server;
71 BlockQueue blockqueue;
72 Paths paths;
73
74 uint64_t current_frame{0};
75
76 struct Event
77 {
78 std::chrono::steady_clock::time_point insert_time;
79 vr::VREvent_t inner;
80 };
81 std::deque<Event> events;
82 size_t events_tail{0};
83 std::mutex event_queue_mut;
84 std::condition_variable event_popped;
85
86 Device *
87 prop_container_to_device(vr::PropertyContainerHandle_t handle);
88
89 vr::EVRInputError
90 create_component_common(vr::PropertyContainerHandle_t container,
91 const char *name,
92 vr::VRInputComponentHandle_t *handle);
93
94 xrt_input *
95 update_component_common_locked(vr::VRInputComponentHandle_t handle,
96 double offset,
97 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now());
98
99 bool
100 setup_hmd(const char *serial, vr::ITrackedDeviceServerDriver *driver);
101
102 bool
103 setup_controller(const char *serial, vr::ITrackedDeviceServerDriver *driver);
104 std::vector<vr::IServerTrackedDeviceProvider *> providers;
105
106public:
107 Context(const std::string &steam_install, const std::string &steamvr_install, u_logging_level level);
108
109 // These are owned by Monado, context is destroyed when these are destroyed
110 std::mutex devices_mut{};
111 class HmdDevice *hmd{nullptr};
112 class ControllerDevice *controller[16]{nullptr};
113
114 bool in_setup{true};
115 const u_logging_level log_level;
116
117 void
118 wait_for_discover();
119
120 void
121 extend_discover();
122
123private:
124 std::condition_variable discover_cv;
125 std::chrono::steady_clock::time_point discover_end_time;
126 //! Devices published to `hmd`/`controller` that the driver has not finished activating (`devices_mut`).
127 size_t devices_in_setup{0};
128 std::atomic<bool> frame_thread_run;
129 std::binary_semaphore frame_thread_event{0};
130 std::thread frame_thread;
131
132 void
133 add_event_locked(vr::VREvent_t event);
134
135public:
136 ~Context();
137
138 [[nodiscard]] static std::shared_ptr<Context>
139 create(const std::string &steam_install,
140 const std::string &steamvr_install,
141 std::vector<vr::IServerTrackedDeviceProvider *> providers);
142
143 size_t
144 add_haptic_event(vr::VREvent_HapticVibration_t event, size_t old_event_index);
145
146 void
147 add_vendor_event(vr::EVREventType type, const vr::VREvent_Data_t &data = {})
148 {
149 VendorSpecificEvent(0, type, data, 0);
150 }
151
152 void
153 Log(const char *pchLogMessage) override;
154
155 /***** IVRDriverContext methods *****/
156
157 void *
158 GetGenericInterface(const char *pchInterfaceVersion, vr::EVRInitError *peError) override;
159
160 vr::DriverHandle_t
161 GetDriverHandle() override;
162
163 /***** IVRServerDriverHost methods *****/
164 bool
165 TrackedDeviceAdded(const char *pchDeviceSerialNumber,
166 vr::ETrackedDeviceClass eDeviceClass,
167 vr::ITrackedDeviceServerDriver *pDriver) override;
168
169 void
170 TrackedDevicePoseUpdated(uint32_t unWhichDevice,
171 const vr::DriverPose_t &newPose,
172 uint32_t unPoseStructSize) override;
173
174 void
175 VsyncEvent(double vsyncTimeOffsetSeconds) override;
176
177 void
178 VendorSpecificEvent(uint32_t unWhichDevice,
179 vr::EVREventType eventType,
180 const vr::VREvent_Data_t &eventData,
181 double eventTimeOffset) override;
182
183 bool
184 IsExiting() override;
185
186 bool
187 PollNextEvent(vr::VREvent_t *pEvent, uint32_t uncbVREvent) override;
188
189 void
190 GetRawTrackedDevicePoses(float fPredictedSecondsFromNow,
191 vr::TrackedDevicePose_t *pTrackedDevicePoseArray,
192 uint32_t unTrackedDevicePoseArrayCount) override;
193
194 void
195 RequestRestart(const char *pchLocalizedReason,
196 const char *pchExecutableToStart,
197 const char *pchArguments,
198 const char *pchWorkingDirectory) override;
199
200 uint32_t
201 GetFrameTimings(vr::Compositor_FrameTiming *pTiming, uint32_t nFrames) override;
202
203 void
204 SetDisplayEyeToHead(uint32_t unWhichDevice,
205 const vr::HmdMatrix34_t &eyeToHeadLeft,
206 const vr::HmdMatrix34_t &eyeToHeadRight) override;
207
208 void
209 SetDisplayProjectionRaw(uint32_t unWhichDevice,
210 const vr::HmdRect2_t &eyeLeft,
211 const vr::HmdRect2_t &eyeRight) override;
212
213 void
214 SetRecommendedRenderTargetSize(uint32_t unWhichDevice, uint32_t nWidth, uint32_t nHeight) override;
215
216 /***** IVRDriverInput methods *****/
217
218 vr::EVRInputError
219 CreateBooleanComponent(vr::PropertyContainerHandle_t ulContainer,
220 const char *pchName,
221 vr::VRInputComponentHandle_t *pHandle) override;
222
223 vr::EVRInputError
224 UpdateBooleanComponent(vr::VRInputComponentHandle_t ulComponent, bool bNewValue, double fTimeOffset) override;
225
226 vr::EVRInputError
227 CreateScalarComponent(vr::PropertyContainerHandle_t ulContainer,
228 const char *pchName,
229 vr::VRInputComponentHandle_t *pHandle,
230 vr::EVRScalarType eType,
231 vr::EVRScalarUnits eUnits) override;
232
233 vr::EVRInputError
234 UpdateScalarComponent(vr::VRInputComponentHandle_t ulComponent, float fNewValue, double fTimeOffset) override;
235
236 vr::EVRInputError
237 CreateHapticComponent(vr::PropertyContainerHandle_t ulContainer,
238 const char *pchName,
239 vr::VRInputComponentHandle_t *pHandle) override;
240
241 vr::EVRInputError
242 CreateSkeletonComponent(vr::PropertyContainerHandle_t ulContainer,
243 const char *pchName,
244 const char *pchSkeletonPath,
245 const char *pchBasePosePath,
246 vr::EVRSkeletalTrackingLevel eSkeletalTrackingLevel,
247 const vr::VRBoneTransform_t *pGripLimitTransforms,
248 uint32_t unGripLimitTransformCount,
249 vr::VRInputComponentHandle_t *pHandle) override;
250
251 vr::EVRInputError
252 UpdateSkeletonComponent(vr::VRInputComponentHandle_t ulComponent,
253 vr::EVRSkeletalMotionRange eMotionRange,
254 const vr::VRBoneTransform_t *pTransforms,
255 uint32_t unTransformCount) override;
256
257 vr::EVRInputError
258 CreatePoseComponent(vr::PropertyContainerHandle_t ulContainer,
259 const char *pchName,
260 vr::VRInputComponentHandle_t *pHandle) override;
261
262 vr::EVRInputError
263 UpdatePoseComponent(vr::VRInputComponentHandle_t ulComponent,
264 const vr::HmdMatrix34_t *pMatPoseOffset,
265 double fTimeOffset) override;
266
267 vr::EVRInputError
268 CreateEyeTrackingComponent(vr::PropertyContainerHandle_t ulContainer,
269 const char *pchName,
270 vr::VRInputComponentHandle_t *pHandle) override;
271
272 vr::EVRInputError
273 UpdateEyeTrackingComponent(vr::VRInputComponentHandle_t ulComponent,
274 const vr::VREyeTrackingData_t *pEyeTrackingData,
275 double fTimeOffset) override;
276
277 /***** IVRProperties methods *****/
278
279 vr::ETrackedPropertyError
280 ReadPropertyBatch(vr::PropertyContainerHandle_t ulContainerHandle,
281 vr::PropertyRead_t *pBatch,
282 uint32_t unBatchEntryCount) override;
283
284 vr::ETrackedPropertyError
285 WritePropertyBatch(vr::PropertyContainerHandle_t ulContainerHandle,
286 vr::PropertyWrite_t *pBatch,
287 uint32_t unBatchEntryCount) override;
288
289 const char *
290 GetPropErrorNameFromEnum(vr::ETrackedPropertyError error) override;
291
292 vr::PropertyContainerHandle_t
293 TrackedDeviceToPropertyContainer(vr::TrackedDeviceIndex_t nDevice) override;
294};
OpenVR IVRBlockQueue interface header.
This interface is missing in the C++ header but present in the C one, and the lighthouse driver requi...
Definition blockqueue.hpp:43
Definition context.hpp:44
static std::shared_ptr< Context > create(const std::string &steam_install, const std::string &steamvr_install, std::vector< vr::IServerTrackedDeviceProvider * > providers)
Since only the devices will live after our get_devices function is called, we make our Context a shar...
Definition steamvr_lh.cpp:144
Definition device.hpp:234
Definition device.hpp:68
Definition driver_manager.hpp:15
Definition device.hpp:154
Definition iobuffer.hpp:15
This interface is missing in the C++ header but present in the C one, and the lighthouse driver requi...
Definition paths.hpp:21
Definition resources.hpp:16
An internal interface utilized by the lighthouse driver.
Definition server.hpp:15
Definition settings.hpp:18
OpenVR IVRDriverManager interface header.
u_logging_level
Logging level enum.
Definition u_logging.h:45
OpenVR IVRIOBuffer interface header.
OpenVR IVRPaths interface header.
OpenVR IVRResources interface header.
OpenVR IVRServer internal interface header.
OpenVR IVRSettings interface header.
Definition context.hpp:49
A single named input, that sits on a xrt_device.
Definition xrt_device.h:226
A tracking system or device origin.
Definition xrt_tracking.h:83
enum xrt_tracking_type type
What can the state tracker expect from this tracking system.
Definition xrt_tracking.h:88
Header defining the tracking system integration in Monado.