Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/vr/gfxVROSVR.cpp
Line
Count
Source (jump to first uncovered line)
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
#include <math.h>
8
9
#include "prenv.h"
10
#include "gfxPrefs.h"
11
#include "nsString.h"
12
#include "mozilla/Preferences.h"
13
#include "mozilla/SharedLibrary.h"
14
15
#include "mozilla/gfx/Quaternion.h"
16
17
#ifdef XP_WIN
18
#include "../layers/d3d11/CompositorD3D11.h"
19
#include "../layers/d3d11/TextureD3D11.h"
20
#endif
21
22
#include "gfxVROSVR.h"
23
24
#include "mozilla/dom/GamepadEventTypes.h"
25
#include "mozilla/dom/GamepadBinding.h"
26
27
#ifndef M_PI
28
#define M_PI 3.14159265358979323846
29
#endif
30
31
using namespace mozilla::layers;
32
using namespace mozilla::gfx;
33
using namespace mozilla::gfx::impl;
34
using namespace mozilla::dom;
35
36
namespace {
37
// need to typedef functions that will be used in the code below
38
extern "C" {
39
typedef OSVR_ClientContext (*pfn_osvrClientInit)(
40
  const char applicationIdentifier[], uint32_t flags);
41
typedef OSVR_ReturnCode (*pfn_osvrClientShutdown)(OSVR_ClientContext ctx);
42
typedef OSVR_ReturnCode (*pfn_osvrClientUpdate)(OSVR_ClientContext ctx);
43
typedef OSVR_ReturnCode (*pfn_osvrClientCheckStatus)(OSVR_ClientContext ctx);
44
typedef OSVR_ReturnCode (*pfn_osvrClientGetInterface)(
45
  OSVR_ClientContext ctx, const char path[], OSVR_ClientInterface* iface);
46
typedef OSVR_ReturnCode (*pfn_osvrClientFreeInterface)(
47
  OSVR_ClientContext ctx, OSVR_ClientInterface iface);
48
typedef OSVR_ReturnCode (*pfn_osvrGetOrientationState)(
49
  OSVR_ClientInterface iface, OSVR_TimeValue* timestamp,
50
  OSVR_OrientationState* state);
51
typedef OSVR_ReturnCode (*pfn_osvrGetPositionState)(OSVR_ClientInterface iface,
52
                                                    OSVR_TimeValue* timestamp,
53
                                                    OSVR_PositionState* state);
54
typedef OSVR_ReturnCode (*pfn_osvrClientGetDisplay)(OSVR_ClientContext ctx,
55
                                                    OSVR_DisplayConfig* disp);
56
typedef OSVR_ReturnCode (*pfn_osvrClientFreeDisplay)(OSVR_DisplayConfig disp);
57
typedef OSVR_ReturnCode (*pfn_osvrClientGetNumEyesForViewer)(
58
  OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount* eyes);
59
typedef OSVR_ReturnCode (*pfn_osvrClientGetViewerEyePose)(
60
  OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye,
61
  OSVR_Pose3* pose);
62
typedef OSVR_ReturnCode (*pfn_osvrClientGetDisplayDimensions)(
63
  OSVR_DisplayConfig disp, OSVR_DisplayInputCount displayInputIndex,
64
  OSVR_DisplayDimension* width, OSVR_DisplayDimension* height);
65
typedef OSVR_ReturnCode (
66
  *pfn_osvrClientGetViewerEyeSurfaceProjectionClippingPlanes)(
67
  OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye,
68
  OSVR_SurfaceCount surface, double* left, double* right, double* bottom,
69
  double* top);
70
typedef OSVR_ReturnCode (*pfn_osvrClientGetRelativeViewportForViewerEyeSurface)(
71
  OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye,
72
  OSVR_SurfaceCount surface, OSVR_ViewportDimension* left,
73
  OSVR_ViewportDimension* bottom, OSVR_ViewportDimension* width,
74
  OSVR_ViewportDimension* height);
75
typedef OSVR_ReturnCode (*pfn_osvrClientGetViewerEyeSurfaceProjectionMatrixf)(
76
  OSVR_DisplayConfig disp, OSVR_ViewerCount viewer, OSVR_EyeCount eye,
77
  OSVR_SurfaceCount surface, float near, float far,
78
  OSVR_MatrixConventions flags, float* matrix);
79
typedef OSVR_ReturnCode (*pfn_osvrClientCheckDisplayStartup)(
80
  OSVR_DisplayConfig disp);
81
typedef OSVR_ReturnCode (*pfn_osvrClientSetRoomRotationUsingHead)(
82
  OSVR_ClientContext ctx);
83
}
84
85
static pfn_osvrClientInit osvr_ClientInit = nullptr;
86
static pfn_osvrClientShutdown osvr_ClientShutdown = nullptr;
87
static pfn_osvrClientUpdate osvr_ClientUpdate = nullptr;
88
static pfn_osvrClientCheckStatus osvr_ClientCheckStatus = nullptr;
89
static pfn_osvrClientGetInterface osvr_ClientGetInterface = nullptr;
90
static pfn_osvrClientFreeInterface osvr_ClientFreeInterface = nullptr;
91
static pfn_osvrGetOrientationState osvr_GetOrientationState = nullptr;
92
static pfn_osvrGetPositionState osvr_GetPositionState = nullptr;
93
static pfn_osvrClientGetDisplay osvr_ClientGetDisplay = nullptr;
94
static pfn_osvrClientFreeDisplay osvr_ClientFreeDisplay = nullptr;
95
static pfn_osvrClientGetNumEyesForViewer osvr_ClientGetNumEyesForViewer =
96
  nullptr;
97
static pfn_osvrClientGetViewerEyePose osvr_ClientGetViewerEyePose = nullptr;
98
static pfn_osvrClientGetDisplayDimensions osvr_ClientGetDisplayDimensions =
99
  nullptr;
100
static pfn_osvrClientGetViewerEyeSurfaceProjectionClippingPlanes
101
  osvr_ClientGetViewerEyeSurfaceProjectionClippingPlanes = nullptr;
102
static pfn_osvrClientGetRelativeViewportForViewerEyeSurface
103
  osvr_ClientGetRelativeViewportForViewerEyeSurface = nullptr;
104
static pfn_osvrClientGetViewerEyeSurfaceProjectionMatrixf
105
  osvr_ClientGetViewerEyeSurfaceProjectionMatrixf = nullptr;
106
static pfn_osvrClientCheckDisplayStartup osvr_ClientCheckDisplayStartup =
107
  nullptr;
108
static pfn_osvrClientSetRoomRotationUsingHead
109
  osvr_ClientSetRoomRotationUsingHead = nullptr;
110
111
bool
112
LoadOSVRRuntime()
113
0
{
114
0
  static PRLibrary* osvrUtilLib = nullptr;
115
0
  static PRLibrary* osvrCommonLib = nullptr;
116
0
  static PRLibrary* osvrClientLib = nullptr;
117
0
  static PRLibrary* osvrClientKitLib = nullptr;
118
0
  //this looks up the path in the about:config setting, from greprefs.js or modules\libpref\init\all.js
119
0
  //we need all the libs to be valid
120
#ifdef XP_WIN
121
  constexpr static auto* pfnGetPathStringPref = mozilla::Preferences::GetString;
122
  nsAutoString osvrUtilPath, osvrCommonPath, osvrClientPath, osvrClientKitPath;
123
#else
124
  constexpr static auto* pfnGetPathStringPref = mozilla::Preferences::GetCString;
125
0
  nsAutoCString osvrUtilPath, osvrCommonPath, osvrClientPath, osvrClientKitPath;
126
0
#endif
127
0
  if (NS_FAILED(pfnGetPathStringPref("gfx.vr.osvr.utilLibPath",
128
0
                                     osvrUtilPath, PrefValueKind::User)) ||
129
0
      NS_FAILED(pfnGetPathStringPref("gfx.vr.osvr.commonLibPath",
130
0
                                     osvrCommonPath, PrefValueKind::User)) ||
131
0
      NS_FAILED(pfnGetPathStringPref("gfx.vr.osvr.clientLibPath",
132
0
                                     osvrClientPath, PrefValueKind::User)) ||
133
0
      NS_FAILED(pfnGetPathStringPref("gfx.vr.osvr.clientKitLibPath",
134
0
                                     osvrClientKitPath, PrefValueKind::User))) {
135
0
    return false;
136
0
  }
137
0
138
0
  osvrUtilLib = LoadLibraryWithFlags(osvrUtilPath.get());
139
0
  osvrCommonLib = LoadLibraryWithFlags(osvrCommonPath.get());
140
0
  osvrClientLib = LoadLibraryWithFlags(osvrClientPath.get());
141
0
  osvrClientKitLib = LoadLibraryWithFlags(osvrClientKitPath.get());
142
0
143
0
  if (!osvrUtilLib) {
144
0
    printf_stderr("[OSVR] Failed to load OSVR Util library!\n");
145
0
    return false;
146
0
  }
147
0
  if (!osvrCommonLib) {
148
0
    printf_stderr("[OSVR] Failed to load OSVR Common library!\n");
149
0
    return false;
150
0
  }
151
0
  if (!osvrClientLib) {
152
0
    printf_stderr("[OSVR] Failed to load OSVR Client library!\n");
153
0
    return false;
154
0
  }
155
0
  if (!osvrClientKitLib) {
156
0
    printf_stderr("[OSVR] Failed to load OSVR ClientKit library!\n");
157
0
    return false;
158
0
  }
159
0
160
0
// make sure all functions that we'll be using are available
161
0
#define REQUIRE_FUNCTION(_x)                                                   \
162
0
  do {                                                                         \
163
0
    *(void**) & osvr_##_x =                                                    \
164
0
      (void*)PR_FindSymbol(osvrClientKitLib, "osvr" #_x);                      \
165
0
    if (!osvr_##_x) {                                                          \
166
0
      printf_stderr("osvr" #_x " symbol missing\n");                           \
167
0
      goto fail;                                                               \
168
0
    }                                                                          \
169
0
  } while (0)
170
0
171
0
  REQUIRE_FUNCTION(ClientInit);
172
0
  REQUIRE_FUNCTION(ClientShutdown);
173
0
  REQUIRE_FUNCTION(ClientUpdate);
174
0
  REQUIRE_FUNCTION(ClientCheckStatus);
175
0
  REQUIRE_FUNCTION(ClientGetInterface);
176
0
  REQUIRE_FUNCTION(ClientFreeInterface);
177
0
  REQUIRE_FUNCTION(GetOrientationState);
178
0
  REQUIRE_FUNCTION(GetPositionState);
179
0
  REQUIRE_FUNCTION(ClientGetDisplay);
180
0
  REQUIRE_FUNCTION(ClientFreeDisplay);
181
0
  REQUIRE_FUNCTION(ClientGetNumEyesForViewer);
182
0
  REQUIRE_FUNCTION(ClientGetViewerEyePose);
183
0
  REQUIRE_FUNCTION(ClientGetDisplayDimensions);
184
0
  REQUIRE_FUNCTION(ClientGetViewerEyeSurfaceProjectionClippingPlanes);
185
0
  REQUIRE_FUNCTION(ClientGetRelativeViewportForViewerEyeSurface);
186
0
  REQUIRE_FUNCTION(ClientGetViewerEyeSurfaceProjectionMatrixf);
187
0
  REQUIRE_FUNCTION(ClientCheckDisplayStartup);
188
0
  REQUIRE_FUNCTION(ClientSetRoomRotationUsingHead);
189
0
190
0
#undef REQUIRE_FUNCTION
191
0
192
0
  return true;
193
0
194
0
fail:
195
0
  return false;
196
0
}
197
198
} // namespace
199
200
mozilla::gfx::VRFieldOfView
201
SetFromTanRadians(double left, double right, double bottom, double top)
202
0
{
203
0
  mozilla::gfx::VRFieldOfView fovInfo;
204
0
  fovInfo.leftDegrees = atan(left) * 180.0 / M_PI;
205
0
  fovInfo.rightDegrees = atan(right) * 180.0 / M_PI;
206
0
  fovInfo.upDegrees = atan(top) * 180.0 / M_PI;
207
0
  fovInfo.downDegrees = atan(bottom) * 180.0 / M_PI;
208
0
  return fovInfo;
209
0
}
210
211
VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
212
                         OSVR_ClientInterface* iface,
213
                         OSVR_DisplayConfig* display)
214
  : VRDisplayLocal(VRDeviceType::OSVR)
215
  , m_ctx(context)
216
  , m_iface(iface)
217
  , m_display(display)
218
0
{
219
0
220
0
  MOZ_COUNT_CTOR_INHERITED(VRDisplayOSVR, VRDisplayLocal);
221
0
222
0
  VRDisplayState& state = mDisplayInfo.mDisplayState;
223
0
  state.mIsConnected = true;
224
0
  strncpy(state.mDisplayName, "OSVR HMD", kVRDisplayNameMaxLen);
225
0
  state.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None;
226
0
  state.mCapabilityFlags =
227
0
    VRDisplayCapabilityFlags::Cap_Orientation | VRDisplayCapabilityFlags::Cap_Position;
228
0
229
0
  state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
230
0
  state.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
231
0
232
0
  // XXX OSVR display topology allows for more than one viewer
233
0
  // will assume only one viewer for now (most likely stay that way)
234
0
235
0
  OSVR_EyeCount numEyes;
236
0
  osvr_ClientGetNumEyesForViewer(*m_display, 0, &numEyes);
237
0
238
0
  for (uint8_t eye = 0; eye < numEyes; eye++) {
239
0
    double left, right, bottom, top;
240
0
    // XXX for now there is only one surface per eye
241
0
    osvr_ClientGetViewerEyeSurfaceProjectionClippingPlanes(
242
0
      *m_display, 0, eye, 0, &left, &right, &bottom, &top);
243
0
    state.mEyeFOV[eye] =
244
0
      SetFromTanRadians(-left, right, -bottom, top);
245
0
  }
246
0
247
0
  // XXX Assuming there is only one display input for now
248
0
  // however, it's possible to have more than one (dSight with 2 HDMI inputs)
249
0
  OSVR_DisplayDimension width, height;
250
0
  osvr_ClientGetDisplayDimensions(*m_display, 0, &width, &height);
251
0
252
0
253
0
  for (uint8_t eye = 0; eye < numEyes; eye++) {
254
0
255
0
    OSVR_ViewportDimension l, b, w, h;
256
0
    osvr_ClientGetRelativeViewportForViewerEyeSurface(*m_display, 0, eye, 0, &l,
257
0
                                                      &b, &w, &h);
258
0
    state.mEyeResolution.width = w;
259
0
    state.mEyeResolution.height = h;
260
0
    OSVR_Pose3 eyePose;
261
0
    // Viewer eye pose may not be immediately available, update client context until we get it
262
0
    OSVR_ReturnCode ret =
263
0
      osvr_ClientGetViewerEyePose(*m_display, 0, eye, &eyePose);
264
0
    while (ret != OSVR_RETURN_SUCCESS) {
265
0
      osvr_ClientUpdate(*m_ctx);
266
0
      ret = osvr_ClientGetViewerEyePose(*m_display, 0, eye, &eyePose);
267
0
    }
268
0
    state.mEyeTranslation[eye].x = eyePose.translation.data[0];
269
0
    state.mEyeTranslation[eye].y = eyePose.translation.data[1];
270
0
    state.mEyeTranslation[eye].z = eyePose.translation.data[2];
271
0
272
0
    Matrix4x4 pose;
273
0
    pose.SetRotationFromQuaternion(gfx::Quaternion(osvrQuatGetX(&eyePose.rotation),
274
0
                                                   osvrQuatGetY(&eyePose.rotation),
275
0
                                                   osvrQuatGetZ(&eyePose.rotation),
276
0
                                                   osvrQuatGetW(&eyePose.rotation)));
277
0
    pose.PreTranslate(eyePose.translation.data[0], eyePose.translation.data[1], eyePose.translation.data[2]);
278
0
    pose.Invert();
279
0
    mHeadToEye[eye] = pose;
280
0
  }
281
0
}
282
283
void
284
VRDisplayOSVR::Destroy()
285
0
{
286
0
  // destroy non-owning pointers
287
0
  m_ctx = nullptr;
288
0
  m_iface = nullptr;
289
0
  m_display = nullptr;
290
0
}
291
292
void
293
VRDisplayOSVR::ZeroSensor()
294
0
{
295
0
  // recenter pose aka reset yaw
296
0
  osvr_ClientSetRoomRotationUsingHead(*m_ctx);
297
0
}
298
299
VRHMDSensorState
300
VRDisplayOSVR::GetSensorState()
301
0
{
302
0
303
0
  //update client context before anything
304
0
  //this usually goes into app's mainloop
305
0
  osvr_ClientUpdate(*m_ctx);
306
0
307
0
  VRHMDSensorState result{};
308
0
  OSVR_TimeValue timestamp;
309
0
310
0
  OSVR_OrientationState orientation;
311
0
312
0
  OSVR_ReturnCode ret =
313
0
    osvr_GetOrientationState(*m_iface, &timestamp, &orientation);
314
0
315
0
  result.timestamp = timestamp.seconds;
316
0
  result.inputFrameID = mDisplayInfo.mFrameId;
317
0
318
0
  if (ret == OSVR_RETURN_SUCCESS) {
319
0
    result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
320
0
    result.pose.orientation[0] = orientation.data[1];
321
0
    result.pose.orientation[1] = orientation.data[2];
322
0
    result.pose.orientation[2] = orientation.data[3];
323
0
    result.pose.orientation[3] = orientation.data[0];
324
0
  } else {
325
0
    // default to an identity quaternion
326
0
    result.pose.orientation[3] = 1.0f;
327
0
  }
328
0
329
0
  OSVR_PositionState position;
330
0
  ret = osvr_GetPositionState(*m_iface, &timestamp, &position);
331
0
  if (ret == OSVR_RETURN_SUCCESS) {
332
0
    result.flags |= VRDisplayCapabilityFlags::Cap_Position;
333
0
    result.pose.position[0] = position.data[0];
334
0
    result.pose.position[1] = position.data[1];
335
0
    result.pose.position[2] = position.data[2];
336
0
  }
337
0
338
0
  result.CalcViewMatrices(mHeadToEye);
339
0
340
0
  return result;
341
0
}
342
343
#if defined(XP_WIN)
344
345
bool
346
VRDisplayOSVR::SubmitFrame(ID3D11Texture2D* aSource,
347
  const IntSize& aSize,
348
  const gfx::Rect& aLeftEyeRect,
349
  const gfx::Rect& aRightEyeRect)
350
{
351
  // XXX Add code to submit frame
352
  return false;
353
}
354
355
#elif defined(XP_MACOSX)
356
357
bool
358
VRDisplayOSVR::SubmitFrame(MacIOSurface* aMacIOSurface,
359
                           const IntSize& aSize,
360
                           const gfx::Rect& aLeftEyeRect,
361
                           const gfx::Rect& aRightEyeRect)
362
{
363
  // XXX Add code to submit frame
364
  MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
365
  return false;
366
}
367
368
#endif
369
370
void
371
VRDisplayOSVR::StartPresentation()
372
0
{
373
0
  // XXX Add code to start VR Presentation
374
0
}
375
376
void
377
VRDisplayOSVR::StopPresentation()
378
0
{
379
0
  // XXX Add code to end VR Presentation
380
0
}
381
382
already_AddRefed<VRSystemManagerOSVR>
383
VRSystemManagerOSVR::Create()
384
0
{
385
0
  MOZ_ASSERT(NS_IsMainThread());
386
0
387
0
  if (!gfxPrefs::VREnabled() || !gfxPrefs::VROSVREnabled()) {
388
0
    return nullptr;
389
0
  }
390
0
  if (!LoadOSVRRuntime()) {
391
0
    return nullptr;
392
0
  }
393
0
  RefPtr<VRSystemManagerOSVR> manager = new VRSystemManagerOSVR();
394
0
  return manager.forget();
395
0
}
396
397
void
398
VRSystemManagerOSVR::CheckOSVRStatus()
399
0
{
400
0
  if (mOSVRInitialized) {
401
0
    return;
402
0
  }
403
0
404
0
  // client context must be initialized first
405
0
  InitializeClientContext();
406
0
407
0
  // update client context
408
0
  osvr_ClientUpdate(m_ctx);
409
0
410
0
  // initialize interface and display if they are not initialized yet
411
0
  InitializeInterface();
412
0
  InitializeDisplay();
413
0
414
0
  // OSVR is fully initialized now
415
0
  if (mClientContextInitialized && mDisplayConfigInitialized &&
416
0
      mInterfaceInitialized) {
417
0
    mOSVRInitialized = true;
418
0
  }
419
0
}
420
421
void
422
VRSystemManagerOSVR::InitializeClientContext()
423
0
{
424
0
  // already initialized
425
0
  if (mClientContextInitialized) {
426
0
    return;
427
0
  }
428
0
429
0
  // first time creating
430
0
  if (!m_ctx) {
431
0
    // get client context
432
0
    m_ctx = osvr_ClientInit("com.osvr.webvr", 0);
433
0
    // update context
434
0
    osvr_ClientUpdate(m_ctx);
435
0
    // verify we are connected
436
0
    if (OSVR_RETURN_SUCCESS == osvr_ClientCheckStatus(m_ctx)) {
437
0
      mClientContextInitialized = true;
438
0
    }
439
0
  }
440
0
  // client context exists but not up and running yet
441
0
  else {
442
0
    // update context
443
0
    osvr_ClientUpdate(m_ctx);
444
0
    if (OSVR_RETURN_SUCCESS == osvr_ClientCheckStatus(m_ctx)) {
445
0
      mClientContextInitialized = true;
446
0
    }
447
0
  }
448
0
}
449
450
void
451
VRSystemManagerOSVR::InitializeInterface()
452
0
{
453
0
  // already initialized
454
0
  if (mInterfaceInitialized) {
455
0
    return;
456
0
  }
457
0
  //Client context must be initialized before getting interface
458
0
  if (mClientContextInitialized) {
459
0
    // m_iface will remain nullptr if no interface is returned
460
0
    if (OSVR_RETURN_SUCCESS ==
461
0
        osvr_ClientGetInterface(m_ctx, "/me/head", &m_iface)) {
462
0
      mInterfaceInitialized = true;
463
0
    }
464
0
  }
465
0
}
466
467
void
468
VRSystemManagerOSVR::InitializeDisplay()
469
0
{
470
0
  // display is fully configured
471
0
  if (mDisplayConfigInitialized) {
472
0
    return;
473
0
  }
474
0
475
0
  //Client context must be initialized before getting interface
476
0
  if (mClientContextInitialized) {
477
0
    // first time creating display object
478
0
    if (m_display == nullptr) {
479
0
480
0
      OSVR_ReturnCode ret = osvr_ClientGetDisplay(m_ctx, &m_display);
481
0
482
0
      if (ret == OSVR_RETURN_SUCCESS) {
483
0
        osvr_ClientUpdate(m_ctx);
484
0
        // display object may have been created but not fully startup
485
0
        if (OSVR_RETURN_SUCCESS == osvr_ClientCheckDisplayStartup(m_display)) {
486
0
          mDisplayConfigInitialized = true;
487
0
        }
488
0
      }
489
0
490
0
      // Typically once we get Display object, pose data is available after
491
0
      // clientUpdate but sometimes it takes ~ 200 ms to get
492
0
      // a succesfull connection, so we might have to run a few update cycles
493
0
    } else {
494
0
495
0
      if (OSVR_RETURN_SUCCESS == osvr_ClientCheckDisplayStartup(m_display)) {
496
0
        mDisplayConfigInitialized = true;
497
0
      }
498
0
    }
499
0
  }
500
0
}
501
502
bool
503
VRSystemManagerOSVR::Init()
504
0
{
505
0
506
0
  // OSVR server should be running in the background
507
0
  // It would load plugins and take care of detecting HMDs
508
0
  if (!mOSVRInitialized) {
509
0
    nsIThread* thread = nullptr;
510
0
    NS_GetCurrentThread(&thread);
511
0
    mOSVRThread = already_AddRefed<nsIThread>(thread);
512
0
513
0
    // initialize client context
514
0
    InitializeClientContext();
515
0
    // try to initialize interface
516
0
    InitializeInterface();
517
0
    // try to initialize display object
518
0
    InitializeDisplay();
519
0
    // verify all components are initialized
520
0
    CheckOSVRStatus();
521
0
  }
522
0
523
0
  return mOSVRInitialized;
524
0
}
525
526
void
527
VRSystemManagerOSVR::Destroy()
528
0
{
529
0
  Shutdown();
530
0
}
531
532
void
533
VRSystemManagerOSVR::Shutdown()
534
0
{
535
0
  if (mOSVRInitialized) {
536
0
    MOZ_ASSERT(NS_GetCurrentThread() == mOSVRThread);
537
0
    mOSVRThread = nullptr;
538
0
    mHMDInfo = nullptr;
539
0
    mOSVRInitialized = false;
540
0
  }
541
0
  // client context may not have been initialized
542
0
  if (m_ctx) {
543
0
    osvr_ClientFreeDisplay(m_display);
544
0
  }
545
0
  // osvr checks that m_ctx or m_iface are not null
546
0
  osvr_ClientFreeInterface(m_ctx, m_iface);
547
0
  osvr_ClientShutdown(m_ctx);
548
0
}
549
550
void
551
VRSystemManagerOSVR::NotifyVSync()
552
0
{
553
0
  VRSystemManager::NotifyVSync();
554
0
555
0
  // TODO - Check for device disconnection or other OSVR events
556
0
}
557
558
void
559
VRSystemManagerOSVR::Enumerate()
560
0
{
561
0
  // make sure context, interface and display are initialized
562
0
  CheckOSVRStatus();
563
0
564
0
  if (!Init()) {
565
0
    return;
566
0
  }
567
0
568
0
  mHMDInfo = new VRDisplayOSVR(&m_ctx, &m_iface, &m_display);
569
0
}
570
571
bool
572
VRSystemManagerOSVR::ShouldInhibitEnumeration()
573
0
{
574
0
  if (VRSystemManager::ShouldInhibitEnumeration()) {
575
0
    return true;
576
0
  }
577
0
  if (mHMDInfo) {
578
0
    // When we find an a VR device, don't
579
0
    // allow any further enumeration as it
580
0
    // may get picked up redundantly by other
581
0
    // API's.
582
0
    return true;
583
0
  }
584
0
  return false;
585
0
}
586
587
void
588
VRSystemManagerOSVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
589
0
{
590
0
  if (mHMDInfo) {
591
0
    aHMDResult.AppendElement(mHMDInfo);
592
0
  }
593
0
}
594
595
bool
596
VRSystemManagerOSVR::GetIsPresenting()
597
0
{
598
0
  if (mHMDInfo) {
599
0
    VRDisplayInfo displayInfo(mHMDInfo->GetDisplayInfo());
600
0
    return displayInfo.GetPresentingGroups() != kVRGroupNone;
601
0
  }
602
0
603
0
  return false;
604
0
}
605
606
void
607
VRSystemManagerOSVR::HandleInput()
608
0
{
609
0
}
610
611
void
612
VRSystemManagerOSVR::VibrateHaptic(uint32_t aControllerIdx,
613
                                   uint32_t aHapticIndex,
614
                                   double aIntensity,
615
                                   double aDuration,
616
                                   const VRManagerPromise& aPromise)
617
0
{
618
0
}
619
620
void
621
VRSystemManagerOSVR::StopVibrateHaptic(uint32_t aControllerIdx)
622
0
{
623
0
}
624
625
void
626
VRSystemManagerOSVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
627
0
{
628
0
}
629
630
void
631
VRSystemManagerOSVR::ScanForControllers()
632
0
{
633
0
}
634
635
void
636
VRSystemManagerOSVR::RemoveControllers()
637
0
{
638
0
}