Source code

Revision control

Other Tools

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 file,
5
* You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/dom/VRServiceTest.h"
8
#include "mozilla/dom/VRServiceTestBinding.h"
9
#include "VRPuppetCommandBuffer.h"
10
#include <type_traits>
11
12
namespace mozilla {
13
using namespace gfx;
14
namespace dom {
15
16
NS_IMPL_CYCLE_COLLECTION_CLASS(VRMockDisplay)
17
18
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRMockDisplay,
19
DOMEventTargetHelper)
20
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
21
22
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRMockDisplay,
23
DOMEventTargetHelper)
24
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
25
26
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRMockDisplay)
27
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
28
29
NS_IMPL_ADDREF_INHERITED(VRMockDisplay, DOMEventTargetHelper)
30
NS_IMPL_RELEASE_INHERITED(VRMockDisplay, DOMEventTargetHelper)
31
32
namespace {
33
template <class T>
34
bool ReadFloat32Array(T& aDestination, const Float32Array& aSource,
35
ErrorResult& aRv) {
36
constexpr size_t length = std::extent<T>::value;
37
aSource.ComputeLengthAndData();
38
if (aSource.Length() != length) {
39
aRv.Throw(NS_ERROR_INVALID_ARG);
40
// We don't want to MOZ_ASSERT here, as that would cause the
41
// browser to crash, making it difficult to debug the problem
42
// in JS code calling this API.
43
return false;
44
}
45
for (size_t i = 0; i < length; i++) {
46
aDestination[i] = aSource.Data()[i];
47
}
48
return true;
49
}
50
}; // anonymous namespace
51
52
VRMockDisplay::VRMockDisplay(VRServiceTest* aVRServiceTest)
53
: DOMEventTargetHelper(aVRServiceTest->GetOwner()),
54
mVRServiceTest(aVRServiceTest) {}
55
56
JSObject* VRMockDisplay::WrapObject(JSContext* aCx,
57
JS::Handle<JSObject*> aGivenProto) {
58
return VRMockDisplay_Binding::Wrap(aCx, this, aGivenProto);
59
}
60
61
VRHMDSensorState& VRMockDisplay::SensorState() const {
62
return mVRServiceTest->SystemState().sensorState;
63
}
64
65
VRDisplayState& VRMockDisplay::DisplayState() const {
66
return mVRServiceTest->SystemState().displayState;
67
}
68
69
void VRMockDisplay::Clear() {
70
VRDisplayState& displayState = DisplayState();
71
displayState.Clear();
72
VRHMDSensorState& sensorState = SensorState();
73
sensorState.Clear();
74
}
75
76
void VRMockDisplay::Create() {
77
Clear();
78
VRDisplayState& state = DisplayState();
79
80
strncpy(state.displayName, "Puppet HMD", kVRDisplayNameMaxLen);
81
state.eightCC = GFX_VR_EIGHTCC('P', 'u', 'p', 'p', 'e', 't', ' ', ' ');
82
state.isConnected = true;
83
state.isMounted = false;
84
state.capabilityFlags = VRDisplayCapabilityFlags::Cap_None |
85
VRDisplayCapabilityFlags::Cap_Orientation |
86
VRDisplayCapabilityFlags::Cap_Position |
87
VRDisplayCapabilityFlags::Cap_External |
88
VRDisplayCapabilityFlags::Cap_Present |
89
VRDisplayCapabilityFlags::Cap_StageParameters |
90
VRDisplayCapabilityFlags::Cap_MountDetection |
91
VRDisplayCapabilityFlags::Cap_ImmersiveVR;
92
state.blendMode = VRDisplayBlendMode::Opaque;
93
94
// 1836 x 2040 resolution is arbitrary and can be overridden.
95
// This default resolution was chosen to be within range of a
96
// typical VR eye buffer size. This value is derived by
97
// scaling a 1080x1200 per-eye panel resolution by the
98
// commonly used pre-lens-distortion pass scaling factor of 1.7x.
99
// 1.7x is commonly used in HMD's employing fresnel lenses to ensure
100
// a sufficient fragment shading rate in the peripheral area of the
101
// post-warp eye buffers.
102
state.eyeResolution.width = 1836; // 1080 * 1.7
103
state.eyeResolution.height = 2040; // 1200 * 1.7
104
105
for (uint32_t eye = 0; eye < VRDisplayState::NumEyes; ++eye) {
106
state.eyeTranslation[eye].x = 0.0f;
107
state.eyeTranslation[eye].y = 0.0f;
108
state.eyeTranslation[eye].z = 0.0f;
109
state.eyeFOV[eye] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
110
}
111
112
// default: 1m x 1m space, 0.75m high in seated position
113
state.stageSize.width = 1.0f;
114
state.stageSize.height = 1.0f;
115
116
state.sittingToStandingTransform[0] = 1.0f;
117
state.sittingToStandingTransform[1] = 0.0f;
118
state.sittingToStandingTransform[2] = 0.0f;
119
state.sittingToStandingTransform[3] = 0.0f;
120
121
state.sittingToStandingTransform[4] = 0.0f;
122
state.sittingToStandingTransform[5] = 1.0f;
123
state.sittingToStandingTransform[6] = 0.0f;
124
state.sittingToStandingTransform[7] = 0.0f;
125
126
state.sittingToStandingTransform[8] = 0.0f;
127
state.sittingToStandingTransform[9] = 0.0f;
128
state.sittingToStandingTransform[10] = 1.0f;
129
state.sittingToStandingTransform[11] = 0.0f;
130
131
state.sittingToStandingTransform[12] = 0.0f;
132
state.sittingToStandingTransform[13] = 0.75f;
133
state.sittingToStandingTransform[14] = 0.0f;
134
state.sittingToStandingTransform[15] = 1.0f;
135
136
VRHMDSensorState& sensorState = SensorState();
137
gfx::Quaternion rot;
138
sensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
139
sensorState.pose.orientation[0] = rot.x;
140
sensorState.pose.orientation[1] = rot.y;
141
sensorState.pose.orientation[2] = rot.z;
142
sensorState.pose.orientation[3] = rot.w;
143
sensorState.pose.angularVelocity[0] = 0.0f;
144
sensorState.pose.angularVelocity[1] = 0.0f;
145
sensorState.pose.angularVelocity[2] = 0.0f;
146
147
sensorState.flags |= VRDisplayCapabilityFlags::Cap_Position;
148
sensorState.pose.position[0] = 0.0f;
149
sensorState.pose.position[1] = 0.0f;
150
sensorState.pose.position[2] = 0.0f;
151
sensorState.pose.linearVelocity[0] = 0.0f;
152
sensorState.pose.linearVelocity[1] = 0.0f;
153
sensorState.pose.linearVelocity[2] = 0.0f;
154
}
155
156
void VRMockDisplay::SetConnected(bool aConnected) {
157
DisplayState().isConnected = aConnected;
158
}
159
bool VRMockDisplay::Connected() const { return DisplayState().isConnected; }
160
161
void VRMockDisplay::SetMounted(bool aMounted) {
162
DisplayState().isMounted = aMounted;
163
}
164
165
bool VRMockDisplay::Mounted() const { return DisplayState().isMounted; }
166
167
void VRMockDisplay::SetCapFlag(VRDisplayCapabilityFlags aFlag, bool aEnabled) {
168
if (aEnabled) {
169
DisplayState().capabilityFlags |= aFlag;
170
} else {
171
DisplayState().capabilityFlags &= ~aFlag;
172
}
173
}
174
bool VRMockDisplay::GetCapFlag(VRDisplayCapabilityFlags aFlag) const {
175
return ((DisplayState().capabilityFlags & aFlag) !=
176
VRDisplayCapabilityFlags::Cap_None);
177
}
178
179
void VRMockDisplay::SetCapPosition(bool aEnabled) {
180
SetCapFlag(VRDisplayCapabilityFlags::Cap_Position, aEnabled);
181
}
182
183
void VRMockDisplay::SetCapOrientation(bool aEnabled) {
184
SetCapFlag(VRDisplayCapabilityFlags::Cap_Orientation, aEnabled);
185
}
186
187
void VRMockDisplay::SetCapPresent(bool aEnabled) {
188
SetCapFlag(VRDisplayCapabilityFlags::Cap_Present, aEnabled);
189
}
190
191
void VRMockDisplay::SetCapExternal(bool aEnabled) {
192
SetCapFlag(VRDisplayCapabilityFlags::Cap_External, aEnabled);
193
}
194
195
void VRMockDisplay::SetCapAngularAcceleration(bool aEnabled) {
196
SetCapFlag(VRDisplayCapabilityFlags::Cap_AngularAcceleration, aEnabled);
197
}
198
199
void VRMockDisplay::SetCapLinearAcceleration(bool aEnabled) {
200
SetCapFlag(VRDisplayCapabilityFlags::Cap_LinearAcceleration, aEnabled);
201
}
202
203
void VRMockDisplay::SetCapStageParameters(bool aEnabled) {
204
SetCapFlag(VRDisplayCapabilityFlags::Cap_StageParameters, aEnabled);
205
}
206
207
void VRMockDisplay::SetCapMountDetection(bool aEnabled) {
208
SetCapFlag(VRDisplayCapabilityFlags::Cap_MountDetection, aEnabled);
209
}
210
211
void VRMockDisplay::SetCapPositionEmulated(bool aEnabled) {
212
SetCapFlag(VRDisplayCapabilityFlags::Cap_PositionEmulated, aEnabled);
213
}
214
215
void VRMockDisplay::SetEyeFOV(VREye aEye, double aUpDegree, double aRightDegree,
216
double aDownDegree, double aLeftDegree) {
217
gfx::VRDisplayState::Eye eye = aEye == VREye::Left
218
? gfx::VRDisplayState::Eye_Left
219
: gfx::VRDisplayState::Eye_Right;
220
VRDisplayState& state = DisplayState();
221
state.eyeFOV[eye] =
222
gfx::VRFieldOfView(aUpDegree, aRightDegree, aDownDegree, aLeftDegree);
223
}
224
225
void VRMockDisplay::SetEyeOffset(VREye aEye, double aOffsetX, double aOffsetY,
226
double aOffsetZ) {
227
gfx::VRDisplayState::Eye eye = aEye == VREye::Left
228
? gfx::VRDisplayState::Eye_Left
229
: gfx::VRDisplayState::Eye_Right;
230
VRDisplayState& state = DisplayState();
231
state.eyeTranslation[eye].x = (float)aOffsetX;
232
state.eyeTranslation[eye].y = (float)aOffsetY;
233
state.eyeTranslation[eye].z = (float)aOffsetZ;
234
}
235
236
bool VRMockDisplay::CapPosition() const {
237
return GetCapFlag(VRDisplayCapabilityFlags::Cap_Position);
238
}
239
240
bool VRMockDisplay::CapOrientation() const {
241
return GetCapFlag(VRDisplayCapabilityFlags::Cap_Orientation);
242
}
243
244
bool VRMockDisplay::CapPresent() const {
245
return GetCapFlag(VRDisplayCapabilityFlags::Cap_Present);
246
}
247
248
bool VRMockDisplay::CapExternal() const {
249
return GetCapFlag(VRDisplayCapabilityFlags::Cap_External);
250
}
251
252
bool VRMockDisplay::CapAngularAcceleration() const {
253
return GetCapFlag(VRDisplayCapabilityFlags::Cap_AngularAcceleration);
254
}
255
256
bool VRMockDisplay::CapLinearAcceleration() const {
257
return GetCapFlag(VRDisplayCapabilityFlags::Cap_LinearAcceleration);
258
}
259
260
bool VRMockDisplay::CapStageParameters() const {
261
return GetCapFlag(VRDisplayCapabilityFlags::Cap_StageParameters);
262
}
263
264
bool VRMockDisplay::CapMountDetection() const {
265
return GetCapFlag(VRDisplayCapabilityFlags::Cap_MountDetection);
266
}
267
268
bool VRMockDisplay::CapPositionEmulated() const {
269
return GetCapFlag(VRDisplayCapabilityFlags::Cap_PositionEmulated);
270
}
271
272
void VRMockDisplay::SetEyeResolution(uint32_t aRenderWidth,
273
uint32_t aRenderHeight) {
274
DisplayState().eyeResolution.width = aRenderWidth;
275
DisplayState().eyeResolution.height = aRenderHeight;
276
}
277
278
void VRMockDisplay::SetStageSize(double aWidth, double aHeight) {
279
VRDisplayState& displayState = DisplayState();
280
displayState.stageSize.width = (float)aWidth;
281
displayState.stageSize.height = (float)aHeight;
282
}
283
284
void VRMockDisplay::SetSittingToStandingTransform(
285
const Float32Array& aTransform, ErrorResult& aRv) {
286
Unused << ReadFloat32Array(DisplayState().sittingToStandingTransform,
287
aTransform, aRv);
288
}
289
290
void VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition,
291
const Nullable<Float32Array>& aLinearVelocity,
292
const Nullable<Float32Array>& aLinearAcceleration,
293
const Nullable<Float32Array>& aOrientation,
294
const Nullable<Float32Array>& aAngularVelocity,
295
const Nullable<Float32Array>& aAngularAcceleration,
296
ErrorResult& aRv) {
297
VRHMDSensorState& sensorState = mVRServiceTest->SystemState().sensorState;
298
sensorState.Clear();
299
sensorState.flags = VRDisplayCapabilityFlags::Cap_None;
300
// sensorState.timestamp will be set automatically during
301
// puppet script execution
302
303
if (!aOrientation.IsNull()) {
304
if (!ReadFloat32Array(sensorState.pose.orientation, aOrientation.Value(),
305
aRv)) {
306
return;
307
}
308
sensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
309
}
310
if (!aAngularVelocity.IsNull()) {
311
if (!ReadFloat32Array(sensorState.pose.angularVelocity,
312
aAngularVelocity.Value(), aRv)) {
313
return;
314
}
315
sensorState.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
316
}
317
if (!aAngularAcceleration.IsNull()) {
318
if (!ReadFloat32Array(sensorState.pose.angularAcceleration,
319
aAngularAcceleration.Value(), aRv)) {
320
return;
321
}
322
sensorState.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
323
}
324
if (!aPosition.IsNull()) {
325
if (!ReadFloat32Array(sensorState.pose.position, aPosition.Value(), aRv)) {
326
return;
327
}
328
sensorState.flags |= VRDisplayCapabilityFlags::Cap_Position;
329
}
330
if (!aLinearVelocity.IsNull()) {
331
if (!ReadFloat32Array(sensorState.pose.linearVelocity,
332
aLinearVelocity.Value(), aRv)) {
333
return;
334
}
335
sensorState.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
336
}
337
if (!aLinearAcceleration.IsNull()) {
338
if (!ReadFloat32Array(sensorState.pose.linearAcceleration,
339
aLinearAcceleration.Value(), aRv)) {
340
return;
341
}
342
sensorState.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
343
}
344
}
345
346
NS_IMPL_CYCLE_COLLECTION_CLASS(VRMockController)
347
348
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRMockController,
349
DOMEventTargetHelper)
350
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
351
352
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRMockController,
353
DOMEventTargetHelper)
354
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
355
356
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRMockController)
357
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
358
359
NS_IMPL_ADDREF_INHERITED(VRMockController, DOMEventTargetHelper)
360
NS_IMPL_RELEASE_INHERITED(VRMockController, DOMEventTargetHelper)
361
362
VRMockController::VRMockController(VRServiceTest* aVRServiceTest,
363
uint32_t aControllerIdx)
364
: DOMEventTargetHelper(aVRServiceTest->GetOwner()),
365
mControllerIdx(aControllerIdx) {
366
MOZ_ASSERT(aControllerIdx < kVRControllerMaxCount);
367
}
368
369
JSObject* VRMockController::WrapObject(JSContext* aCx,
370
JS::Handle<JSObject*> aGivenProto) {
371
return VRMockController_Binding::Wrap(aCx, this, aGivenProto);
372
}
373
374
VRControllerState& VRMockController::ControllerState() const {
375
return mVRServiceTest->SystemState().controllerState[mControllerIdx];
376
}
377
378
void VRMockController::Create() {
379
// Initialize with a 6dof, left-handed gamepad with one haptic actuator
380
// Tests are expected to modify the controller before it is sent to the
381
// puppet.
382
Clear();
383
VRControllerState& state = ControllerState();
384
strncpy(state.controllerName, "Puppet Gamepad", kVRControllerNameMaxLen);
385
state.hand = GamepadHand::Left;
386
state.flags = GamepadCapabilityFlags::Cap_Position |
387
GamepadCapabilityFlags::Cap_Orientation;
388
state.numButtons = 1;
389
state.numHaptics = 1;
390
state.triggerValue[0] = 0.0f;
391
}
392
393
void VRMockController::Clear() {
394
mVRServiceTest->ClearController(mControllerIdx);
395
}
396
397
void VRMockController::SetCapFlag(GamepadCapabilityFlags aFlag, bool aEnabled) {
398
if (aEnabled) {
399
ControllerState().flags |= aFlag;
400
} else {
401
ControllerState().flags &= ~aFlag;
402
}
403
}
404
bool VRMockController::GetCapFlag(GamepadCapabilityFlags aFlag) const {
405
return (ControllerState().flags & aFlag) != GamepadCapabilityFlags::Cap_None;
406
}
407
408
void VRMockController::SetHand(GamepadHand aHand) {
409
ControllerState().hand = aHand;
410
}
411
412
GamepadHand VRMockController::Hand() const { return ControllerState().hand; }
413
414
void VRMockController::SetCapPosition(bool aEnabled) {
415
SetCapFlag(GamepadCapabilityFlags::Cap_Position, aEnabled);
416
}
417
418
bool VRMockController::CapPosition() const {
419
return GetCapFlag(GamepadCapabilityFlags::Cap_Position);
420
}
421
422
void VRMockController::SetCapOrientation(bool aEnabled) {
423
SetCapFlag(GamepadCapabilityFlags::Cap_Orientation, aEnabled);
424
}
425
426
bool VRMockController::CapOrientation() const {
427
return GetCapFlag(GamepadCapabilityFlags::Cap_Orientation);
428
}
429
430
void VRMockController::SetCapAngularAcceleration(bool aEnabled) {
431
SetCapFlag(GamepadCapabilityFlags::Cap_AngularAcceleration, aEnabled);
432
}
433
434
bool VRMockController::CapAngularAcceleration() const {
435
return GetCapFlag(GamepadCapabilityFlags::Cap_AngularAcceleration);
436
}
437
438
void VRMockController::SetCapLinearAcceleration(bool aEnabled) {
439
SetCapFlag(GamepadCapabilityFlags::Cap_LinearAcceleration, aEnabled);
440
}
441
442
bool VRMockController::CapLinearAcceleration() const {
443
return GetCapFlag(GamepadCapabilityFlags::Cap_LinearAcceleration);
444
}
445
446
void VRMockController::SetAxisCount(uint32_t aCount) {
447
MOZ_ASSERT(aCount <= kVRControllerMaxAxis);
448
ControllerState().numAxes = aCount;
449
}
450
451
uint32_t VRMockController::AxisCount() const {
452
return ControllerState().numAxes;
453
}
454
455
void VRMockController::SetButtonCount(uint32_t aCount) {
456
MOZ_ASSERT(aCount <= kVRControllerMaxButtons);
457
ControllerState().numButtons = aCount;
458
}
459
460
uint32_t VRMockController::ButtonCount() const {
461
return ControllerState().numButtons;
462
}
463
464
void VRMockController::SetHapticCount(uint32_t aCount) {
465
ControllerState().numHaptics = aCount;
466
}
467
468
uint32_t VRMockController::HapticCount() const {
469
return ControllerState().numHaptics;
470
}
471
472
void VRMockController::SetButtonPressed(uint32_t aButtonIdx, bool aPressed) {
473
MOZ_ASSERT(aButtonIdx < kVRControllerMaxButtons);
474
if (aPressed) {
475
ControllerState().buttonPressed |= (1 << aButtonIdx);
476
} else {
477
ControllerState().buttonPressed &= ~(1 << aButtonIdx);
478
}
479
}
480
481
void VRMockController::SetButtonTouched(uint32_t aButtonIdx, bool aTouched) {
482
MOZ_ASSERT(aButtonIdx < kVRControllerMaxButtons);
483
if (aTouched) {
484
ControllerState().buttonTouched |= (1 << aButtonIdx);
485
} else {
486
ControllerState().buttonTouched &= ~(1 << aButtonIdx);
487
}
488
}
489
490
void VRMockController::SetButtonTrigger(uint32_t aButtonIdx, double aTrigger) {
491
MOZ_ASSERT(aButtonIdx < kVRControllerMaxButtons);
492
493
ControllerState().triggerValue[aButtonIdx] = (float)aTrigger;
494
}
495
496
void VRMockController::SetAxisValue(uint32_t aAxisIdx, double aValue) {
497
MOZ_ASSERT(aAxisIdx < kVRControllerMaxAxis);
498
ControllerState().axisValue[aAxisIdx] = (float)aValue;
499
}
500
501
void VRMockController::SetPose(
502
const Nullable<Float32Array>& aPosition,
503
const Nullable<Float32Array>& aLinearVelocity,
504
const Nullable<Float32Array>& aLinearAcceleration,
505
const Nullable<Float32Array>& aOrientation,
506
const Nullable<Float32Array>& aAngularVelocity,
507
const Nullable<Float32Array>& aAngularAcceleration, ErrorResult& aRv) {
508
VRControllerState& controllerState = ControllerState();
509
controllerState.flags = GamepadCapabilityFlags::Cap_None;
510
511
if (!aOrientation.IsNull()) {
512
if (!ReadFloat32Array(controllerState.pose.orientation,
513
aOrientation.Value(), aRv)) {
514
return;
515
}
516
controllerState.flags |= GamepadCapabilityFlags::Cap_Orientation;
517
}
518
if (!aAngularVelocity.IsNull()) {
519
if (!ReadFloat32Array(controllerState.pose.angularVelocity,
520
aAngularVelocity.Value(), aRv)) {
521
return;
522
}
523
controllerState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
524
}
525
if (!aAngularAcceleration.IsNull()) {
526
if (!ReadFloat32Array(controllerState.pose.angularAcceleration,
527
aAngularAcceleration.Value(), aRv)) {
528
return;
529
}
530
controllerState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
531
}
532
if (!aPosition.IsNull()) {
533
if (!ReadFloat32Array(controllerState.pose.position, aPosition.Value(),
534
aRv)) {
535
return;
536
}
537
controllerState.flags |= GamepadCapabilityFlags::Cap_Position;
538
}
539
if (!aLinearVelocity.IsNull()) {
540
if (!ReadFloat32Array(controllerState.pose.linearVelocity,
541
aLinearVelocity.Value(), aRv)) {
542
return;
543
}
544
controllerState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
545
}
546
if (!aLinearAcceleration.IsNull()) {
547
if (!ReadFloat32Array(controllerState.pose.linearAcceleration,
548
aLinearAcceleration.Value(), aRv)) {
549
return;
550
}
551
controllerState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
552
}
553
}
554
555
NS_IMPL_CYCLE_COLLECTION_CLASS(VRServiceTest)
556
557
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRServiceTest,
558
DOMEventTargetHelper)
559
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
560
561
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRServiceTest,
562
DOMEventTargetHelper)
563
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
564
565
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRServiceTest)
566
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
567
568
NS_IMPL_ADDREF_INHERITED(VRServiceTest, DOMEventTargetHelper)
569
NS_IMPL_RELEASE_INHERITED(VRServiceTest, DOMEventTargetHelper)
570
571
JSObject* VRServiceTest::WrapObject(JSContext* aCx,
572
JS::Handle<JSObject*> aGivenProto) {
573
return VRServiceTest_Binding::Wrap(aCx, this, aGivenProto);
574
}
575
576
// static
577
already_AddRefed<VRServiceTest> VRServiceTest::CreateTestService(
578
nsPIDOMWindowInner* aWindow) {
579
MOZ_ASSERT(aWindow);
580
RefPtr<VRServiceTest> service = new VRServiceTest(aWindow);
581
return service.forget();
582
}
583
584
VRServiceTest::VRServiceTest(nsPIDOMWindowInner* aWindow)
585
: mWindow(aWindow), mPendingState{}, mEncodedState{}, mShuttingDown(false) {
586
mDisplay = new VRMockDisplay(this);
587
for (int i = 0; i < kVRControllerMaxCount; i++) {
588
mControllers.AppendElement(new VRMockController(this, i));
589
}
590
ClearAll();
591
}
592
593
gfx::VRSystemState& VRServiceTest::SystemState() { return mPendingState; }
594
595
VRMockDisplay* VRServiceTest::GetVRDisplay() { return mDisplay; }
596
597
VRMockController* VRServiceTest::GetVRController(uint32_t aControllerIdx,
598
ErrorResult& aRv) {
599
if (aControllerIdx >= kVRControllerMaxCount) {
600
aRv.Throw(NS_ERROR_INVALID_ARG);
601
return nullptr;
602
}
603
return mControllers[aControllerIdx];
604
}
605
606
void VRServiceTest::Shutdown() {
607
MOZ_ASSERT(!mShuttingDown);
608
mShuttingDown = true;
609
mWindow = nullptr;
610
}
611
612
void VRServiceTest::AddCommand(uint64_t aCommand) {
613
EncodeData();
614
mCommandBuffer.AppendElement(aCommand);
615
}
616
617
void VRServiceTest::End() {
618
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_End);
619
}
620
621
void VRServiceTest::ClearAll() {
622
memset(&mPendingState, 0, sizeof(VRSystemState));
623
memset(&mEncodedState, 0, sizeof(VRSystemState));
624
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_ClearAll);
625
}
626
627
void VRServiceTest::ClearController(uint32_t aControllerIdx) {
628
MOZ_ASSERT(aControllerIdx < kVRControllerMaxCount);
629
mPendingState.controllerState[aControllerIdx].Clear();
630
mEncodedState.controllerState[aControllerIdx].Clear();
631
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_ClearController |
632
(uint64_t)aControllerIdx);
633
}
634
635
void VRServiceTest::Timeout(uint32_t aDuration) {
636
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_Timeout |
637
(uint64_t)aDuration);
638
}
639
640
void VRServiceTest::Wait(uint32_t aDuration) {
641
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_Wait | (uint64_t)aDuration);
642
}
643
644
void VRServiceTest::WaitHapticIntensity(uint32_t aControllerIdx,
645
uint32_t aHapticIdx, double aIntensity,
646
ErrorResult& aRv) {
647
if (aControllerIdx >= kVRControllerMaxCount) {
648
aRv.Throw(NS_ERROR_INVALID_ARG);
649
return;
650
}
651
if (aHapticIdx >= kVRHapticsMaxCount) {
652
aRv.Throw(NS_ERROR_INVALID_ARG);
653
return;
654
}
655
// convert to 16.16 fixed point. This must match conversion in
656
// VRPuppetCommandBuffer::RunCommand
657
uint64_t iIntensity = round((float)aIntensity * (1 << 16));
658
if (iIntensity > 0xffffffff) {
659
iIntensity = 0xffffffff;
660
}
661
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitHapticIntensity |
662
((uint64_t)aControllerIdx << 40) | ((uint64_t)aHapticIdx << 32) |
663
iIntensity);
664
}
665
666
void VRServiceTest::WaitSubmit() {
667
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitSubmit);
668
}
669
670
void VRServiceTest::WaitPresentationStart() {
671
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitPresentationStart);
672
}
673
void VRServiceTest::WaitPresentationEnd() {
674
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitPresentationEnd);
675
}
676
677
void VRServiceTest::EncodeData() {
678
VRPuppetCommandBuffer::EncodeStruct(
679
mCommandBuffer, (uint8_t*)&mPendingState.displayState,
680
(uint8_t*)&mEncodedState.displayState, sizeof(VRDisplayState),
681
VRPuppet_Command::VRPuppet_UpdateDisplay);
682
VRPuppetCommandBuffer::EncodeStruct(
683
mCommandBuffer, (uint8_t*)&mPendingState.sensorState,
684
(uint8_t*)&mEncodedState.sensorState, sizeof(VRHMDSensorState),
685
VRPuppet_Command::VRPuppet_UpdateSensor);
686
VRPuppetCommandBuffer::EncodeStruct(
687
mCommandBuffer, (uint8_t*)&mPendingState.controllerState,
688
(uint8_t*)&mEncodedState.controllerState,
689
sizeof(VRControllerState) * kVRControllerMaxCount,
690
VRPuppet_Command::VRPuppet_UpdateControllers);
691
}
692
693
void VRServiceTest::CaptureFrame() {
694
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_CaptureFrame);
695
}
696
697
void VRServiceTest::AcknowledgeFrame() {
698
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_AcknowledgeFrame);
699
}
700
701
void VRServiceTest::RejectFrame() {
702
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_RejectFrame);
703
}
704
705
void VRServiceTest::StartTimer() {
706
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_StartTimer);
707
}
708
709
void VRServiceTest::StopTimer() {
710
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_StopTimer);
711
}
712
713
void VRServiceTest::Commit() {
714
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_Commit);
715
}
716
717
already_AddRefed<Promise> VRServiceTest::Run(ErrorResult& aRv) {
718
if (mShuttingDown) {
719
return nullptr;
720
}
721
722
AddCommand((uint64_t)VRPuppet_Command::VRPuppet_End);
723
724
RefPtr<dom::Promise> runPuppetPromise =
725
Promise::Create(mWindow->AsGlobal(), aRv);
726
if (NS_WARN_IF(aRv.Failed())) {
727
return nullptr;
728
}
729
730
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
731
vm->RunPuppet(mCommandBuffer, runPuppetPromise, aRv);
732
if (NS_WARN_IF(aRv.Failed())) {
733
return nullptr;
734
}
735
736
mCommandBuffer.Clear();
737
738
return runPuppetPromise.forget();
739
}
740
741
already_AddRefed<Promise> VRServiceTest::Reset(ErrorResult& aRv) {
742
if (mShuttingDown) {
743
return nullptr;
744
}
745
746
RefPtr<dom::Promise> resetPuppetPromise =
747
Promise::Create(mWindow->AsGlobal(), aRv);
748
if (NS_WARN_IF(aRv.Failed())) {
749
return nullptr;
750
}
751
752
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
753
vm->ResetPuppet(resetPuppetPromise, aRv);
754
if (NS_WARN_IF(aRv.Failed())) {
755
return nullptr;
756
}
757
758
memset(&mPendingState, 0, sizeof(VRSystemState));
759
memset(&mEncodedState, 0, sizeof(VRSystemState));
760
mCommandBuffer.Clear();
761
762
return resetPuppetPromise.forget();
763
}
764
765
} // namespace dom
766
} // namespace mozilla