1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_VR_H
#define GFX_VR_H
#include "moz_external_vr.h"
#include "nsTArray.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Atomics.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TypedEnumBits.h"
#include <type_traits>
namespace mozilla {
namespace layers {
class PTextureParent;
}
namespace dom {
enum class GamepadMappingType : uint8_t;
enum class GamepadHand : uint8_t;
} // namespace dom
namespace gfx {
enum class VRAPIMode : uint8_t { WebXR, WebVR, NumVRAPIModes };
class VRLayerParent;
class VRDisplayHost;
class VRManagerPromise;
// The maximum number of frames of latency that we would expect before we
// should give up applying pose prediction.
// If latency is greater than one second, then the experience is not likely
// to be corrected by pose prediction. Setting this value too
// high may result in unnecessary memory allocation.
// As the current fastest refresh rate is 90hz, 100 is selected as a
// conservative value.
static const int kVRMaxLatencyFrames = 100;
struct VRDisplayInfo {
uint32_t mDisplayID;
uint32_t mPresentingGroups;
uint32_t mGroupMask;
uint64_t mFrameId;
VRDisplayState mDisplayState;
VRControllerState mControllerState[kVRControllerMaxCount];
VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames];
void Clear() { memset(this, 0, sizeof(VRDisplayInfo)); }
const VRHMDSensorState& GetSensorState() const {
return mLastSensorState[mFrameId % kVRMaxLatencyFrames];
}
uint32_t GetDisplayID() const { return mDisplayID; }
const char* GetDisplayName() const { return mDisplayState.displayName; }
VRDisplayCapabilityFlags GetCapabilities() const {
return mDisplayState.capabilityFlags;
}
const IntSize SuggestedEyeResolution() const;
const Point3D GetEyeTranslation(uint32_t whichEye) const;
const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const {
return mDisplayState.eyeFOV[whichEye];
}
bool GetIsConnected() const { return mDisplayState.isConnected; }
bool GetIsMounted() const { return mDisplayState.isMounted; }
uint32_t GetPresentingGroups() const { return mPresentingGroups; }
uint32_t GetGroupMask() const { return mGroupMask; }
const Size GetStageSize() const;
const Matrix4x4 GetSittingToStandingTransform() const;
uint64_t GetFrameId() const { return mFrameId; }
bool operator==(const VRDisplayInfo& other) const {
for (size_t i = 0; i < kVRMaxLatencyFrames; i++) {
if (mLastSensorState[i] != other.mLastSensorState[i]) {
return false;
}
}
// Note that mDisplayState and mControllerState are asserted to be POD
// types, so memcmp is safe
return mDisplayID == other.mDisplayID &&
memcmp(&mDisplayState, &other.mDisplayState,
sizeof(VRDisplayState)) == 0 &&
memcmp(mControllerState, other.mControllerState,
sizeof(VRControllerState) * kVRControllerMaxCount) == 0 &&
mPresentingGroups == other.mPresentingGroups &&
mGroupMask == other.mGroupMask && mFrameId == other.mFrameId;
}
bool operator!=(const VRDisplayInfo& other) const {
return !(*this == other);
}
};
static_assert(std::is_pod<VRDisplayInfo>::value,
"VRDisplayInfo must be a POD type.");
struct VRSubmitFrameResultInfo {
VRSubmitFrameResultInfo()
: mFormat(SurfaceFormat::UNKNOWN), mFrameNum(0), mWidth(0), mHeight(0) {}
nsCString mBase64Image;
SurfaceFormat mFormat;
uint64_t mFrameNum;
uint32_t mWidth;
uint32_t mHeight;
};
struct VRControllerInfo {
uint32_t GetControllerID() const { return mControllerID; }
const char* GetControllerName() const {
return mControllerState.controllerName;
}
dom::GamepadMappingType GetMappingType() const { return mMappingType; }
uint32_t GetDisplayID() const { return mDisplayID; }
dom::GamepadHand GetHand() const { return mControllerState.hand; }
uint32_t GetNumButtons() const { return mControllerState.numButtons; }
uint32_t GetNumAxes() const { return mControllerState.numAxes; }
uint32_t GetNumHaptics() const { return mControllerState.numHaptics; }
uint32_t mControllerID;
dom::GamepadMappingType mMappingType;
uint32_t mDisplayID;
VRControllerState mControllerState;
bool operator==(const VRControllerInfo& other) const {
// Note that mControllerState is asserted to be a POD type, so memcmp is
// safe
return mControllerID == other.mControllerID &&
memcmp(&mControllerState, &other.mControllerState,
sizeof(VRControllerState)) == 0 &&
mMappingType == other.mMappingType && mDisplayID == other.mDisplayID;
}
bool operator!=(const VRControllerInfo& other) const {
return !(*this == other);
}
};
struct VRTelemetry {
VRTelemetry() : mLastDroppedFrameCount(-1) {}
void Clear() {
mPresentationStart = TimeStamp();
mLastDroppedFrameCount = -1;
}
bool IsLastDroppedFrameValid() { return (mLastDroppedFrameCount != -1); }
TimeStamp mPresentationStart;
int32_t mLastDroppedFrameCount;
};
} // namespace gfx
} // namespace mozilla
#endif /* GFX_VR_H */
|