Skip to content

Commit

Permalink
Make vrdisplayactivate driven enter-vr path more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
dmarcos committed Mar 20, 2019
1 parent 789eed3 commit a3ac58e
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 29 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -50,7 +50,7 @@
"promise-polyfill": "^3.1.0",
"style-attr": "^1.0.2",
"super-animejs": "^3.0.0",
"super-three": "^0.102.1",
"super-three": "^0.102.2",
"three-bmfont-text": "^2.1.0",
"webvr-polyfill": "^0.10.10"
},
Expand Down
24 changes: 13 additions & 11 deletions src/core/scene/a-scene.js
Expand Up @@ -38,6 +38,7 @@ module.exports.AScene = registerElement('a-scene', {
prototype: Object.create(AEntity.prototype, {
createdCallback: {
value: function () {
this.clock = new THREE.Clock();
this.isIOS = isIOS;
this.isMobile = isMobile;
this.hasWebXR = isWebXRAvailable;
Expand Down Expand Up @@ -265,8 +266,8 @@ module.exports.AScene = registerElement('a-scene', {
// Has VR.
if (this.checkHeadsetConnected() || this.isMobile) {
vrDisplay = utils.device.getVRDisplay();
vrManager.setDevice(vrDisplay);
vrManager.enabled = true;
vrManager.setDevice(vrDisplay);

if (this.hasWebXR) {
// XR API.
Expand All @@ -286,17 +287,12 @@ module.exports.AScene = registerElement('a-scene', {
enterVRSuccess();
});
} else {
// WebVR API.
if (vrDisplay.isPresenting) {
enterVRSuccess();
return Promise.resolve();
}

var rendererSystem = this.getAttribute('renderer');
var presentationAttributes = {
highRefreshRate: rendererSystem.highRefreshRate,
foveationLevel: rendererSystem.foveationLevel
};

return vrDisplay.requestPresent([{
source: this.canvas,
attributes: presentationAttributes
Expand Down Expand Up @@ -326,6 +322,8 @@ module.exports.AScene = registerElement('a-scene', {
if (!self.isMobile && !self.checkHeadsetConnected()) {
requestFullscreen(self.canvas);
}

self.renderer.setAnimationLoop(self.render);
self.resize();
}

Expand Down Expand Up @@ -624,19 +622,23 @@ module.exports.AScene = registerElement('a-scene', {
}

this.addEventListener('loaded', function () {
var renderer = this.renderer;
var vrManager = this.renderer.vr;
AEntity.prototype.play.call(this); // .play() *before* render.

if (sceneEl.renderStarted) { return; }

sceneEl.resize();

// Kick off render loop.
if (sceneEl.renderer) {
if (window.performance) { window.performance.mark('render-started'); }
sceneEl.clock = new THREE.Clock();
loadingScreen.remove();
sceneEl.renderer.setAnimationLoop(this.render);
sceneEl.render();
if (utils.device.getVRDisplay().isPresenting) {
vrManager.setDevice(utils.device.getVRDisplay());
vrManager.enabled = true;
sceneEl.enterVR();
}
renderer.setAnimationLoop(this.render);
sceneEl.renderStarted = true;
sceneEl.emit('renderstart');
}
Expand Down
16 changes: 0 additions & 16 deletions src/core/scene/loadingScreen.js
Expand Up @@ -9,22 +9,6 @@ var getSceneCanvasSize;
var ATTR_NAME = 'loading-screen';
var LOADER_TITLE_CLASS = 'a-loader-title';

// It catches vrdisplayactivate early to ensure we can enter VR mode after the scene loads.
window.addEventListener('vrdisplayactivate', function () {
var vrManager = sceneEl.renderer.vr;
var vrDisplay;

// WebXR takes priority if available.
if (navigator.xr) { return; }

vrDisplay = utils.device.getVRDisplay();
vrManager.setDevice(vrDisplay);
vrManager.enabled = true;
if (!vrDisplay.isPresenting) {
return vrDisplay.requestPresent([{source: sceneEl.canvas}]).then(function () {}, function () {});
}
});

module.exports.setup = function setup (el, getCanvasSize) {
sceneEl = el;
getSceneCanvasSize = getCanvasSize;
Expand Down
11 changes: 11 additions & 0 deletions src/utils/device.js
Expand Up @@ -2,6 +2,17 @@ var error = require('debug')('device:error');

var vrDisplay;

// It catches vrdisplayactivate early to ensure we can enter VR mode after the scene loads.
window.addEventListener('vrdisplayactivate', function (evt) {
var canvasEl;
// WebXR takes priority if available.
if (navigator.xr) { return; }
canvasEl = document.createElement('canvas');
vrDisplay = evt.display;
// Request present immediately. a-scene will be allowed to enter VR without user gesture.
vrDisplay.requestPresent([{source: canvasEl}]).then(function () {}, function () {});
});

// Support both WebVR and WebXR APIs.
if (navigator.xr) {
navigator.xr.requestDevice().then(function (device) {
Expand Down
4 changes: 3 additions & 1 deletion tests/core/scene/a-scene.test.js
Expand Up @@ -141,7 +141,9 @@ suite('a-scene (without renderer)', function () {
getDevice: function () {},
setDevice: function () {},
setPoseTarget: function () {}
}
},
getContext: function () { return undefined; },
setAnimationLoop: function () {}
};

// mock camera
Expand Down

0 comments on commit a3ac58e

Please sign in to comment.