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
#ifndef mozilla_dom_VRDisplay_h_
8
#define mozilla_dom_VRDisplay_h_
9
10
#include <stdint.h>
11
12
#include "mozilla/ErrorResult.h"
13
#include "mozilla/dom/TypedArray.h"
14
#include "mozilla/dom/VRDisplayBinding.h"
15
#include "mozilla/DOMEventTargetHelper.h"
16
#include "mozilla/dom/DOMPoint.h"
17
#include "mozilla/dom/DOMRect.h"
18
#include "mozilla/dom/Pose.h"
19
#include "mozilla/TimeStamp.h"
20
21
#include "nsCOMPtr.h"
22
#include "nsString.h"
23
#include "nsTArray.h"
24
25
#include "gfxVR.h"
26
27
namespace mozilla {
28
namespace gfx {
29
class VRDisplayClient;
30
class VRDisplayPresentation;
31
struct VRFieldOfView;
32
enum class VRDisplayCapabilityFlags : uint16_t;
33
struct VRHMDSensorState;
34
} // namespace gfx
35
namespace dom {
36
class Navigator;
37
38
class VRFieldOfView final : public nsWrapperCache {
39
public:
40
VRFieldOfView(nsISupports* aParent, double aUpDegrees, double aRightDegrees,
41
double aDownDegrees, double aLeftDegrees);
42
VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc);
43
44
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfView)
45
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfView)
46
47
double UpDegrees() const { return mUpDegrees; }
48
double RightDegrees() const { return mRightDegrees; }
49
double DownDegrees() const { return mDownDegrees; }
50
double LeftDegrees() const { return mLeftDegrees; }
51
52
nsISupports* GetParentObject() const { return mParent; }
53
virtual JSObject* WrapObject(JSContext* aCx,
54
JS::Handle<JSObject*> aGivenProto) override;
55
56
protected:
57
virtual ~VRFieldOfView() {}
58
59
nsCOMPtr<nsISupports> mParent;
60
61
double mUpDegrees;
62
double mRightDegrees;
63
double mDownDegrees;
64
double mLeftDegrees;
65
};
66
67
class VRDisplayCapabilities final : public nsWrapperCache {
68
public:
69
VRDisplayCapabilities(nsISupports* aParent,
70
const gfx::VRDisplayCapabilityFlags& aFlags)
71
: mParent(aParent), mFlags(aFlags) {}
72
73
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRDisplayCapabilities)
74
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRDisplayCapabilities)
75
76
nsISupports* GetParentObject() const { return mParent; }
77
78
virtual JSObject* WrapObject(JSContext* aCx,
79
JS::Handle<JSObject*> aGivenProto) override;
80
81
bool HasPosition() const;
82
bool HasOrientation() const;
83
bool HasExternalDisplay() const;
84
bool CanPresent() const;
85
uint32_t MaxLayers() const;
86
87
protected:
88
~VRDisplayCapabilities() {}
89
nsCOMPtr<nsISupports> mParent;
90
gfx::VRDisplayCapabilityFlags mFlags;
91
};
92
93
class VRPose final : public Pose {
94
public:
95
VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
96
explicit VRPose(nsISupports* aParent);
97
98
virtual void GetPosition(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
99
ErrorResult& aRv) override;
100
virtual void GetLinearVelocity(JSContext* aCx,
101
JS::MutableHandle<JSObject*> aRetval,
102
ErrorResult& aRv) override;
103
virtual void GetLinearAcceleration(JSContext* aCx,
104
JS::MutableHandle<JSObject*> aRetval,
105
ErrorResult& aRv) override;
106
virtual void GetOrientation(JSContext* aCx,
107
JS::MutableHandle<JSObject*> aRetval,
108
ErrorResult& aRv) override;
109
virtual void GetAngularVelocity(JSContext* aCx,
110
JS::MutableHandle<JSObject*> aRetval,
111
ErrorResult& aRv) override;
112
virtual void GetAngularAcceleration(JSContext* aCx,
113
JS::MutableHandle<JSObject*> aRetval,
114
ErrorResult& aRv) override;
115
116
virtual JSObject* WrapObject(JSContext* aCx,
117
JS::Handle<JSObject*> aGivenProto) override;
118
119
void Update(const gfx::VRHMDSensorState& aState);
120
121
protected:
122
~VRPose();
123
124
gfx::VRHMDSensorState mVRState;
125
};
126
127
struct VRFrameInfo {
128
VRFrameInfo();
129
130
void Update(const gfx::VRDisplayInfo& aInfo,
131
const gfx::VRHMDSensorState& aState, float aDepthNear,
132
float aDepthFar);
133
134
void Clear();
135
bool IsDirty();
136
137
gfx::VRHMDSensorState mVRState;
138
gfx::Matrix4x4 mLeftProjection;
139
gfx::Matrix4x4 mLeftView;
140
gfx::Matrix4x4 mRightProjection;
141
gfx::Matrix4x4 mRightView;
142
143
/**
144
* In order to avoid leaking information related to the duration of
145
* the user's VR session, we re-base timestamps.
146
* mTimeStampOffset is added to the actual timestamp returned by the
147
* underlying VR platform API when returned through WebVR API's.
148
*/
149
double mTimeStampOffset;
150
};
151
152
class VRFrameData final : public nsWrapperCache {
153
public:
154
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFrameData)
155
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFrameData)
156
157
explicit VRFrameData(nsISupports* aParent);
158
static already_AddRefed<VRFrameData> Constructor(const GlobalObject& aGlobal);
159
160
void Update(const VRFrameInfo& aFrameInfo);
161
162
// WebIDL Members
163
double Timestamp() const;
164
void GetLeftProjectionMatrix(JSContext* aCx,
165
JS::MutableHandle<JSObject*> aRetval,
166
ErrorResult& aRv);
167
void GetLeftViewMatrix(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
168
ErrorResult& aRv);
169
void GetRightProjectionMatrix(JSContext* aCx,
170
JS::MutableHandle<JSObject*> aRetval,
171
ErrorResult& aRv);
172
void GetRightViewMatrix(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
173
ErrorResult& aRv);
174
175
VRPose* Pose();
176
177
// WebIDL Boilerplate
178
nsISupports* GetParentObject() const { return mParent; }
179
virtual JSObject* WrapObject(JSContext* aCx,
180
JS::Handle<JSObject*> aGivenProto) override;
181
182
protected:
183
~VRFrameData();
184
nsCOMPtr<nsISupports> mParent;
185
186
VRFrameInfo mFrameInfo;
187
RefPtr<VRPose> mPose;
188
JS::Heap<JSObject*> mLeftProjectionMatrix;
189
JS::Heap<JSObject*> mLeftViewMatrix;
190
JS::Heap<JSObject*> mRightProjectionMatrix;
191
JS::Heap<JSObject*> mRightViewMatrix;
192
193
void LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat,
194
JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
195
ErrorResult& aRv);
196
};
197
198
class VRStageParameters final : public nsWrapperCache {
199
public:
200
VRStageParameters(nsISupports* aParent,
201
const gfx::Matrix4x4& aSittingToStandingTransform,
202
const gfx::Size& aSize);
203
204
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRStageParameters)
205
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRStageParameters)
206
207
void GetSittingToStandingTransform(JSContext* aCx,
208
JS::MutableHandle<JSObject*> aRetval,
209
ErrorResult& aRv);
210
float SizeX() const { return mSize.width; }
211
float SizeZ() const { return mSize.height; }
212
213
nsISupports* GetParentObject() const { return mParent; }
214
virtual JSObject* WrapObject(JSContext* aCx,
215
JS::Handle<JSObject*> aGivenProto) override;
216
217
protected:
218
~VRStageParameters();
219
220
nsCOMPtr<nsISupports> mParent;
221
222
gfx::Matrix4x4 mSittingToStandingTransform;
223
JS::Heap<JSObject*> mSittingToStandingTransformArray;
224
gfx::Size mSize;
225
};
226
227
class VREyeParameters final : public nsWrapperCache {
228
public:
229
VREyeParameters(nsISupports* aParent, const gfx::Point3D& aEyeTranslation,
230
const gfx::VRFieldOfView& aFOV,
231
const gfx::IntSize& aRenderSize);
232
233
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
234
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
235
236
void GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal,
237
ErrorResult& aRv);
238
239
VRFieldOfView* FieldOfView();
240
241
uint32_t RenderWidth() const { return mRenderSize.width; }
242
uint32_t RenderHeight() const { return mRenderSize.height; }
243
244
nsISupports* GetParentObject() const { return mParent; }
245
virtual JSObject* WrapObject(JSContext* aCx,
246
JS::Handle<JSObject*> aGivenProto) override;
247
248
protected:
249
~VREyeParameters();
250
251
nsCOMPtr<nsISupports> mParent;
252
253
gfx::Point3D mEyeTranslation;
254
gfx::IntSize mRenderSize;
255
JS::Heap<JSObject*> mOffset;
256
RefPtr<VRFieldOfView> mFOV;
257
};
258
259
class VRDisplay final : public DOMEventTargetHelper, public nsIObserver {
260
public:
261
NS_DECL_ISUPPORTS_INHERITED
262
NS_DECL_NSIOBSERVER
263
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(VRDisplay, DOMEventTargetHelper)
264
265
virtual JSObject* WrapObject(JSContext* aCx,
266
JS::Handle<JSObject*> aGivenProto) override;
267
268
uint32_t PresentingGroups() const;
269
uint32_t GroupMask() const;
270
void SetGroupMask(const uint32_t& aGroupMask);
271
bool IsAnyPresenting(uint32_t aGroupMask) const;
272
bool IsPresenting() const;
273
bool IsConnected() const;
274
275
VRDisplayCapabilities* Capabilities();
276
VRStageParameters* GetStageParameters();
277
278
uint32_t DisplayId() const;
279
void GetDisplayName(nsAString& aDisplayName) const;
280
// Replacing the old VRDisplayClient with the newest one to avoid
281
// JS needs to reload to recover VRDisplay when VRService is shutdown at the
282
// backend.
283
void UpdateDisplayClient(already_AddRefed<gfx::VRDisplayClient> aClient);
284
285
static bool RefreshVRDisplays(uint64_t aWindowId);
286
static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays,
287
nsPIDOMWindowInner* aWindow);
288
289
gfx::VRDisplayClient* GetClient() { return mClient; }
290
291
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
292
293
bool GetFrameData(VRFrameData& aFrameData);
294
already_AddRefed<VRPose> GetPose();
295
void ResetPose();
296
297
double DepthNear() { return mDepthNear; }
298
299
double DepthFar() { return mDepthFar; }
300
301
void SetDepthNear(double aDepthNear) {
302
// XXX When we start sending depth buffers to VRLayer's we will want
303
// to communicate this with the VRDisplayHost
304
mDepthNear = aDepthNear;
305
}
306
307
void SetDepthFar(double aDepthFar) {
308
// XXX When we start sending depth buffers to VRLayer's we will want
309
// to communicate this with the VRDisplayHost
310
mDepthFar = aDepthFar;
311
}
312
313
already_AddRefed<Promise> RequestPresent(const nsTArray<VRLayer>& aLayers,
314
CallerType aCallerType,
315
ErrorResult& aRv);
316
already_AddRefed<Promise> ExitPresent(ErrorResult& aRv);
317
void GetLayers(nsTArray<VRLayer>& result);
318
void SubmitFrame();
319
320
int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
321
mozilla::ErrorResult& aError);
322
void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
323
void StartVRNavigation();
324
void StartHandlingVRNavigationEvent();
325
void StopHandlingVRNavigationEvent();
326
bool IsHandlingVRNavigationEvent();
327
void OnPresentationGenerationChanged();
328
329
protected:
330
VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient);
331
virtual ~VRDisplay();
332
virtual void LastRelease() override;
333
334
void ExitPresentInternal();
335
void Shutdown();
336
void UpdateFrameInfo();
337
338
RefPtr<gfx::VRDisplayClient> mClient;
339
340
RefPtr<VRDisplayCapabilities> mCapabilities;
341
RefPtr<VRStageParameters> mStageParameters;
342
343
double mDepthNear;
344
double mDepthFar;
345
346
RefPtr<gfx::VRDisplayPresentation> mPresentation;
347
348
/**
349
* The WebVR 1.1 spec Requires that VRDisplay.getPose and
350
* VRDisplay.getFrameData must return the same values until the next
351
* VRDisplay.submitFrame. mFrameInfo is updated only on the first call to
352
* either function within one frame. Subsequent calls before the next
353
* SubmitFrame or ExitPresent call will use these cached values.
354
*/
355
VRFrameInfo mFrameInfo;
356
357
// Time at which we began expecting VR navigation.
358
TimeStamp mHandlingVRNavigationEventStart;
359
int32_t mVRNavigationEventDepth;
360
bool mShutdown;
361
};
362
363
} // namespace dom
364
} // namespace mozilla
365
366
#endif