Auto merge of #17608 - MortimerGoro:webvr_11, r=jdm

WebVR 1.1 spec compatibility

<!-- Please describe your changes on the following line: -->

Servo WebVR implementation started when WebVR spec 1.2 was about to be released. 1.2 API included some minor breaking changes from spec 1.1 in order to improve the support of the API in WebWorkers.

But eventually the WebVR  committee decided not to release 1.2 and make it a major version number with a lot more changes. WebVR API 2.0 is still under heavy churn.

This PR removes the WebVR changes that non-released 1.2 version introduced to support full WebVR 1.1 spec.

I pushed some GC fixes in a separate commit. See https://github.com/servo/servo/issues/17076 and https://github.com/servo/rust-mozjs/issues/351

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17608)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-07-06 07:25:57 -07:00 committed by GitHub
commit ddd3a15b50
21 changed files with 142 additions and 69 deletions

View file

@ -20,6 +20,7 @@ use dom_struct::dom_struct;
use js::jsapi::{Heap, JSContext, JSObject};
use js::typedarray::{Float64Array, CreateWith};
use std::cell::Cell;
use std::ptr;
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
#[dom_struct]
@ -86,9 +87,13 @@ impl Gamepad {
data.display_id),
global,
GamepadBinding::Wrap);
let cx = global.get_cx();
rooted!(in (cx) let mut array = ptr::null_mut());
unsafe {
let _ = Float64Array::create(global.get_cx(), CreateWith::Slice(&state.axes), gamepad.axes.handle_mut());
let _ = Float64Array::create(cx, CreateWith::Slice(&state.axes), array.handle_mut());
}
gamepad.axes.set(array.get());
gamepad
}

View file

@ -503,6 +503,13 @@ macro_rules! window_event_handlers(
event_handler!(unhandledrejection, GetOnunhandledrejection,
SetOnunhandledrejection);
event_handler!(unload, GetOnunload, SetOnunload);
event_handler!(vrdisplayconnect, GetOnvrdisplayconnect, SetOnvrdisplayconnect);
event_handler!(vrdisplaydisconnect, GetOnvrdisplaydisconnect, SetOnvrdisplaydisconnect);
event_handler!(vrdisplayactivate, GetOnvrdisplayactivate, SetOnvrdisplayactivate);
event_handler!(vrdisplaydeactivate, GetOnvrdisplaydeactivate, SetOnvrdisplaydeactivate);
event_handler!(vrdisplayblur, GetOnvrdisplayblur, SetOnvrdisplayblur);
event_handler!(vrdisplayfocus, GetOnvrdisplayfocus, SetOnvrdisplayfocus);
event_handler!(vrdisplaypresentchange, GetOnvrdisplaypresentchange, SetOnvrdisplaypresentchange);
);
(ForwardToWindow) => (
window_owned_event_handler!(afterprint, GetOnafterprint,
@ -528,6 +535,14 @@ macro_rules! window_event_handlers(
window_owned_event_handler!(unhandledrejection, GetOnunhandledrejection,
SetOnunhandledrejection);
window_owned_event_handler!(unload, GetOnunload, SetOnunload);
window_owned_event_handler!(vrdisplayconnect, GetOnvrdisplayconnect, SetOnvrdisplayconnect);
window_owned_event_handler!(vrdisplaydisconnect, GetOnvrdisplaydisconnect, SetOnvrdisplaydisconnect);
window_owned_event_handler!(vrdisplayactivate, GetOnvrdisplayactivate, SetOnvrdisplayactivate);
window_owned_event_handler!(vrdisplaydeactivate, GetOnvrdisplaydeactivate, SetOnvrdisplaydeactivate);
window_owned_event_handler!(vrdisplayblur, GetOnvrdisplayblur, SetOnvrdisplayblur);
window_owned_event_handler!(vrdisplayfocus, GetOnvrdisplayfocus, SetOnvrdisplayfocus);
window_owned_event_handler!(vrdisplaypresentchange, GetOnvrdisplaypresentchange, SetOnvrdisplaypresentchange);
);
);

View file

@ -4,6 +4,7 @@
use dom::bindings::codegen::Bindings::NavigatorBinding;
use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
use dom::bindings::codegen::Bindings::VRBinding::VRBinding::VRMethods;
use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{Reflector, DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
@ -13,10 +14,12 @@ use dom::mimetypearray::MimeTypeArray;
use dom::navigatorinfo;
use dom::permissions::Permissions;
use dom::pluginarray::PluginArray;
use dom::promise::Promise;
use dom::serviceworkercontainer::ServiceWorkerContainer;
use dom::vr::VR;
use dom::window::Window;
use dom_struct::dom_struct;
use std::rc::Rc;
#[dom_struct]
pub struct Navigator {
@ -124,12 +127,6 @@ impl NavigatorMethods for Navigator {
true
}
#[allow(unrooted_must_root)]
// https://w3c.github.io/webvr/#interface-navigator
fn Vr(&self) -> Root<VR> {
self.vr.or_init(|| VR::new(&self.global()))
}
// https://www.w3.org/TR/gamepad/#navigator-interface-extension
fn GetGamepads(&self) -> Root<GamepadList> {
let root = self.gamepads.or_init(|| {
@ -145,4 +142,16 @@ impl NavigatorMethods for Navigator {
fn Permissions(&self) -> Root<Permissions> {
self.permissions.or_init(|| Permissions::new(&self.global()))
}
// https://w3c.github.io/webvr/spec/1.1/#navigator-getvrdisplays-attribute
#[allow(unrooted_must_root)]
fn GetVRDisplays(&self) -> Rc<Promise> {
self.Vr().GetDisplays()
}
}
impl Navigator {
pub fn Vr(&self) -> Root<VR> {
self.vr.or_init(|| VR::new(&self.global()))
}
}

View file

@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods;
use dom::bindings::error::Error;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::event::Event;
use dom::eventtarget::EventTarget;
use dom::gamepad::Gamepad;
@ -27,7 +27,7 @@ use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState};
#[dom_struct]
pub struct VR {
eventtarget: EventTarget,
reflector_: Reflector,
displays: DOMRefCell<Vec<JS<VRDisplay>>>,
gamepads: DOMRefCell<Vec<JS<Gamepad>>>
}
@ -35,7 +35,7 @@ pub struct VR {
impl VR {
fn new_inherited() -> VR {
VR {
eventtarget: EventTarget::new_inherited(),
reflector_: Reflector::new(),
displays: DOMRefCell::new(Vec::new()),
gamepads: DOMRefCell::new(Vec::new()),
}
@ -200,7 +200,7 @@ impl VR {
fn notify_display_event(&self, display: &VRDisplay, event: &WebVRDisplayEvent) {
let event = VRDisplayEvent::new_from_webvr(&self.global(), &display, &event);
event.upcast::<Event>().fire(self.upcast());
event.upcast::<Event>().fire(self.global().upcast::<EventTarget>());
}
}

View file

@ -11,6 +11,7 @@ use dom::bindings::codegen::Bindings::VRDisplayBinding;
use dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods;
use dom::bindings::codegen::Bindings::VRDisplayBinding::VREye;
use dom::bindings::codegen::Bindings::VRLayerBinding::VRLayer;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
use dom::bindings::codegen::Bindings::WindowBinding::FrameRequestCallback;
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::inheritance::Castable;
@ -391,6 +392,22 @@ impl VRDisplayMethods for VRDisplay {
let msg = VRCompositorCommand::SubmitFrame(display_id, layer.left_bounds, layer.right_bounds);
api_sender.send(CanvasMsg::WebVR(msg)).unwrap();
}
// https://w3c.github.io/webvr/spec/1.1/#dom-vrdisplay-getlayers
fn GetLayers(&self) -> Vec<VRLayer> {
// WebVR spec: MUST return an empty array if the VRDisplay is not currently presenting
if !self.presenting.get() {
return Vec::new();
}
let layer = self.layer.borrow();
vec![VRLayer {
leftBounds: Some(bounds_to_vec(&layer.left_bounds)),
rightBounds: Some(bounds_to_vec(&layer.right_bounds)),
source: self.layer_ctx.get().map(|ctx| ctx.Canvas()),
}]
}
}
impl VRDisplay {
@ -467,7 +484,7 @@ impl VRDisplay {
fn notify_event(&self, event: &WebVRDisplayEvent) {
let root = Root::from_ref(&*self);
let event = VRDisplayEvent::new_from_webvr(&self.global(), &root, &event);
event.upcast::<Event>().fire(self.upcast());
event.upcast::<Event>().fire(self.global().upcast::<EventTarget>());
}
fn init_present(&self) {
@ -643,3 +660,10 @@ fn validate_layer(cx: *mut JSContext,
Err("VRLayer source must be a WebGL Context")
}
}
fn bounds_to_vec(src: &[f32; 4]) -> Vec<Finite<f32>> {
vec![Finite::wrap(src[0]),
Finite::wrap(src[1]),
Finite::wrap(src[2]),
Finite::wrap(src[3])]
}

View file

@ -59,13 +59,13 @@ impl VRDisplayEvent {
event: &WebVRDisplayEvent)
-> Root<VRDisplayEvent> {
let (name, reason) = match *event {
WebVRDisplayEvent::Connect(_) => ("displayconnect", None),
WebVRDisplayEvent::Disconnect(_) => ("displaydisconnect", None),
WebVRDisplayEvent::Activate(_, reason) => ("activate", Some(reason)),
WebVRDisplayEvent::Deactivate(_, reason) => ("deactivate", Some(reason)),
WebVRDisplayEvent::Blur(_) => ("blur", None),
WebVRDisplayEvent::Focus(_) => ("focus", None),
WebVRDisplayEvent::PresentChange(_, _) => ("presentchange", None),
WebVRDisplayEvent::Connect(_) => ("vrdisplayconnect", None),
WebVRDisplayEvent::Disconnect(_) => ("vrdisplaydisconnect", None),
WebVRDisplayEvent::Activate(_, reason) => ("vrdisplayactivate", Some(reason)),
WebVRDisplayEvent::Deactivate(_, reason) => ("vrdisplaydeactivate", Some(reason)),
WebVRDisplayEvent::Blur(_) => ("vrdisplayblur", None),
WebVRDisplayEvent::Focus(_) => ("vrdisplayfocus", None),
WebVRDisplayEvent::PresentChange(_, _) => ("vrdisplaypresentchange", None),
WebVRDisplayEvent::Change(_) |
WebVRDisplayEvent::Pause(_) |
WebVRDisplayEvent::Resume(_) |

View file

@ -14,6 +14,7 @@ use dom_struct::dom_struct;
use js::jsapi::{Heap, JSContext, JSObject};
use js::typedarray::{Float32Array, CreateWith};
use std::default::Default;
use std::ptr;
use webvr_traits::WebVREyeParameters;
#[dom_struct]
@ -41,14 +42,16 @@ impl VREyeParameters {
pub fn new(parameters: WebVREyeParameters, global: &GlobalScope) -> Root<VREyeParameters> {
let fov = VRFieldOfView::new(&global, parameters.field_of_view.clone());
let cx = global.get_cx();
rooted!(in (cx) let mut array = ptr::null_mut());
unsafe {
let _ = Float32Array::create(cx, CreateWith::Slice(&parameters.offset), array.handle_mut());
}
let eye_parameters = reflect_dom_object(box VREyeParameters::new_inherited(parameters, &fov),
global,
VREyeParametersBinding::Wrap);
unsafe {
let _ = Float32Array::create(global.get_cx(),
CreateWith::Slice(&eye_parameters.parameters.borrow().offset),
eye_parameters.offset.handle_mut());
}
eye_parameters.offset.set(array.get());
eye_parameters
}

View file

@ -16,6 +16,7 @@ use dom_struct::dom_struct;
use js::jsapi::{Heap, JSContext, JSObject};
use js::typedarray::{Float32Array, CreateWith};
use std::cell::Cell;
use std::ptr;
use webvr_traits::WebVRFrameData;
#[dom_struct]
@ -72,9 +73,11 @@ impl VRFrameData {
#[allow(unsafe_code)]
fn create_typed_array(cx: *mut JSContext, src: &[f32], dst: &Heap<*mut JSObject>) {
rooted!(in (cx) let mut array = ptr::null_mut());
unsafe {
let _ = Float32Array::create(cx, CreateWith::Slice(src), dst.handle_mut());
let _ = Float32Array::create(cx, CreateWith::Slice(src), array.handle_mut());
}
(*dst).set(array.get());
}
impl VRFrameData {

View file

@ -32,7 +32,9 @@ unsafe fn update_or_create_typed_array(cx: *mut JSContext,
match src {
Some(data) => {
if dst.get().is_null() {
let _ = Float32Array::create(cx, CreateWith::Slice(data), dst.handle_mut());
rooted!(in (cx) let mut array = ptr::null_mut());
let _ = Float32Array::create(cx, CreateWith::Slice(data), array.handle_mut());
(*dst).set(array.get());
} else {
typedarray!(in(cx) let array: Float32Array = dst.get());
if let Ok(mut array) = array {

View file

@ -13,6 +13,7 @@ use dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::jsapi::{Heap, JSContext, JSObject};
use js::typedarray::{Float32Array, CreateWith};
use std::ptr;
use webvr_traits::WebVRStageParameters;
#[dom_struct]
@ -37,15 +38,17 @@ impl VRStageParameters {
#[allow(unsafe_code)]
pub fn new(parameters: WebVRStageParameters, global: &GlobalScope) -> Root<VRStageParameters> {
let cx = global.get_cx();
rooted!(in (cx) let mut array = ptr::null_mut());
unsafe {
let _ = Float32Array::create(cx, CreateWith::Slice(&parameters.sitting_to_standing_transform),
array.handle_mut());
}
let stage_parameters = reflect_dom_object(box VRStageParameters::new_inherited(parameters),
global,
VRStageParametersBinding::Wrap);
unsafe {
let source = &stage_parameters.parameters.borrow().sitting_to_standing_transform;
let _ = Float32Array::create(cx,
CreateWith::Slice(source),
stage_parameters.transform.handle_mut());
}
stage_parameters.transform.set(array.get());
stage_parameters
}

View file

@ -114,6 +114,17 @@ interface WindowEventHandlers {
attribute EventHandler onunload;
};
// https://w3c.github.io/webvr/spec/1.1/#interface-window
partial interface WindowEventHandlers {
attribute EventHandler onvrdisplayconnect;
attribute EventHandler onvrdisplaydisconnect;
attribute EventHandler onvrdisplayactivate;
attribute EventHandler onvrdisplaydeactivate;
attribute EventHandler onvrdisplayblur;
attribute EventHandler onvrdisplayfocus;
attribute EventHandler onvrdisplaypresentchange;
};
// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
[NoInterfaceObject, Exposed=Window]
interface DocumentAndElementEventHandlers {

View file

@ -58,9 +58,9 @@ interface NavigatorCookies {
readonly attribute boolean cookieEnabled;
};
// https://w3c.github.io/webvr/#interface-navigator
// https://w3c.github.io/webvr/spec/1.1/#interface-navigator
partial interface Navigator {
[SameObject, Pref="dom.webvr.enabled"] readonly attribute VR vr;
[Pref="dom.webvr.enabled"] Promise<sequence<VRDisplay>> getVRDisplays();
};
// https://w3c.github.io/permissions/#navigator-and-workernavigator-extension

View file

@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://w3c.github.io/webvr/#interface-navigator
[Pref="dom.webvr.enabled"]
interface VR: EventTarget {
[NoInterfaceObject]
interface VR {
Promise<sequence<VRDisplay>> getDisplays();
//readonly attribute FrozenArray<VRDisplay> activeVRDisplays;
};

View file

@ -119,7 +119,7 @@ interface VRDisplay : EventTarget {
/**
* Get the layers currently being presented.
*/
//sequence<VRLayer> getLayers();
sequence<VRLayer> getLayers();
/**
* The VRLayer provided to the VRDisplay will be captured and presented

View file

@ -27,7 +27,6 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
use dom::bindings::codegen::Bindings::EventBinding::EventInit;
use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
use dom::bindings::codegen::Bindings::TransitionEventBinding::TransitionEventInit;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};

View file

@ -168,10 +168,10 @@ found in the LICENSE file.
var frameData;
if (navigator.vr) {
if (navigator.getVRDisplays) {
frameData = new VRFrameData();
navigator.vr.getDisplays().then(function (displays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[0];
vrDisplay.depthNear = 0.1;
@ -190,9 +190,9 @@ found in the LICENSE file.
if (vrDisplay.capabilities.canPresent)
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
vrDisplay.addEventListener('presentchange', onVRPresentChange, false);
//vrDisplay.addEventListener('activate', onVRRequestPresent, false);
//vrDisplay.addEventListener('deactivate', onVRExitPresent, false);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
} else {
initWebGL();
VRSamplesUtil.addInfo("WebVR supported, but no VRDisplays found.", 3000);

View file

@ -175,10 +175,10 @@ found in the LICENSE file.
onResize();
}
if (navigator.vr) {
if (navigator.getVRDisplays) {
frameData = new VRFrameData();
navigator.vr.getDisplays().then(function (displays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[0];
VRSamplesUtil.addButton("Reset Pose", "R", null, function () { vrDisplay.resetPose(); });
@ -186,9 +186,9 @@ found in the LICENSE file.
if (vrDisplay.capabilities.canPresent)
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
vrDisplay.addEventListener('presentchange', onVRPresentChange, false);
//vrDisplay.addEventListener('activate', onVRRequestPresent, false);
//vrDisplay.addEventListener('deactivate', onVRExitPresent, false);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
initWebGL(vrDisplay.capabilities.hasExternalDisplay);
} else {

View file

@ -164,10 +164,10 @@ found in the LICENSE file.
}
}
if (navigator.vr) {
if (navigator.getVRDisplays) {
frameData = new VRFrameData();
navigator.vr.getDisplays().then(function (displays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[0];
vrDisplay.depthNear = 0.1;
@ -198,9 +198,9 @@ found in the LICENSE file.
if (vrDisplay.capabilities.canPresent)
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
vrDisplay.addEventListener('presentchange', onVRPresentChange, false);
//vrDisplay.addEventListener('activate', onVRRequestPresent, false);
//vrDisplay.addEventListener('deactivate', onVRExitPresent, false);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
} else {
initWebGL(false);
VRSamplesUtil.addInfo("WebVR supported, but no VRDisplays found.", 3000);

View file

@ -160,10 +160,10 @@ found in the LICENSE file.
}
}
if (navigator.vr) {
if (navigator.getVRDisplays) {
frameData = new VRFrameData();
navigator.vr.getDisplays().then(function (displays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[0];
vrDisplay.depthNear = 0.1;
@ -174,9 +174,9 @@ found in the LICENSE file.
if (vrDisplay.capabilities.canPresent)
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
vrDisplay.addEventListener('presentchange', onVRPresentChange, false);
//vrDisplay.addEventListener('activate', onVRRequestPresent, false);
//vrDisplay.addEventListener('deactivate', onVRExitPresent, false);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
// Only use preserveDrawingBuffer if we have an external display to
// mirror to.

View file

@ -192,10 +192,9 @@ found in the LICENSE file.
}
}
if (navigator.vr || navigator.getVRDisplays) {
if (navigator.getVRDisplays) {
frameData = new VRFrameData();
navigator.vr.getDisplays().then(function (displays) {
// navigator.getVRDisplays().then(function (displays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[displays.length - 1];
vrDisplay.depthNear = 0.1;
@ -214,9 +213,9 @@ found in the LICENSE file.
if (vrDisplay.capabilities.canPresent)
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
vrDisplay.addEventListener('presentchange', onVRPresentChange, false);
//vrDisplay.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
//vrDisplay.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
console.log(navigator.getGamepads());
setTimeout(function(){
onVRRequestPresent();

View file

@ -179,10 +179,10 @@ found in the LICENSE file.
}
}
if (navigator.vr) {
if (navigator.getVRDisplays) {
frameData = new VRFrameData();
navigator.vr.getDisplays().then(function (displays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[0];
@ -203,7 +203,7 @@ found in the LICENSE file.
// The UA may kick us out of VR present mode for any reason, so to
// ensure we always know when we begin/end presenting we need to
// listen for vrdisplaypresentchange events.
vrDisplay.addEventListener('presentchange', onVRPresentChange, false);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
// These events fire when the user agent has had some indication that
// it would be appropariate to enter or exit VR presentation mode, such
@ -211,8 +211,8 @@ found in the LICENSE file.
// You can inspect the `reason` property of the event to learn why the
// event was fired, but in this case we're going to always trust the
// event and enter or exit VR presentation mode when asked.
//vrDisplay.addEventListener('activate', onVRRequestPresent, false);
//vrDisplay.addEventListener('deactivate', onVRExitPresent, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
} else {
VRSamplesUtil.addInfo("WebVR supported, but no VRDisplays found.", 3000);
}