Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/vr/gfxVR.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 "gfxVR.h"
10
#include "mozilla/dom/GamepadEventTypes.h"
11
#include "mozilla/dom/GamepadBinding.h"
12
#include "VRDisplayHost.h"
13
14
#ifndef M_PI
15
# define M_PI 3.14159265358979323846
16
#endif
17
18
using namespace mozilla;
19
using namespace mozilla::gfx;
20
21
Atomic<uint32_t> VRSystemManager::sDisplayBase(0);
22
Atomic<uint32_t> VRSystemManager::sControllerBase(0);
23
24
/* static */ uint32_t
25
VRSystemManager::AllocateDisplayID()
26
0
{
27
0
  return ++sDisplayBase;
28
0
}
29
30
/* static */ uint32_t
31
VRSystemManager::AllocateControllerID()
32
0
{
33
0
  return ++sControllerBase;
34
0
}
35
36
/**
37
 * VRSystemManager::NotifyVsync must be called even when a WebVR site is
38
 * not active, in order to poll for respond to VR Platform API requests.
39
 * This should be called very often, ideally once per frame.
40
 * VRSystemManager::Refresh will not activate VR hardware or
41
 * initialize VR runtimes that have not already been activated.
42
 */
43
void
44
VRSystemManager::NotifyVSync()
45
0
{
46
0
  // VRDisplayHost::NotifyVSync may modify mVRDisplays, so we iterate
47
0
  // through a local copy here.
48
0
  nsTArray<RefPtr<VRDisplayHost>> displays;
49
0
  GetHMDs(displays);
50
0
  for (const auto& display : displays) {
51
0
    display->NotifyVSync();
52
0
  }
53
0
54
0
  // Ensure that the controller state is updated at least
55
0
  // on every 2d display VSync when not in a VR presentation.
56
0
  if (!GetIsPresenting()) {
57
0
    HandleInput();
58
0
  }
59
0
}
60
61
/**
62
 * VRSystemManager::GetHMDs must not be called unless
63
 * VRSystemManager::ShouldInhibitEnumeration is called
64
 * on all VRSystemManager instances and they all return
65
 * false.
66
 *
67
 * This is used to ensure that VR devices that can be
68
 * enumerated by multiple API's are only enumerated by
69
 * one API.
70
 *
71
 * GetHMDs is called for the most specific API
72
 * (ie. Oculus SDK) first before calling GetHMDs on
73
 * more generic api's (ie. OpenVR) to ensure that a device
74
 * is accessed using the API most optimized for it.
75
 *
76
 * ShouldInhibitEnumeration may also be used to prevent
77
 * devices from jumping to other API's when they are
78
 * intentionally ignored, such as when responding to
79
 * requests by the VR platform to unload the libraries
80
 * for runtime software updates.
81
 */
82
bool
83
VRSystemManager::ShouldInhibitEnumeration()
84
0
{
85
0
  return false;
86
0
}
87
88
Matrix4x4
89
VRFieldOfView::ConstructProjectionMatrix(float zNear, float zFar,
90
                                         bool rightHanded) const
91
0
{
92
0
  float upTan = tan(upDegrees * M_PI / 180.0);
93
0
  float downTan = tan(downDegrees * M_PI / 180.0);
94
0
  float leftTan = tan(leftDegrees * M_PI / 180.0);
95
0
  float rightTan = tan(rightDegrees * M_PI / 180.0);
96
0
97
0
  float handednessScale = rightHanded ? -1.0 : 1.0;
98
0
99
0
  float pxscale = 2.0f / (leftTan + rightTan);
100
0
  float pxoffset = (leftTan - rightTan) * pxscale * 0.5;
101
0
  float pyscale = 2.0f / (upTan + downTan);
102
0
  float pyoffset = (upTan - downTan) * pyscale * 0.5;
103
0
104
0
  Matrix4x4 mobj;
105
0
  float *m = &mobj._11;
106
0
107
0
  m[0*4+0] = pxscale;
108
0
  m[2*4+0] = pxoffset * handednessScale;
109
0
110
0
  m[1*4+1] = pyscale;
111
0
  m[2*4+1] = -pyoffset * handednessScale;
112
0
113
0
  m[2*4+2] = zFar / (zNear - zFar) * -handednessScale;
114
0
  m[3*4+2] = (zFar * zNear) / (zNear - zFar);
115
0
116
0
  m[2*4+3] = handednessScale;
117
0
  m[3*4+3] = 0.0f;
118
0
119
0
  return mobj;
120
0
}
121
122
void
123
VRSystemManager::AddGamepad(const VRControllerInfo& controllerInfo)
124
0
{
125
0
  dom::GamepadAdded a(NS_ConvertUTF8toUTF16(controllerInfo.GetControllerName()),
126
0
                      controllerInfo.GetMappingType(),
127
0
                      controllerInfo.GetHand(),
128
0
                      controllerInfo.GetDisplayID(),
129
0
                      controllerInfo.GetNumButtons(),
130
0
                      controllerInfo.GetNumAxes(),
131
0
                      controllerInfo.GetNumHaptics());
132
0
133
0
  VRManager* vm = VRManager::Get();
134
0
  vm->NotifyGamepadChange<dom::GamepadAdded>(mControllerCount, a);
135
0
}
136
137
void
138
VRSystemManager::RemoveGamepad(uint32_t aIndex)
139
0
{
140
0
  dom::GamepadRemoved a;
141
0
142
0
  VRManager* vm = VRManager::Get();
143
0
  vm->NotifyGamepadChange<dom::GamepadRemoved>(aIndex, a);
144
0
}
145
146
void
147
VRSystemManager::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
148
                                bool aPressed, bool aTouched, double aValue)
149
0
{
150
0
  dom::GamepadButtonInformation a(aButton, aValue, aPressed, aTouched);
151
0
152
0
  VRManager* vm = VRManager::Get();
153
0
  vm->NotifyGamepadChange<dom::GamepadButtonInformation>(aIndex, a);
154
0
}
155
156
void
157
VRSystemManager::NewAxisMove(uint32_t aIndex, uint32_t aAxis,
158
                             double aValue)
159
0
{
160
0
  dom::GamepadAxisInformation a(aAxis, aValue);
161
0
162
0
  VRManager* vm = VRManager::Get();
163
0
  vm->NotifyGamepadChange<dom::GamepadAxisInformation>(aIndex, a);
164
0
}
165
166
void
167
VRSystemManager::NewPoseState(uint32_t aIndex,
168
                              const dom::GamepadPoseState& aPose)
169
0
{
170
0
  dom::GamepadPoseInformation a(aPose);
171
0
172
0
  VRManager* vm = VRManager::Get();
173
0
  vm->NotifyGamepadChange<dom::GamepadPoseInformation>(aIndex, a);
174
0
}
175
176
void
177
VRSystemManager::NewHandChangeEvent(uint32_t aIndex,
178
                                    const dom::GamepadHand aHand)
179
0
{
180
0
  dom::GamepadHandInformation a(aHand);
181
0
182
0
  VRManager* vm = VRManager::Get();
183
0
  vm->NotifyGamepadChange<dom::GamepadHandInformation>(aIndex, a);
184
0
}
185
186
void
187
VRHMDSensorState::CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms)
188
0
{
189
0
190
0
  gfx::Matrix4x4 matHead;
191
0
  if (flags & VRDisplayCapabilityFlags::Cap_Orientation) {
192
0
    matHead.SetRotationFromQuaternion(gfx::Quaternion(pose.orientation[0], pose.orientation[1],
193
0
                                                      pose.orientation[2], pose.orientation[3]));
194
0
  }
195
0
  matHead.PreTranslate(-pose.position[0], -pose.position[1], -pose.position[2]);
196
0
197
0
  gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayState::Eye_Left];
198
0
  matView.Normalize();
199
0
  memcpy(leftViewMatrix, matView.components, sizeof(matView.components));
200
0
  matView = matHead * aHeadToEyeTransforms[VRDisplayState::Eye_Right];
201
0
  matView.Normalize();
202
0
  memcpy(rightViewMatrix, matView.components, sizeof(matView.components));
203
0
}
204
205
const IntSize
206
VRDisplayInfo::SuggestedEyeResolution() const
207
0
{
208
0
  return IntSize(mDisplayState.mEyeResolution.width,
209
0
                 mDisplayState.mEyeResolution.height);
210
0
}
211
212
const Point3D
213
VRDisplayInfo::GetEyeTranslation(uint32_t whichEye) const
214
0
{
215
0
  return Point3D(mDisplayState.mEyeTranslation[whichEye].x,
216
0
                 mDisplayState.mEyeTranslation[whichEye].y,
217
0
                 mDisplayState.mEyeTranslation[whichEye].z);
218
0
}
219
220
const Size
221
VRDisplayInfo::GetStageSize() const
222
0
{
223
0
  return Size(mDisplayState.mStageSize.width,
224
0
              mDisplayState.mStageSize.height);
225
0
}
226
227
const Matrix4x4
228
VRDisplayInfo::GetSittingToStandingTransform() const
229
0
{
230
0
  Matrix4x4 m;
231
0
  // If we could replace Matrix4x4 with a pod type, we could
232
0
  // use it directly from the VRDisplayInfo struct.
233
0
  memcpy(m.components, mDisplayState.mSittingToStandingTransform, sizeof(float) * 16);
234
0
  return m;
235
0
}