Commit 7b440d39 authored by Alex Cooper's avatar Alex Cooper Committed by Commit Bot

Support inline sessions when no device is present

Adds support for creating an inline session when no device is present.
Per the spec, inline sessions should be always guaranteed available
with the identity reference space.  This change both enables that
behavior and adds a test to guarantee that is the case.

Bug: 934354,933614
Change-Id: Id180b6f3916d611a1a4040e8479e882e25385963
Reviewed-on: https://chromium-review.googlesource.com/c/1481908Reviewed-by: default avatarBill Orr <billorr@chromium.org>
Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635718}
parent e567c7b0
...@@ -665,7 +665,10 @@ if (!is_android) { ...@@ -665,7 +665,10 @@ if (!is_android) {
] ]
# Common/partially common tests. # Common/partially common tests.
sources += [ "webxr_vr_transition_browser_test.cc" ] sources += [
"webxr_vr_spatial_tracking_test.cc",
"webxr_vr_transition_browser_test.cc",
]
# Common dependencies. # Common dependencies.
deps = [ deps = [
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/vr/test/webvr_browser_test.h"
#include "build/build_config.h"
#include "chrome/browser/vr/test/webxr_vr_browser_test.h"
#include "content/public/test/browser_test_utils.h"
namespace vr {
// Tests that WebXR can still get an inline identity reference space when there
// are no runtimes available.
IN_PROC_BROWSER_TEST_F(WebXrVrBrowserTestOpenVrDisabled,
TestInlineIdentityAlwaysAvailable) {
LoadUrlAndAwaitInitialization(
GetFileUrlForHtmlTestFile("test_inline_identity_available"));
WaitOnJavaScriptStep();
EndTest();
}
} // namespace vr
<!doctype html>
<!--
Tests that it is always possible to create an inline session and access the
identity reference space
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css">
</head>
<body>
<script src="../../../../../../third_party/blink/web_tests/resources/testharness.js"></script>
<script src="../resources/webxr_e2e.js"></script>
<script>
let session = null;
let testFrames = 5;
let numFramesReceived = 0;
function onRequestAnimationFrame() {
if (session === null) {
assert_unreached("Session should not be null");
}
numFramesReceived++;
if (numFramesReceived < testFrames) {
session.requestAnimationFrame(onRequestAnimationFrame);
} else {
done();
}
}
// TODO (crbug.com/934912): Consider improving flow once methods are
// updated.
let step = "supportsInline";
navigator.xr.supportsSessionMode('inline')
.then(()=> {
let outputCanvas = document.createElement('canvas');
let ctx = outputCanvas.getContext('xrpresent');
step = "requestSession";
return navigator.xr.requestSession({ outputContext: ctx });
})
.then((xrSession) => {
session = xrSession;
step = "requestReferenceSpace";
return xrSession.requestReferenceSpace({ type: 'identity' });
})
.then((referenceSpace) => {
assert_not_equals(referenceSpace, null);
step = "Request Animation Frames";
// Create an offscreen canvas and get its context
let offscreenCanvas = document.createElement('canvas');
let gl = offscreenCanvas.getContext('webgl', { xrCompatible: true });
if (!gl) {
throw 'Failed to get WebGL context';
}
session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
session.requestAnimationFrame(onRequestAnimationFrame);
})
.catch((err) => {
assert_unreached("Failed with " + err + " at step " + step);
});
</script>
</body>
</html>
...@@ -292,6 +292,15 @@ ScriptPromise XR::requestSession(ScriptState* script_state, ...@@ -292,6 +292,15 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
void XR::DispatchRequestSession(PendingSessionQuery* query) { void XR::DispatchRequestSession(PendingSessionQuery* query) {
if (!device_) { if (!device_) {
if (query->mode == XRSession::kModeInline) {
XRSession* session = MakeGarbageCollected<XRSession>(
this, nullptr /* client request */, query->mode,
query->output_context, XRSession::kBlendModeOpaque);
sessions_.insert(session);
query->resolver->Resolve(session);
return;
}
// If we don't have a device by the time we reach this call it indicates // If we don't have a device by the time we reach this call it indicates
// that there's no WebXR hardware. Reject as not supported. // that there's no WebXR hardware. Reject as not supported.
query->resolver->Reject(DOMException::Create( query->resolver->Reject(DOMException::Create(
......
...@@ -213,9 +213,6 @@ void XRFrameProvider::ScheduleNonImmersiveFrame() { ...@@ -213,9 +213,6 @@ void XRFrameProvider::ScheduleNonImmersiveFrame() {
TRACE_EVENT0("gpu", __FUNCTION__); TRACE_EVENT0("gpu", __FUNCTION__);
DCHECK(!immersive_session_) DCHECK(!immersive_session_)
<< "Scheduling should be done via the exclusive session if present."; << "Scheduling should be done via the exclusive session if present.";
DCHECK(xr_->xrMagicWindowProviderPtr())
<< "If there is no exclusive session, it should be impossible to "
"schedule a frame without a MagicWindowProvider.";
if (pending_non_immersive_vsync_) if (pending_non_immersive_vsync_)
return; return;
...@@ -232,8 +229,12 @@ void XRFrameProvider::ScheduleNonImmersiveFrame() { ...@@ -232,8 +229,12 @@ void XRFrameProvider::ScheduleNonImmersiveFrame() {
pending_non_immersive_vsync_ = true; pending_non_immersive_vsync_ = true;
xr_->xrMagicWindowProviderPtr()->GetFrameData(WTF::Bind( if (xr_->xrMagicWindowProviderPtr()) {
&XRFrameProvider::OnNonImmersiveFrameData, WrapWeakPersistent(this))); xr_->xrMagicWindowProviderPtr()->GetFrameData(WTF::Bind(
&XRFrameProvider::OnNonImmersiveFrameData, WrapWeakPersistent(this)));
} else {
OnNonImmersiveFrameData(nullptr);
}
// TODO(https://crbug.com/839253): Generalize the pass-through images // TODO(https://crbug.com/839253): Generalize the pass-through images
// code path so that it also works for immersive sessions on an AR device // code path so that it also works for immersive sessions on an AR device
...@@ -332,9 +333,14 @@ void XRFrameProvider::OnNonImmersiveFrameData( ...@@ -332,9 +333,14 @@ void XRFrameProvider::OnNonImmersiveFrameData(
return; return;
if (!frame_data) { if (!frame_data) {
// Unexpectedly didn't get frame data, and we don't have a timestamp. // Since we don't have any frame data, we will try to request a regular
// Try to request a regular animation frame to avoid getting stuck. // animation frame to avoid getting stuck.
DVLOG(1) << __FUNCTION__ << ": NO FRAME DATA!"; // If we have a MagicWindowProvider this is unexpected, and we should log
// for diagnostic purposes.
if (xr_->xrMagicWindowProviderPtr()) {
DVLOG(1) << __FUNCTION__ << ": NO FRAME DATA!";
}
frame_pose_ = nullptr; frame_pose_ = nullptr;
doc->RequestAnimationFrame( doc->RequestAnimationFrame(
MakeGarbageCollected<XRFrameProviderRequestCallback>(this)); MakeGarbageCollected<XRFrameProviderRequestCallback>(this));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment