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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "VRDisplayPresentation.h"
8 #include "mozilla/dom/DocGroup.h"
9 #include "mozilla/dom/Document.h"
10 #include "mozilla/dom/XRWebGLLayer.h"
11 #include "mozilla/Unused.h"
12 #include "VRDisplayClient.h"
13 #include "VRLayerChild.h"
15 using namespace mozilla
;
16 using namespace mozilla::gfx
;
18 VRDisplayPresentation::VRDisplayPresentation(
19 VRDisplayClient
* aDisplayClient
,
20 const nsTArray
<mozilla::dom::VRLayer
>& aLayers
, uint32_t aGroup
)
21 : mDisplayClient(aDisplayClient
),
22 mDOMLayers(aLayers
.Clone()),
27 void VRDisplayPresentation::UpdateLayers(
28 const nsTArray
<mozilla::dom::VRLayer
>& aLayers
) {
29 mDOMLayers
= aLayers
.Clone();
33 void VRDisplayPresentation::UpdateXRWebGLLayer(dom::XRWebGLLayer
* aLayer
) {
34 VRManagerChild
* manager
= VRManagerChild::Get();
36 // This should not happen, but let's log it and avoid a crash in case
38 NS_WARNING("VRManagerChild::Get returned null!");
42 dom::HTMLCanvasElement
* canvasElement
= aLayer
->GetCanvas();
44 if (mLayers
.Length() == 0) {
45 // WebXR uses a single layer for now.
46 RefPtr
<VRLayerChild
> vrLayer
=
47 static_cast<VRLayerChild
*>(manager
->CreateVRLayer(
48 mDisplayClient
->GetDisplayInfo().GetDisplayID(), mGroup
));
49 mLayers
.AppendElement(vrLayer
);
51 RefPtr
<VRLayerChild
> vrLayer
= mLayers
[0];
53 Rect
leftBounds(0.0, 0.0, 0.5, 1.0);
54 Rect
rightBounds(0.5, 0.0, 0.5, 1.0);
56 vrLayer
->Initialize(canvasElement
, leftBounds
, rightBounds
);
57 vrLayer
->SetXRFramebuffer(aLayer
->GetFramebuffer());
60 uint32_t VRDisplayPresentation::GetGroup() const { return mGroup
; }
62 void VRDisplayPresentation::CreateLayers() {
63 VRManagerChild
* manager
= VRManagerChild::Get();
65 // This should not happen, but let's log it and avoid a crash in case
67 NS_WARNING("VRManagerChild::Get returned null!");
71 unsigned int iLayer
= 0;
72 for (dom::VRLayer
& layer
: mDOMLayers
) {
73 dom::HTMLCanvasElement
* canvasElement
= layer
.mSource
;
75 /// XXX In the future we will support WebVR in WebWorkers here
79 Rect
leftBounds(0.0, 0.0, 0.5, 1.0);
80 if (layer
.mLeftBounds
.Length() == 4) {
81 leftBounds
.SetRect(layer
.mLeftBounds
[0], layer
.mLeftBounds
[1],
82 layer
.mLeftBounds
[2], layer
.mLeftBounds
[3]);
83 } else if (layer
.mLeftBounds
.Length() != 0) {
85 * We ignore layers with an incorrect number of values.
86 * In the future, VRDisplay.requestPresent may throw in
87 * this case. See https://github.com/w3c/webvr/issues/71
92 Rect
rightBounds(0.5, 0.0, 0.5, 1.0);
93 if (layer
.mRightBounds
.Length() == 4) {
94 rightBounds
.SetRect(layer
.mRightBounds
[0], layer
.mRightBounds
[1],
95 layer
.mRightBounds
[2], layer
.mRightBounds
[3]);
96 } else if (layer
.mRightBounds
.Length() != 0) {
98 * We ignore layers with an incorrect number of values.
99 * In the future, VRDisplay.requestPresent may throw in
100 * this case. See https://github.com/w3c/webvr/issues/71
105 if (mLayers
.Length() <= iLayer
) {
106 // Not enough layers, let's add one
107 RefPtr
<VRLayerChild
> vrLayer
=
108 static_cast<VRLayerChild
*>(manager
->CreateVRLayer(
109 mDisplayClient
->GetDisplayInfo().GetDisplayID(), mGroup
));
111 NS_WARNING("CreateVRLayer returned null!");
114 vrLayer
->Initialize(canvasElement
, leftBounds
, rightBounds
);
115 mLayers
.AppendElement(vrLayer
);
117 // We already have a layer, let's update it
118 mLayers
[iLayer
]->Initialize(canvasElement
, leftBounds
, rightBounds
);
123 // Truncate any excess layers that weren't included in the updated list
124 mLayers
.SetLength(iLayer
);
127 void VRDisplayPresentation::DestroyLayers() {
128 for (VRLayerChild
* layer
: mLayers
) {
129 if (layer
->IsIPCOpen()) {
130 Unused
<< layer
->SendDestroy();
136 void VRDisplayPresentation::GetDOMLayers(nsTArray
<dom::VRLayer
>& result
) {
137 result
= mDOMLayers
.Clone();
140 VRDisplayPresentation::~VRDisplayPresentation() {
142 mDisplayClient
->PresentationDestroyed();
145 void VRDisplayPresentation::SubmitFrame() {
146 // Currently only one layer supported, submit only the first
147 if (mLayers
.Length() >= 1) {
148 VRLayerChild
* layer
= mLayers
.ElementAt(0);
149 layer
->SubmitFrame(mDisplayClient
->GetDisplayInfo());