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