Commit 1ff84516 authored by Bill Orr's avatar Bill Orr Committed by Commit Bot

Add an option to XRSessionCreationOptions to specify AR sessions

environmentIntegration is the new flag, which is now queried when
requesting sessions.  Plumbing to the browser process will happen in
a followup.

Now that both AR and VR can be supported simultaneously in tests,
WebXRHitTest is made experimental and the ar_hittest layout test passes.

BUG=828321

Change-Id: I4d8f13cc7c836c608d1f4d69d07813d163cea18f
Reviewed-on: https://chromium-review.googlesource.com/1132427
Commit-Queue: Bill Orr <billorr@chromium.org>
Reviewed-by: default avatarDavid Dorwin <ddorwin@chromium.org>
Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Reviewed-by: default avatarIan Vollick <vollick@chromium.org>
Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575911}
parent 677ac15f
...@@ -86,7 +86,7 @@ function onRequestSession() { ...@@ -86,7 +86,7 @@ function onRequestSession() {
break; break;
case sessionTypes.AR: case sessionTypes.AR:
let sessionOptions = { let sessionOptions = {
requestAR: true, environmentIntegration: true,
outputContext: webglCanvas.getContext('xrpresent'), outputContext: webglCanvas.getContext('xrpresent'),
}; };
xrDevice.requestSession(sessionOptions).then((session) => { xrDevice.requestSession(sessionOptions).then((session) => {
......
...@@ -9991,6 +9991,10 @@ interface XRFrameOfReference : XRCoordinateSystem ...@@ -9991,6 +9991,10 @@ interface XRFrameOfReference : XRCoordinateSystem
getter bounds getter bounds
getter emulatedHeight getter emulatedHeight
method constructor method constructor
interface XRHitResult
attribute @@toStringTag
getter hitMatrix
method constructor
interface XRInputPose interface XRInputPose
attribute @@toStringTag attribute @@toStringTag
getter emulatedPosition getter emulatedPosition
...@@ -10033,6 +10037,7 @@ interface XRSession : EventTarget ...@@ -10033,6 +10037,7 @@ interface XRSession : EventTarget
method getInputSources method getInputSources
method requestAnimationFrame method requestAnimationFrame
method requestFrameOfReference method requestFrameOfReference
method requestHitTest
setter baseLayer setter baseLayer
setter depthFar setter depthFar
setter depthNear setter depthNear
......
This is a testharness.js-based test.
FAIL Ensures hit-test returns expected mock results promise_test: Unhandled rejection with value: "Test failed while running with the following options:\n { immersive: false, outputContext: [object XRPresentationContext] } NotSupportedError: The specified session configuration is not supported."
Harness: the test ran to completion.
...@@ -18,7 +18,7 @@ promise_test( (t) => { ...@@ -18,7 +18,7 @@ promise_test( (t) => {
runWithUserGesture( () => { runWithUserGesture( () => {
resolve(promise_rejects( resolve(promise_rejects(
t, t,
"NotAllowedError", "NotSupportedError",
magicWindowOnlyDevice.requestSession({ immersive: true }) magicWindowOnlyDevice.requestSession({ immersive: true })
)) ))
}); });
......
...@@ -59,30 +59,12 @@ const char* XRDevice::checkSessionSupport( ...@@ -59,30 +59,12 @@ const char* XRDevice::checkSessionSupport(
} }
} }
// TODO(https://crbug.com/828321): Use session options instead of the flag. if (options.environmentIntegration() && !supports_ar_) {
bool is_ar = RuntimeEnabledFeatures::WebXRHitTestEnabled(); return kSessionNotSupported;
if (is_ar) { }
if (!supports_ar_) {
return kSessionNotSupported;
}
// Exclusive AR sessions aren't supported, but we could do exclusive without if (options.immersive() && !supports_immersive_) {
// AR. Since is_ar isn't based on options, assume for now that non-ar was return kSessionNotSupported;
// desired.
// TODO(https://crbug.com/828321): Actually use options to check for AR.
if (options.immersive()) {
return nullptr;
}
} else {
// TODO(https://crbug.com/828321): Remove this check when properly
// supporting multiple VRDevice registration.
if (supports_ar_) {
// We don't expect to get an AR-capable device, but it can happen in
// layout tests, due to mojo mocking. For now just reject the session
// request.
return kSessionNotSupported;
}
// TODO(https://crbug.com/828321): Check that VR is supported.
} }
return nullptr; return nullptr;
...@@ -178,8 +160,7 @@ ScriptPromise XRDevice::requestSession( ...@@ -178,8 +160,7 @@ ScriptPromise XRDevice::requestSession(
} }
// All AR sessions require a user gesture. // All AR sessions require a user gesture.
// TODO(https://crbug.com/828321): Use session options instead. if (options.environmentIntegration()) {
if (RuntimeEnabledFeatures::WebXRHitTestEnabled()) {
if (!has_user_activation) { if (!has_user_activation) {
return ScriptPromise::RejectWithDOMException( return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError, script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
...@@ -194,8 +175,7 @@ ScriptPromise XRDevice::requestSession( ...@@ -194,8 +175,7 @@ ScriptPromise XRDevice::requestSession(
device::mojom::blink::XRSessionOptions::New(); device::mojom::blink::XRSessionOptions::New();
session_options->immersive = options.immersive(); session_options->immersive = options.immersive();
session_options->provide_passthrough_camera = session_options->provide_passthrough_camera =
RuntimeEnabledFeatures::WebXRHitTestEnabled() && options.environmentIntegration();
!session_options->immersive;
session_options->has_user_activation = has_user_activation; session_options->has_user_activation = has_user_activation;
// TODO(offenwanger): Once device activation is sorted out for WebXR, either // TODO(offenwanger): Once device activation is sorted out for WebXR, either
...@@ -228,13 +208,13 @@ void XRDevice::OnRequestSessionReturned( ...@@ -228,13 +208,13 @@ void XRDevice::OnRequestSessionReturned(
} }
XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque; XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque;
// TODO(https://crbug.com/828321): Use session options instead of the flag. if (options.environmentIntegration()) {
if (RuntimeEnabledFeatures::WebXRHitTestEnabled()) {
blend_mode = XRSession::kBlendModeAlphaBlend; blend_mode = XRSession::kBlendModeAlphaBlend;
} }
XRSession* session = XRSession* session =
new XRSession(this, options.immersive(), output_context, blend_mode); new XRSession(this, options.immersive(), options.environmentIntegration(),
output_context, blend_mode);
sessions_.insert(session); sessions_.insert(session);
if (options.immersive()) { if (options.immersive()) {
......
...@@ -184,6 +184,15 @@ void XRFrameProvider::RequestFrame(XRSession* session) { ...@@ -184,6 +184,15 @@ void XRFrameProvider::RequestFrame(XRSession* session) {
ScheduleNonImmersiveFrame(); ScheduleNonImmersiveFrame();
} }
bool XRFrameProvider::HasARSession() {
for (unsigned i = 0; i < requesting_sessions_.size(); ++i) {
XRSession* session = requesting_sessions_.at(i).Get();
if (session->environmentIntegration())
return true;
}
return false;
}
void XRFrameProvider::ScheduleImmersiveFrame() { void XRFrameProvider::ScheduleImmersiveFrame() {
TRACE_EVENT0("gpu", __FUNCTION__); TRACE_EVENT0("gpu", __FUNCTION__);
if (pending_immersive_vsync_) if (pending_immersive_vsync_)
...@@ -228,8 +237,7 @@ void XRFrameProvider::ScheduleNonImmersiveFrame() { ...@@ -228,8 +237,7 @@ void XRFrameProvider::ScheduleNonImmersiveFrame() {
// with pass-through technology. // with pass-through technology.
// TODO(http://crbug.com/856257) Remove the special casing for AR and non-AR. // TODO(http://crbug.com/856257) Remove the special casing for AR and non-AR.
if (!device_->xrDisplayInfoPtr() if (!HasARSession()) {
->capabilities->can_provide_pass_through_images) {
doc->RequestAnimationFrame(new XRFrameProviderRequestCallback(this)); doc->RequestAnimationFrame(new XRFrameProviderRequestCallback(this));
} }
} }
...@@ -310,8 +318,7 @@ void XRFrameProvider::OnNonImmersiveFrameData( ...@@ -310,8 +318,7 @@ void XRFrameProvider::OnNonImmersiveFrameData(
double timestamp = frame_data->time_delta.InSecondsF(); double timestamp = frame_data->time_delta.InSecondsF();
if (device_->xrDisplayInfoPtr() if (HasARSession()) {
->capabilities->can_provide_pass_through_images) {
Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask( Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
FROM_HERE, FROM_HERE,
WTF::Bind(&XRFrameProvider::ProcessScheduledFrame, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
......
...@@ -57,6 +57,8 @@ class XRFrameProvider final ...@@ -57,6 +57,8 @@ class XRFrameProvider final
void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data, void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data,
double timestamp); double timestamp);
bool HasARSession();
const Member<XRDevice> device_; const Member<XRDevice> device_;
Member<XRSession> immersive_session_; Member<XRSession> immersive_session_;
Member<XRFrameTransport> frame_transport_; Member<XRFrameTransport> frame_transport_;
......
...@@ -91,10 +91,12 @@ class XRSession::XRSessionResizeObserverDelegate final ...@@ -91,10 +91,12 @@ class XRSession::XRSessionResizeObserverDelegate final
XRSession::XRSession(XRDevice* device, XRSession::XRSession(XRDevice* device,
bool immersive, bool immersive,
bool environment_integration,
XRPresentationContext* output_context, XRPresentationContext* output_context,
EnvironmentBlendMode environment_blend_mode) EnvironmentBlendMode environment_blend_mode)
: device_(device), : device_(device),
immersive_(immersive), immersive_(immersive),
environment_integration_(environment_integration),
output_context_(output_context), output_context_(output_context),
callback_collection_(new XRFrameRequestCallbackCollection( callback_collection_(new XRFrameRequestCallbackCollection(
device->xr()->GetExecutionContext())) { device->xr()->GetExecutionContext())) {
......
...@@ -46,12 +46,14 @@ class XRSession final : public EventTargetWithInlineData { ...@@ -46,12 +46,14 @@ class XRSession final : public EventTargetWithInlineData {
XRSession(XRDevice*, XRSession(XRDevice*,
bool immersive, bool immersive,
bool environment_integration,
XRPresentationContext* output_context, XRPresentationContext* output_context,
EnvironmentBlendMode environment_blend_mode); EnvironmentBlendMode environment_blend_mode);
~XRSession() override = default; ~XRSession() override = default;
XRDevice* device() const { return device_; } XRDevice* device() const { return device_; }
bool immersive() const { return immersive_; } bool immersive() const { return immersive_; }
bool environmentIntegration() const { return environment_integration_; }
XRPresentationContext* outputContext() const { return output_context_; } XRPresentationContext* outputContext() const { return output_context_; }
const String& environmentBlendMode() const { return blend_mode_string_; } const String& environmentBlendMode() const { return blend_mode_string_; }
...@@ -163,6 +165,7 @@ class XRSession final : public EventTargetWithInlineData { ...@@ -163,6 +165,7 @@ class XRSession final : public EventTargetWithInlineData {
const Member<XRDevice> device_; const Member<XRDevice> device_;
const bool immersive_; const bool immersive_;
const bool environment_integration_;
const Member<XRPresentationContext> output_context_; const Member<XRPresentationContext> output_context_;
String blend_mode_string_; String blend_mode_string_;
Member<XRLayer> base_layer_; Member<XRLayer> base_layer_;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
[ [
SecureContext SecureContext
] dictionary XRSessionCreationOptions { ] dictionary XRSessionCreationOptions {
[RuntimeEnabled=WebXRHitTest] boolean environmentIntegration = false;
boolean immersive = false; boolean immersive = false;
XRPresentationContext outputContext; XRPresentationContext outputContext;
}; };
...@@ -1413,6 +1413,7 @@ ...@@ -1413,6 +1413,7 @@
}, },
{ {
name: "WebXRHitTest", name: "WebXRHitTest",
status: "experimental"
}, },
{ {
name: "WindowPostMessageOptions", name: "WindowPostMessageOptions",
......
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