Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / vr / VRServiceTest.cpp
blob4e7691638d366cc871e10033a8a716a9b8d42f00
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/. */
7 #include "mozilla/dom/VRServiceTest.h"
8 #include "mozilla/dom/VRServiceTestBinding.h"
9 #include "mozilla/dom/GamepadPoseState.h"
10 #include "mozilla/dom/Promise.h"
11 #include "VRManagerChild.h"
12 #include "VRPuppetCommandBuffer.h"
13 #include <type_traits>
15 namespace mozilla {
16 using namespace gfx;
17 namespace dom {
19 NS_IMPL_CYCLE_COLLECTION_INHERITED(VRMockDisplay, DOMEventTargetHelper,
20 mVRServiceTest)
22 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(VRMockDisplay,
23 DOMEventTargetHelper)
25 namespace {
26 template <class T>
27 bool ReadFloat32Array(T& aDestination, const Float32Array& aSource,
28 ErrorResult& aRv) {
29 if (!aSource.CopyDataTo(aDestination)) {
30 aRv.Throw(NS_ERROR_INVALID_ARG);
31 // We don't want to MOZ_ASSERT here, as that would cause the
32 // browser to crash, making it difficult to debug the problem
33 // in JS code calling this API.
34 return false;
36 return true;
38 }; // anonymous namespace
40 VRMockDisplay::VRMockDisplay(VRServiceTest* aVRServiceTest)
41 : DOMEventTargetHelper(aVRServiceTest->GetOwner()),
42 mVRServiceTest(aVRServiceTest) {}
44 JSObject* VRMockDisplay::WrapObject(JSContext* aCx,
45 JS::Handle<JSObject*> aGivenProto) {
46 return VRMockDisplay_Binding::Wrap(aCx, this, aGivenProto);
49 VRHMDSensorState& VRMockDisplay::SensorState() const {
50 return mVRServiceTest->SystemState().sensorState;
53 VRDisplayState& VRMockDisplay::DisplayState() const {
54 return mVRServiceTest->SystemState().displayState;
57 void VRMockDisplay::Clear() {
58 VRDisplayState& displayState = DisplayState();
59 displayState.Clear();
60 VRHMDSensorState& sensorState = SensorState();
61 sensorState.Clear();
64 void VRMockDisplay::Create() {
65 Clear();
66 VRDisplayState& state = DisplayState();
68 strncpy(state.displayName, "Puppet HMD", kVRDisplayNameMaxLen);
69 state.eightCC = GFX_VR_EIGHTCC('P', 'u', 'p', 'p', 'e', 't', ' ', ' ');
70 state.isConnected = true;
71 state.isMounted = false;
72 state.capabilityFlags = VRDisplayCapabilityFlags::Cap_None |
73 VRDisplayCapabilityFlags::Cap_Orientation |
74 VRDisplayCapabilityFlags::Cap_Position |
75 VRDisplayCapabilityFlags::Cap_External |
76 VRDisplayCapabilityFlags::Cap_Present |
77 VRDisplayCapabilityFlags::Cap_StageParameters |
78 VRDisplayCapabilityFlags::Cap_MountDetection |
79 VRDisplayCapabilityFlags::Cap_ImmersiveVR;
80 state.blendMode = VRDisplayBlendMode::Opaque;
82 // 1836 x 2040 resolution is arbitrary and can be overridden.
83 // This default resolution was chosen to be within range of a
84 // typical VR eye buffer size. This value is derived by
85 // scaling a 1080x1200 per-eye panel resolution by the
86 // commonly used pre-lens-distortion pass scaling factor of 1.7x.
87 // 1.7x is commonly used in HMD's employing fresnel lenses to ensure
88 // a sufficient fragment shading rate in the peripheral area of the
89 // post-warp eye buffers.
90 state.eyeResolution.width = 1836; // 1080 * 1.7
91 state.eyeResolution.height = 2040; // 1200 * 1.7
93 for (uint32_t eye = 0; eye < VRDisplayState::NumEyes; ++eye) {
94 state.eyeTranslation[eye].x = 0.0f;
95 state.eyeTranslation[eye].y = 0.0f;
96 state.eyeTranslation[eye].z = 0.0f;
97 state.eyeFOV[eye] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
100 // default: 1m x 1m space, 0.75m high in seated position
101 state.stageSize.width = 1.0f;
102 state.stageSize.height = 1.0f;
104 state.sittingToStandingTransform[0] = 1.0f;
105 state.sittingToStandingTransform[1] = 0.0f;
106 state.sittingToStandingTransform[2] = 0.0f;
107 state.sittingToStandingTransform[3] = 0.0f;
109 state.sittingToStandingTransform[4] = 0.0f;
110 state.sittingToStandingTransform[5] = 1.0f;
111 state.sittingToStandingTransform[6] = 0.0f;
112 state.sittingToStandingTransform[7] = 0.0f;
114 state.sittingToStandingTransform[8] = 0.0f;
115 state.sittingToStandingTransform[9] = 0.0f;
116 state.sittingToStandingTransform[10] = 1.0f;
117 state.sittingToStandingTransform[11] = 0.0f;
119 state.sittingToStandingTransform[12] = 0.0f;
120 state.sittingToStandingTransform[13] = 0.75f;
121 state.sittingToStandingTransform[14] = 0.0f;
122 state.sittingToStandingTransform[15] = 1.0f;
124 VRHMDSensorState& sensorState = SensorState();
125 gfx::Quaternion rot;
126 sensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
127 sensorState.pose.orientation[0] = rot.x;
128 sensorState.pose.orientation[1] = rot.y;
129 sensorState.pose.orientation[2] = rot.z;
130 sensorState.pose.orientation[3] = rot.w;
131 sensorState.pose.angularVelocity[0] = 0.0f;
132 sensorState.pose.angularVelocity[1] = 0.0f;
133 sensorState.pose.angularVelocity[2] = 0.0f;
135 sensorState.flags |= VRDisplayCapabilityFlags::Cap_Position;
136 sensorState.pose.position[0] = 0.0f;
137 sensorState.pose.position[1] = 0.0f;
138 sensorState.pose.position[2] = 0.0f;
139 sensorState.pose.linearVelocity[0] = 0.0f;
140 sensorState.pose.linearVelocity[1] = 0.0f;
141 sensorState.pose.linearVelocity[2] = 0.0f;
144 void VRMockDisplay::SetConnected(bool aConnected) {
145 DisplayState().isConnected = aConnected;
147 bool VRMockDisplay::Connected() const { return DisplayState().isConnected; }
149 void VRMockDisplay::SetMounted(bool aMounted) {
150 DisplayState().isMounted = aMounted;
153 bool VRMockDisplay::Mounted() const { return DisplayState().isMounted; }
155 void VRMockDisplay::SetCapFlag(VRDisplayCapabilityFlags aFlag, bool aEnabled) {
156 if (aEnabled) {
157 DisplayState().capabilityFlags |= aFlag;
158 } else {
159 DisplayState().capabilityFlags &= ~aFlag;
162 bool VRMockDisplay::GetCapFlag(VRDisplayCapabilityFlags aFlag) const {
163 return ((DisplayState().capabilityFlags & aFlag) !=
164 VRDisplayCapabilityFlags::Cap_None);
167 void VRMockDisplay::SetCapPosition(bool aEnabled) {
168 SetCapFlag(VRDisplayCapabilityFlags::Cap_Position, aEnabled);
171 void VRMockDisplay::SetCapOrientation(bool aEnabled) {
172 SetCapFlag(VRDisplayCapabilityFlags::Cap_Orientation, aEnabled);
175 void VRMockDisplay::SetCapPresent(bool aEnabled) {
176 SetCapFlag(VRDisplayCapabilityFlags::Cap_Present, aEnabled);
179 void VRMockDisplay::SetCapExternal(bool aEnabled) {
180 SetCapFlag(VRDisplayCapabilityFlags::Cap_External, aEnabled);
183 void VRMockDisplay::SetCapAngularAcceleration(bool aEnabled) {
184 SetCapFlag(VRDisplayCapabilityFlags::Cap_AngularAcceleration, aEnabled);
187 void VRMockDisplay::SetCapLinearAcceleration(bool aEnabled) {
188 SetCapFlag(VRDisplayCapabilityFlags::Cap_LinearAcceleration, aEnabled);
191 void VRMockDisplay::SetCapStageParameters(bool aEnabled) {
192 SetCapFlag(VRDisplayCapabilityFlags::Cap_StageParameters, aEnabled);
195 void VRMockDisplay::SetCapMountDetection(bool aEnabled) {
196 SetCapFlag(VRDisplayCapabilityFlags::Cap_MountDetection, aEnabled);
199 void VRMockDisplay::SetCapPositionEmulated(bool aEnabled) {
200 SetCapFlag(VRDisplayCapabilityFlags::Cap_PositionEmulated, aEnabled);
203 void VRMockDisplay::SetEyeFOV(VREye aEye, double aUpDegree, double aRightDegree,
204 double aDownDegree, double aLeftDegree) {
205 gfx::VRDisplayState::Eye eye = aEye == VREye::Left
206 ? gfx::VRDisplayState::Eye_Left
207 : gfx::VRDisplayState::Eye_Right;
208 VRDisplayState& state = DisplayState();
209 state.eyeFOV[eye] =
210 gfx::VRFieldOfView(aUpDegree, aRightDegree, aDownDegree, aLeftDegree);
213 void VRMockDisplay::SetEyeOffset(VREye aEye, double aOffsetX, double aOffsetY,
214 double aOffsetZ) {
215 gfx::VRDisplayState::Eye eye = aEye == VREye::Left
216 ? gfx::VRDisplayState::Eye_Left
217 : gfx::VRDisplayState::Eye_Right;
218 VRDisplayState& state = DisplayState();
219 state.eyeTranslation[eye].x = (float)aOffsetX;
220 state.eyeTranslation[eye].y = (float)aOffsetY;
221 state.eyeTranslation[eye].z = (float)aOffsetZ;
224 bool VRMockDisplay::CapPosition() const {
225 return GetCapFlag(VRDisplayCapabilityFlags::Cap_Position);
228 bool VRMockDisplay::CapOrientation() const {
229 return GetCapFlag(VRDisplayCapabilityFlags::Cap_Orientation);
232 bool VRMockDisplay::CapPresent() const {
233 return GetCapFlag(VRDisplayCapabilityFlags::Cap_Present);
236 bool VRMockDisplay::CapExternal() const {
237 return GetCapFlag(VRDisplayCapabilityFlags::Cap_External);
240 bool VRMockDisplay::CapAngularAcceleration() const {
241 return GetCapFlag(VRDisplayCapabilityFlags::Cap_AngularAcceleration);
244 bool VRMockDisplay::CapLinearAcceleration() const {
245 return GetCapFlag(VRDisplayCapabilityFlags::Cap_LinearAcceleration);
248 bool VRMockDisplay::CapStageParameters() const {
249 return GetCapFlag(VRDisplayCapabilityFlags::Cap_StageParameters);
252 bool VRMockDisplay::CapMountDetection() const {
253 return GetCapFlag(VRDisplayCapabilityFlags::Cap_MountDetection);
256 bool VRMockDisplay::CapPositionEmulated() const {
257 return GetCapFlag(VRDisplayCapabilityFlags::Cap_PositionEmulated);
260 void VRMockDisplay::SetEyeResolution(uint32_t aRenderWidth,
261 uint32_t aRenderHeight) {
262 DisplayState().eyeResolution.width = aRenderWidth;
263 DisplayState().eyeResolution.height = aRenderHeight;
266 void VRMockDisplay::SetStageSize(double aWidth, double aHeight) {
267 VRDisplayState& displayState = DisplayState();
268 displayState.stageSize.width = (float)aWidth;
269 displayState.stageSize.height = (float)aHeight;
272 void VRMockDisplay::SetSittingToStandingTransform(
273 const Float32Array& aTransform, ErrorResult& aRv) {
274 Unused << ReadFloat32Array(DisplayState().sittingToStandingTransform,
275 aTransform, aRv);
278 void VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition,
279 const Nullable<Float32Array>& aLinearVelocity,
280 const Nullable<Float32Array>& aLinearAcceleration,
281 const Nullable<Float32Array>& aOrientation,
282 const Nullable<Float32Array>& aAngularVelocity,
283 const Nullable<Float32Array>& aAngularAcceleration,
284 ErrorResult& aRv) {
285 VRHMDSensorState& sensorState = mVRServiceTest->SystemState().sensorState;
286 sensorState.Clear();
287 sensorState.flags = VRDisplayCapabilityFlags::Cap_None;
288 // sensorState.timestamp will be set automatically during
289 // puppet script execution
291 if (!aOrientation.IsNull()) {
292 if (!ReadFloat32Array(sensorState.pose.orientation, aOrientation.Value(),
293 aRv)) {
294 return;
296 sensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
298 if (!aAngularVelocity.IsNull()) {
299 if (!ReadFloat32Array(sensorState.pose.angularVelocity,
300 aAngularVelocity.Value(), aRv)) {
301 return;
303 sensorState.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
305 if (!aAngularAcceleration.IsNull()) {
306 if (!ReadFloat32Array(sensorState.pose.angularAcceleration,
307 aAngularAcceleration.Value(), aRv)) {
308 return;
310 sensorState.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
312 if (!aPosition.IsNull()) {
313 if (!ReadFloat32Array(sensorState.pose.position, aPosition.Value(), aRv)) {
314 return;
316 sensorState.flags |= VRDisplayCapabilityFlags::Cap_Position;
318 if (!aLinearVelocity.IsNull()) {
319 if (!ReadFloat32Array(sensorState.pose.linearVelocity,
320 aLinearVelocity.Value(), aRv)) {
321 return;
323 sensorState.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
325 if (!aLinearAcceleration.IsNull()) {
326 if (!ReadFloat32Array(sensorState.pose.linearAcceleration,
327 aLinearAcceleration.Value(), aRv)) {
328 return;
330 sensorState.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
334 NS_IMPL_CYCLE_COLLECTION_INHERITED(VRMockController, DOMEventTargetHelper,
335 mVRServiceTest)
337 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(VRMockController,
338 DOMEventTargetHelper)
340 VRMockController::VRMockController(VRServiceTest* aVRServiceTest,
341 uint32_t aControllerIdx)
342 : DOMEventTargetHelper(aVRServiceTest->GetOwner()),
343 mVRServiceTest(aVRServiceTest),
344 mControllerIdx(aControllerIdx) {
345 MOZ_ASSERT(aControllerIdx < kVRControllerMaxCount);
348 JSObject* VRMockController::WrapObject(JSContext* aCx,
349 JS::Handle<JSObject*> aGivenProto) {
350 return VRMockController_Binding::Wrap(aCx, this, aGivenProto);
353 VRControllerState& VRMockController::ControllerState() const {
354 return mVRServiceTest->SystemState().controllerState[mControllerIdx];
357 void VRMockController::Create() {
358 // Initialize with a 6dof, left-handed gamepad with one haptic actuator
359 // Tests are expected to modify the controller before it is sent to the
360 // puppet.
361 Clear();
362 VRControllerState& state = ControllerState();
363 strncpy(state.controllerName, "Puppet Gamepad", kVRControllerNameMaxLen);
364 state.hand = GamepadHand::Left;
365 state.flags = GamepadCapabilityFlags::Cap_Position |
366 GamepadCapabilityFlags::Cap_Orientation;
367 state.numButtons = 1;
368 state.numHaptics = 1;
369 state.triggerValue[0] = 0.0f;
372 void VRMockController::Clear() {
373 mVRServiceTest->ClearController(mControllerIdx);
376 void VRMockController::SetCapFlag(GamepadCapabilityFlags aFlag, bool aEnabled) {
377 if (aEnabled) {
378 ControllerState().flags |= aFlag;
379 } else {
380 ControllerState().flags &= ~aFlag;
383 bool VRMockController::GetCapFlag(GamepadCapabilityFlags aFlag) const {
384 return (ControllerState().flags & aFlag) != GamepadCapabilityFlags::Cap_None;
387 void VRMockController::SetHand(GamepadHand aHand) {
388 ControllerState().hand = aHand;
391 GamepadHand VRMockController::Hand() const { return ControllerState().hand; }
393 void VRMockController::SetCapPosition(bool aEnabled) {
394 SetCapFlag(GamepadCapabilityFlags::Cap_Position, aEnabled);
397 bool VRMockController::CapPosition() const {
398 return GetCapFlag(GamepadCapabilityFlags::Cap_Position);
401 void VRMockController::SetCapOrientation(bool aEnabled) {
402 SetCapFlag(GamepadCapabilityFlags::Cap_Orientation, aEnabled);
405 bool VRMockController::CapOrientation() const {
406 return GetCapFlag(GamepadCapabilityFlags::Cap_Orientation);
409 void VRMockController::SetCapAngularAcceleration(bool aEnabled) {
410 SetCapFlag(GamepadCapabilityFlags::Cap_AngularAcceleration, aEnabled);
413 bool VRMockController::CapAngularAcceleration() const {
414 return GetCapFlag(GamepadCapabilityFlags::Cap_AngularAcceleration);
417 void VRMockController::SetCapLinearAcceleration(bool aEnabled) {
418 SetCapFlag(GamepadCapabilityFlags::Cap_LinearAcceleration, aEnabled);
421 bool VRMockController::CapLinearAcceleration() const {
422 return GetCapFlag(GamepadCapabilityFlags::Cap_LinearAcceleration);
425 void VRMockController::SetAxisCount(uint32_t aCount) {
426 MOZ_ASSERT(aCount <= kVRControllerMaxAxis);
427 ControllerState().numAxes = aCount;
430 uint32_t VRMockController::AxisCount() const {
431 return ControllerState().numAxes;
434 void VRMockController::SetButtonCount(uint32_t aCount) {
435 MOZ_ASSERT(aCount <= kVRControllerMaxButtons);
436 ControllerState().numButtons = aCount;
439 uint32_t VRMockController::ButtonCount() const {
440 return ControllerState().numButtons;
443 void VRMockController::SetHapticCount(uint32_t aCount) {
444 ControllerState().numHaptics = aCount;
447 uint32_t VRMockController::HapticCount() const {
448 return ControllerState().numHaptics;
451 void VRMockController::SetButtonPressed(uint32_t aButtonIdx, bool aPressed) {
452 MOZ_ASSERT(aButtonIdx < kVRControllerMaxButtons);
453 if (aPressed) {
454 ControllerState().buttonPressed |= (1 << aButtonIdx);
455 } else {
456 ControllerState().buttonPressed &= ~(1 << aButtonIdx);
460 void VRMockController::SetButtonTouched(uint32_t aButtonIdx, bool aTouched) {
461 MOZ_ASSERT(aButtonIdx < kVRControllerMaxButtons);
462 if (aTouched) {
463 ControllerState().buttonTouched |= (1 << aButtonIdx);
464 } else {
465 ControllerState().buttonTouched &= ~(1 << aButtonIdx);
469 void VRMockController::SetButtonTrigger(uint32_t aButtonIdx, double aTrigger) {
470 MOZ_ASSERT(aButtonIdx < kVRControllerMaxButtons);
472 ControllerState().triggerValue[aButtonIdx] = (float)aTrigger;
475 void VRMockController::SetAxisValue(uint32_t aAxisIdx, double aValue) {
476 MOZ_ASSERT(aAxisIdx < kVRControllerMaxAxis);
477 ControllerState().axisValue[aAxisIdx] = (float)aValue;
480 void VRMockController::SetPose(
481 const Nullable<Float32Array>& aPosition,
482 const Nullable<Float32Array>& aLinearVelocity,
483 const Nullable<Float32Array>& aLinearAcceleration,
484 const Nullable<Float32Array>& aOrientation,
485 const Nullable<Float32Array>& aAngularVelocity,
486 const Nullable<Float32Array>& aAngularAcceleration, ErrorResult& aRv) {
487 VRControllerState& controllerState = ControllerState();
488 controllerState.flags = GamepadCapabilityFlags::Cap_None;
490 if (!aOrientation.IsNull()) {
491 if (!ReadFloat32Array(controllerState.pose.orientation,
492 aOrientation.Value(), aRv)) {
493 return;
495 controllerState.flags |= GamepadCapabilityFlags::Cap_Orientation;
497 if (!aAngularVelocity.IsNull()) {
498 if (!ReadFloat32Array(controllerState.pose.angularVelocity,
499 aAngularVelocity.Value(), aRv)) {
500 return;
502 controllerState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
504 if (!aAngularAcceleration.IsNull()) {
505 if (!ReadFloat32Array(controllerState.pose.angularAcceleration,
506 aAngularAcceleration.Value(), aRv)) {
507 return;
509 controllerState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
511 if (!aPosition.IsNull()) {
512 if (!ReadFloat32Array(controllerState.pose.position, aPosition.Value(),
513 aRv)) {
514 return;
516 controllerState.flags |= GamepadCapabilityFlags::Cap_Position;
518 if (!aLinearVelocity.IsNull()) {
519 if (!ReadFloat32Array(controllerState.pose.linearVelocity,
520 aLinearVelocity.Value(), aRv)) {
521 return;
523 controllerState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
525 if (!aLinearAcceleration.IsNull()) {
526 if (!ReadFloat32Array(controllerState.pose.linearAcceleration,
527 aLinearAcceleration.Value(), aRv)) {
528 return;
530 controllerState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
534 NS_IMPL_CYCLE_COLLECTION_INHERITED(VRServiceTest, DOMEventTargetHelper,
535 mDisplay, mControllers, mWindow)
537 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(VRServiceTest,
538 DOMEventTargetHelper)
540 JSObject* VRServiceTest::WrapObject(JSContext* aCx,
541 JS::Handle<JSObject*> aGivenProto) {
542 return VRServiceTest_Binding::Wrap(aCx, this, aGivenProto);
545 // static
546 already_AddRefed<VRServiceTest> VRServiceTest::CreateTestService(
547 nsPIDOMWindowInner* aWindow) {
548 MOZ_ASSERT(aWindow);
549 RefPtr<VRServiceTest> service = new VRServiceTest(aWindow);
550 return service.forget();
553 VRServiceTest::VRServiceTest(nsPIDOMWindowInner* aWindow)
554 : mWindow(aWindow), mPendingState{}, mEncodedState{}, mShuttingDown(false) {
555 mDisplay = new VRMockDisplay(this);
556 for (int i = 0; i < kVRControllerMaxCount; i++) {
557 mControllers.AppendElement(new VRMockController(this, i));
559 ClearAll();
562 gfx::VRSystemState& VRServiceTest::SystemState() { return mPendingState; }
564 VRMockDisplay* VRServiceTest::GetVRDisplay() { return mDisplay; }
566 VRMockController* VRServiceTest::GetVRController(uint32_t aControllerIdx,
567 ErrorResult& aRv) {
568 if (aControllerIdx >= kVRControllerMaxCount) {
569 aRv.Throw(NS_ERROR_INVALID_ARG);
570 return nullptr;
572 return mControllers[aControllerIdx];
575 void VRServiceTest::Shutdown() {
576 MOZ_ASSERT(!mShuttingDown);
577 mShuttingDown = true;
578 mWindow = nullptr;
581 void VRServiceTest::AddCommand(uint64_t aCommand) {
582 EncodeData();
583 mCommandBuffer.AppendElement(aCommand);
586 void VRServiceTest::End() {
587 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_End);
590 void VRServiceTest::ClearAll() {
591 memset(&mPendingState, 0, sizeof(VRSystemState));
592 memset(&mEncodedState, 0, sizeof(VRSystemState));
593 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_ClearAll);
596 void VRServiceTest::ClearController(uint32_t aControllerIdx) {
597 MOZ_ASSERT(aControllerIdx < kVRControllerMaxCount);
598 mPendingState.controllerState[aControllerIdx].Clear();
599 mEncodedState.controllerState[aControllerIdx].Clear();
600 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_ClearController |
601 (uint64_t)aControllerIdx);
604 void VRServiceTest::Timeout(uint32_t aDuration) {
605 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_Timeout |
606 (uint64_t)aDuration);
609 void VRServiceTest::Wait(uint32_t aDuration) {
610 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_Wait | (uint64_t)aDuration);
613 void VRServiceTest::WaitHapticIntensity(uint32_t aControllerIdx,
614 uint32_t aHapticIdx, double aIntensity,
615 ErrorResult& aRv) {
616 if (aControllerIdx >= kVRControllerMaxCount) {
617 aRv.Throw(NS_ERROR_INVALID_ARG);
618 return;
620 if (aHapticIdx >= kVRHapticsMaxCount) {
621 aRv.Throw(NS_ERROR_INVALID_ARG);
622 return;
624 // convert to 16.16 fixed point. This must match conversion in
625 // VRPuppetCommandBuffer::RunCommand
626 uint64_t iIntensity = round((float)aIntensity * (1 << 16));
627 if (iIntensity > 0xffffffff) {
628 iIntensity = 0xffffffff;
630 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitHapticIntensity |
631 ((uint64_t)aControllerIdx << 40) | ((uint64_t)aHapticIdx << 32) |
632 iIntensity);
635 void VRServiceTest::WaitSubmit() {
636 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitSubmit);
639 void VRServiceTest::WaitPresentationStart() {
640 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitPresentationStart);
642 void VRServiceTest::WaitPresentationEnd() {
643 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_WaitPresentationEnd);
646 void VRServiceTest::EncodeData() {
647 VRPuppetCommandBuffer::EncodeStruct(
648 mCommandBuffer, (uint8_t*)&mPendingState.displayState,
649 (uint8_t*)&mEncodedState.displayState, sizeof(VRDisplayState),
650 VRPuppet_Command::VRPuppet_UpdateDisplay);
651 VRPuppetCommandBuffer::EncodeStruct(
652 mCommandBuffer, (uint8_t*)&mPendingState.sensorState,
653 (uint8_t*)&mEncodedState.sensorState, sizeof(VRHMDSensorState),
654 VRPuppet_Command::VRPuppet_UpdateSensor);
655 VRPuppetCommandBuffer::EncodeStruct(
656 mCommandBuffer, (uint8_t*)&mPendingState.controllerState,
657 (uint8_t*)&mEncodedState.controllerState,
658 sizeof(VRControllerState) * kVRControllerMaxCount,
659 VRPuppet_Command::VRPuppet_UpdateControllers);
662 void VRServiceTest::CaptureFrame() {
663 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_CaptureFrame);
666 void VRServiceTest::AcknowledgeFrame() {
667 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_AcknowledgeFrame);
670 void VRServiceTest::RejectFrame() {
671 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_RejectFrame);
674 void VRServiceTest::StartTimer() {
675 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_StartTimer);
678 void VRServiceTest::StopTimer() {
679 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_StopTimer);
682 void VRServiceTest::Commit() {
683 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_Commit);
686 already_AddRefed<Promise> VRServiceTest::Run(ErrorResult& aRv) {
687 if (mShuttingDown) {
688 return nullptr;
691 AddCommand((uint64_t)VRPuppet_Command::VRPuppet_End);
693 RefPtr<dom::Promise> runPuppetPromise =
694 Promise::Create(mWindow->AsGlobal(), aRv);
695 if (NS_WARN_IF(aRv.Failed())) {
696 return nullptr;
699 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
700 vm->RunPuppet(mCommandBuffer, runPuppetPromise, aRv);
701 if (NS_WARN_IF(aRv.Failed())) {
702 return nullptr;
705 mCommandBuffer.Clear();
707 return runPuppetPromise.forget();
710 already_AddRefed<Promise> VRServiceTest::Reset(ErrorResult& aRv) {
711 if (mShuttingDown) {
712 return nullptr;
715 RefPtr<dom::Promise> resetPuppetPromise =
716 Promise::Create(mWindow->AsGlobal(), aRv);
717 if (NS_WARN_IF(aRv.Failed())) {
718 return nullptr;
721 gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
722 vm->ResetPuppet(resetPuppetPromise, aRv);
723 if (NS_WARN_IF(aRv.Failed())) {
724 return nullptr;
727 memset(&mPendingState, 0, sizeof(VRSystemState));
728 memset(&mEncodedState, 0, sizeof(VRSystemState));
729 mCommandBuffer.Clear();
731 return resetPuppetPromise.forget();
734 } // namespace dom
735 } // namespace mozilla