Commit fee9f198 authored by Max Rebuschatis's avatar Max Rebuschatis Committed by Commit Bot

Reland "Make XR FrameData and Environment mojo associated"

This is a reland of 126a1168

The fix in this change addresses compile errors on the
Oculus platform.

TBR=dcheng@chromium.org
dcheng@chromium.org: please review, though there are no
new changes to vr_service.mojom

Original change's description:
> Make XR FrameData and Environment mojo associated
>
> The XRFrameDataProvider now returns an associated
> XREnvironmentDataProvider interface so that the
> two share callback queues and thus allow strict
> ordering of the two interfaces. This is critical
> for frame synchronization between frames and the
> associated environment data.
>
> Note: We can't just mark the interfaceptrs for
> XRFrameDataProvider and
> XREnvironmentIntegrationProvider as associated
> in the XRSession struct. XRDevice implementations
> mostly live on separate threads from the
> XRFrameDataProviders, so we'd have extra thread
> hopping. For the VR headsets we explicitly live
> off the main thread to avoid latency, and because
> we do some work that may block the thread the
> XRFrameDataProvider lives on (for example waiting
> for vsync, or submitting frames to headset APIs).
>
> Bug: 867057, 876135, 843376
> Change-Id: If2fb62fcd185825209dec08e421df05f34d41c30
> Reviewed-on: https://chromium-review.googlesource.com/c/1171794
> Commit-Queue: Max Rebuschatis <lincolnfrog@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Bill Orr <billorr@chromium.org>
> Reviewed-by: Klaus Weidner <klausw@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#605545}

Bug: 867057, 876135, 843376
Change-Id: If76578ebabbb40d03a21f6f557c5d4c27f69fc38
Reviewed-on: https://chromium-review.googlesource.com/c/1324089
Commit-Queue: Max Rebuschatis <lincolnfrog@chromium.org>
Reviewed-by: default avatarBill Orr <billorr@chromium.org>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606643}
parent 683a25ac
...@@ -42,7 +42,7 @@ mojom::VRDisplayInfoPtr CreateVRDisplayInfo(mojom::XRDeviceId device_id) { ...@@ -42,7 +42,7 @@ mojom::VRDisplayInfoPtr CreateVRDisplayInfo(mojom::XRDeviceId device_id) {
device->capabilities->hasPosition = true; device->capabilities->hasPosition = true;
device->capabilities->hasExternalDisplay = false; device->capabilities->hasExternalDisplay = false;
device->capabilities->canPresent = false; device->capabilities->canPresent = false;
device->capabilities->can_provide_pass_through_images = true; device->capabilities->canProvideEnvironmentIntegration = true;
device->leftEye = mojom::VREyeParameters::New(); device->leftEye = mojom::VREyeParameters::New();
device->rightEye = nullptr; device->rightEye = nullptr;
mojom::VREyeParametersPtr& left_eye = device->leftEye; mojom::VREyeParametersPtr& left_eye = device->leftEye;
...@@ -306,15 +306,12 @@ void ArCoreDevice::CallDeferredRequestSessionCallbacks(bool success) { ...@@ -306,15 +306,12 @@ void ArCoreDevice::CallDeferredRequestSessionCallbacks(bool success) {
mojom::XRSessionPtr session; mojom::XRSessionPtr session;
if (success) { if (success) {
mojom::XRFrameDataProviderPtr data_provider; mojom::XRFrameDataProviderPtr data_provider;
mojom::XREnvironmentIntegrationProviderPtr environment_provider;
magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>( magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>(
this, mojo::MakeRequest(&data_provider), this, mojo::MakeRequest(&data_provider),
mojo::MakeRequest(&environment_provider),
mojo::MakeRequest(&controller))); mojo::MakeRequest(&controller)));
session = mojom::XRSession::New(); session = mojom::XRSession::New();
session->data_provider = data_provider.PassInterface(); session->data_provider = data_provider.PassInterface();
session->environment_provider = environment_provider.PassInterface();
session->display_info = display_info_.Clone(); session->display_info = display_info_.Clone();
} }
// We don't expect this call to alter deferred_request_session_callbacks_. // We don't expect this call to alter deferred_request_session_callbacks_.
......
...@@ -157,7 +157,8 @@ class ArCoreDeviceTest : public testing::Test { ...@@ -157,7 +157,8 @@ class ArCoreDeviceTest : public testing::Test {
controller_->SetFrameDataRestricted(false); controller_->SetFrameDataRestricted(false);
frame_provider.Bind(std::move(session_->data_provider)); frame_provider.Bind(std::move(session_->data_provider));
environment_provider.Bind(std::move(session_->environment_provider)); frame_provider->GetEnvironmentIntegrationProvider(
mojo::MakeRequest(&environment_provider));
std::move(quit_closure).Run(); std::move(quit_closure).Run();
} }
...@@ -165,7 +166,7 @@ class ArCoreDeviceTest : public testing::Test { ...@@ -165,7 +166,7 @@ class ArCoreDeviceTest : public testing::Test {
StubArCoreInstallUtils* install_utils; StubArCoreInstallUtils* install_utils;
StubArCorePermissionHelper* permission_helper; StubArCorePermissionHelper* permission_helper;
mojom::XRFrameDataProviderPtr frame_provider; mojom::XRFrameDataProviderPtr frame_provider;
mojom::XREnvironmentIntegrationProviderPtr environment_provider; mojom::XREnvironmentIntegrationProviderAssociatedPtr environment_provider;
std::unique_ptr<base::RunLoop> run_loop; std::unique_ptr<base::RunLoop> run_loop;
base::OnceClosure quit_closure; base::OnceClosure quit_closure;
......
...@@ -1261,4 +1261,12 @@ void GvrSchedulerDelegate::ProcessWebVrFrameFromGMB( ...@@ -1261,4 +1261,12 @@ void GvrSchedulerDelegate::ProcessWebVrFrameFromGMB(
WebXrTryStartAnimatingFrame(false); WebXrTryStartAnimatingFrame(false);
} }
void GvrSchedulerDelegate::GetEnvironmentIntegrationProvider(
device::mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) {
// Environment integration is not supported. This call should not
// be made on this device.
mojo::ReportBadMessage("Environment integration is not supported.");
}
} // namespace vr } // namespace vr
...@@ -133,6 +133,9 @@ class GvrSchedulerDelegate : public BaseSchedulerDelegate, ...@@ -133,6 +133,9 @@ class GvrSchedulerDelegate : public BaseSchedulerDelegate,
// XRFrameDataProvider // XRFrameDataProvider
void GetFrameData(device::mojom::XRFrameDataProvider::GetFrameDataCallback void GetFrameData(device::mojom::XRFrameDataProvider::GetFrameDataCallback
callback) override; callback) override;
void GetEnvironmentIntegrationProvider(
device::mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) override;
// XRPresentationProvider // XRPresentationProvider
void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override; void SubmitFrameMissing(int16_t frame_index, const gpu::SyncToken&) override;
......
...@@ -44,8 +44,7 @@ device::mojom::XRRuntimeSessionOptionsPtr GetRuntimeOptions( ...@@ -44,8 +44,7 @@ device::mojom::XRRuntimeSessionOptionsPtr GetRuntimeOptions(
device::mojom::XRRuntimeSessionOptions::New(); device::mojom::XRRuntimeSessionOptions::New();
runtime_options->immersive = options->immersive; runtime_options->immersive = options->immersive;
runtime_options->has_user_activation = options->has_user_activation; runtime_options->has_user_activation = options->has_user_activation;
runtime_options->provide_passthrough_camera = runtime_options->environment_integration = options->environment_integration;
options->provide_passthrough_camera;
runtime_options->use_legacy_webvr_render_path = runtime_options->use_legacy_webvr_render_path =
options->use_legacy_webvr_render_path; options->use_legacy_webvr_render_path;
return runtime_options; return runtime_options;
......
...@@ -150,11 +150,20 @@ BrowserXRRuntime* XRRuntimeManager::GetRuntime(device::mojom::XRDeviceId id) { ...@@ -150,11 +150,20 @@ BrowserXRRuntime* XRRuntimeManager::GetRuntime(device::mojom::XRDeviceId id) {
BrowserXRRuntime* XRRuntimeManager::GetRuntimeForOptions( BrowserXRRuntime* XRRuntimeManager::GetRuntimeForOptions(
device::mojom::XRSessionOptions* options) { device::mojom::XRSessionOptions* options) {
// Examine options to determine which device provider we should use. // Examine options to determine which device provider we should use.
if (options->immersive && !options->provide_passthrough_camera) {
return GetImmersiveRuntime(); // AR requested.
} else if (options->provide_passthrough_camera && !options->immersive) { if (options->environment_integration) {
if (options->immersive) {
// No support for immersive AR.
return nullptr;
}
// Return the ARCore device.
return GetRuntime(device::mojom::XRDeviceId::ARCORE_DEVICE_ID); return GetRuntime(device::mojom::XRDeviceId::ARCORE_DEVICE_ID);
} else if (!options->provide_passthrough_camera && !options->immersive) { }
if (options->immersive) {
return GetImmersiveRuntime();
} else {
// Non immersive session. // Non immersive session.
// Try the orientation provider if it exists. // Try the orientation provider if it exists.
auto* orientation_runtime = auto* orientation_runtime =
...@@ -166,7 +175,6 @@ BrowserXRRuntime* XRRuntimeManager::GetRuntimeForOptions( ...@@ -166,7 +175,6 @@ BrowserXRRuntime* XRRuntimeManager::GetRuntimeForOptions(
// Otherwise fall back to immersive providers. // Otherwise fall back to immersive providers.
return GetImmersiveRuntime(); return GetImmersiveRuntime();
} }
return nullptr;
} }
BrowserXRRuntime* XRRuntimeManager::GetImmersiveRuntime() { BrowserXRRuntime* XRRuntimeManager::GetImmersiveRuntime() {
...@@ -208,7 +216,7 @@ device::mojom::VRDisplayInfoPtr XRRuntimeManager::GetCurrentVRDisplayInfo( ...@@ -208,7 +216,7 @@ device::mojom::VRDisplayInfoPtr XRRuntimeManager::GetCurrentVRDisplayInfo(
// Get an AR device if there is one. // Get an AR device if there is one.
device::mojom::XRSessionOptions options = {}; device::mojom::XRSessionOptions options = {};
options.provide_passthrough_camera = true; options.environment_integration = true;
auto* ar_runtime = GetRuntimeForOptions(&options); auto* ar_runtime = GetRuntimeForOptions(&options);
if (ar_runtime) { if (ar_runtime) {
// Listen to changes for this device. // Listen to changes for this device.
...@@ -230,12 +238,10 @@ device::mojom::VRDisplayInfoPtr XRRuntimeManager::GetCurrentVRDisplayInfo( ...@@ -230,12 +238,10 @@ device::mojom::VRDisplayInfoPtr XRRuntimeManager::GetCurrentVRDisplayInfo(
: nullptr; : nullptr;
} }
// Use the immersive or AR device. However, if we are using the immersive // Use the immersive or AR device.
// device's info, and AR is supported, reflect that in capabilities.
device::mojom::VRDisplayInfoPtr device_info = device::mojom::VRDisplayInfoPtr device_info =
immersive_runtime ? immersive_runtime->GetVRDisplayInfo() immersive_runtime ? immersive_runtime->GetVRDisplayInfo()
: ar_runtime->GetVRDisplayInfo(); : ar_runtime->GetVRDisplayInfo();
device_info->capabilities->can_provide_pass_through_images = !!ar_runtime;
return device_info; return device_info;
} }
......
...@@ -141,7 +141,7 @@ TEST_F(XRRuntimeManagerTest, AddRemoveDevices) { ...@@ -141,7 +141,7 @@ TEST_F(XRRuntimeManagerTest, AddRemoveDevices) {
Provider()->AddDevice(base::WrapUnique(device)); Provider()->AddDevice(base::WrapUnique(device));
device::mojom::XRSessionOptions options = {}; device::mojom::XRSessionOptions options = {};
options.provide_passthrough_camera = true; options.environment_integration = true;
EXPECT_TRUE(DeviceManager()->GetRuntimeForOptions(&options)); EXPECT_TRUE(DeviceManager()->GetRuntimeForOptions(&options));
Provider()->RemoveDevice(device->GetId()); Provider()->RemoveDevice(device->GetId());
EXPECT_TRUE(!DeviceManager()->GetRuntimeForOptions(&options)); EXPECT_TRUE(!DeviceManager()->GetRuntimeForOptions(&options));
......
...@@ -80,6 +80,15 @@ mojom::XRGamepadDataPtr OculusRenderLoop::GetNextGamepadData() { ...@@ -80,6 +80,15 @@ mojom::XRGamepadDataPtr OculusRenderLoop::GetNextGamepadData() {
return OculusGamepadHelper::GetGamepadData(session_); return OculusGamepadHelper::GetGamepadData(session_);
} }
void OculusRenderLoop::GetEnvironmentIntegrationProvider(
mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) {
// Environment integration is not supported. This call should not
// be made on this device.
mojo::ReportBadMessage("Environment integration is not supported.");
return;
}
bool OculusRenderLoop::StartRuntime() { bool OculusRenderLoop::StartRuntime() {
if (!session_) { if (!session_) {
ovrInitParams initParams = {ovrInit_RequestVersion | ovrInit_MixedRendering, ovrInitParams initParams = {ovrInit_RequestVersion | ovrInit_MixedRendering,
......
...@@ -33,6 +33,9 @@ class OculusRenderLoop : public XRCompositorCommon { ...@@ -33,6 +33,9 @@ class OculusRenderLoop : public XRCompositorCommon {
// XRDeviceAbstraction: // XRDeviceAbstraction:
mojom::XRFrameDataPtr GetNextFrameData() override; mojom::XRFrameDataPtr GetNextFrameData() override;
mojom::XRGamepadDataPtr GetNextGamepadData() override; mojom::XRGamepadDataPtr GetNextGamepadData() override;
void GetEnvironmentIntegrationProvider(
mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) override;
bool StartRuntime() override; bool StartRuntime() override;
void StopRuntime() override; void StopRuntime() override;
void OnSessionStart() override; void OnSessionStart() override;
......
...@@ -195,6 +195,15 @@ mojom::XRFrameDataPtr OpenVRRenderLoop::GetNextFrameData() { ...@@ -195,6 +195,15 @@ mojom::XRFrameDataPtr OpenVRRenderLoop::GetNextFrameData() {
return frame_data; return frame_data;
} }
void OpenVRRenderLoop::GetEnvironmentIntegrationProvider(
mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) {
// Environment integration is not supported. This call should not
// be made on this device.
mojo::ReportBadMessage("Environment integration is not supported.");
return;
}
std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState( std::vector<mojom::XRInputSourceStatePtr> OpenVRRenderLoop::GetInputState(
vr::TrackedDevicePose_t* poses, vr::TrackedDevicePose_t* poses,
uint32_t count) { uint32_t count) {
......
...@@ -34,6 +34,9 @@ class OpenVRRenderLoop : public XRCompositorCommon { ...@@ -34,6 +34,9 @@ class OpenVRRenderLoop : public XRCompositorCommon {
// XRDeviceAbstraction: // XRDeviceAbstraction:
mojom::XRFrameDataPtr GetNextFrameData() override; mojom::XRFrameDataPtr GetNextFrameData() override;
mojom::XRGamepadDataPtr GetNextGamepadData() override; mojom::XRGamepadDataPtr GetNextGamepadData() override;
void GetEnvironmentIntegrationProvider(
mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) override;
bool StartRuntime() override; bool StartRuntime() override;
void StopRuntime() override; void StopRuntime() override;
void OnSessionStart() override; void OnSessionStart() override;
......
...@@ -41,7 +41,7 @@ interface XRRuntimeEventListener { ...@@ -41,7 +41,7 @@ interface XRRuntimeEventListener {
struct XRRuntimeSessionOptions { struct XRRuntimeSessionOptions {
bool immersive; bool immersive;
bool provide_passthrough_camera; bool environment_integration;
// The following options are used for permission requests. // The following options are used for permission requests.
// TODO(crbug.com/854655): remove these fields, and do permission checks in // TODO(crbug.com/854655): remove these fields, and do permission checks in
......
...@@ -43,7 +43,7 @@ enum XRTargetRayMode { ...@@ -43,7 +43,7 @@ enum XRTargetRayMode {
struct XRSessionOptions { struct XRSessionOptions {
bool immersive; bool immersive;
bool provide_passthrough_camera; bool environment_integration;
// A flag to indicate if there has been a user activation when the request // A flag to indicate if there has been a user activation when the request
// session is made. // session is made.
...@@ -73,7 +73,6 @@ struct XRSession { ...@@ -73,7 +73,6 @@ struct XRSession {
// info to more sensible places so that this doesn't need to be sent here. // info to more sensible places so that this doesn't need to be sent here.
VRDisplayInfo display_info; VRDisplayInfo display_info;
XRPresentationConnection? submit_frame_sink; XRPresentationConnection? submit_frame_sink;
XREnvironmentIntegrationProvider? environment_provider;
}; };
// This structure contains the infomation and interfaces needed to create a two // This structure contains the infomation and interfaces needed to create a two
...@@ -165,11 +164,11 @@ struct VRDisplayCapabilities { ...@@ -165,11 +164,11 @@ struct VRDisplayCapabilities {
// Indicates whether the display can actively show imagery on a headset. // Indicates whether the display can actively show imagery on a headset.
bool canPresent; bool canPresent;
// If true, this is an AR display that can provide a background image along // Whether the display gathers data about the environment (for AR like
// with each pose. Clients who want them should send a frame image request // planes, point clouds, meshes, etc.). The backend will decide whether
// via getFrameData instead of getPose. // it needs to provide camera frames or not based on whether it is a
// TODO(https://crbug.com/836349): this may need to change. // see-through HMD or camera-based AR system.
bool can_provide_pass_through_images; bool canProvideEnvironmentIntegration;
}; };
// Information about the optical properties for an eye in a VRDisplay. // Information about the optical properties for an eye in a VRDisplay.
...@@ -303,17 +302,6 @@ interface XRDevice { ...@@ -303,17 +302,6 @@ interface XRDevice {
ExitPresent(); ExitPresent();
}; };
// Provides the necessary functionality for a WebXR session to get data for
// drawing frames. The kind of data it gets depends on what kind of session was
// requested.
// This interface is hosted in the Browser process, but will move to a sandboxed
// utility process on Windows. The render process communicates with it.
interface XRFrameDataProvider {
// frame_data is optional and will not be set if and only if the call fails
// for some reason, such as device disconnection.
GetFrameData() => (XRFrameData? frame_data);
};
// Provides functionality for integrating environment information into an // Provides functionality for integrating environment information into an
// XRSession. For example, some AR sessions would implement hit test to allow // XRSession. For example, some AR sessions would implement hit test to allow
// developers to get the information about the world that its sensors supply. // developers to get the information about the world that its sensors supply.
...@@ -335,6 +323,19 @@ interface XREnvironmentIntegrationProvider { ...@@ -335,6 +323,19 @@ interface XREnvironmentIntegrationProvider {
RequestHitTest(XRRay ray) => (array<XRHitResult>? results); RequestHitTest(XRRay ray) => (array<XRHitResult>? results);
}; };
// Provides the necessary functionality for a WebXR session to get data for
// drawing frames. The kind of data it gets depends on what kind of session was
// requested.
// This interface is hosted in the Browser process, but will move to a sandboxed
// utility process on Windows. The render process communicates with it.
interface XRFrameDataProvider {
// frame_data is optional and will not be set if and only if the call fails
// for some reason, such as device disconnection.
GetFrameData() => (XRFrameData? frame_data);
GetEnvironmentIntegrationProvider(
associated XREnvironmentIntegrationProvider& environment_provider);
};
// Provides the necessary functionality for sending frames to a headset. // Provides the necessary functionality for sending frames to a headset.
// This interface is hosted in the Browser process, but will move to a sandboxed // This interface is hosted in the Browser process, but will move to a sandboxed
// utility process on Windows. The render process communicates with it. // utility process on Windows. The render process communicates with it.
......
...@@ -113,16 +113,11 @@ void VRDeviceBase::ReturnNonImmersiveSession( ...@@ -113,16 +113,11 @@ void VRDeviceBase::ReturnNonImmersiveSession(
mojom::XRFrameDataProviderPtr data_provider; mojom::XRFrameDataProviderPtr data_provider;
mojom::XREnvironmentIntegrationProviderPtr environment_provider; mojom::XREnvironmentIntegrationProviderPtr environment_provider;
mojom::XRSessionControllerPtr controller; mojom::XRSessionControllerPtr controller;
magic_window_sessions_.push_back( magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>(
std::make_unique<VRDisplayImpl>(this, mojo::MakeRequest(&data_provider), this, mojo::MakeRequest(&data_provider), mojo::MakeRequest(&controller)));
mojo::MakeRequest(&environment_provider),
mojo::MakeRequest(&controller)));
auto session = mojom::XRSession::New(); auto session = mojom::XRSession::New();
session->data_provider = data_provider.PassInterface(); session->data_provider = data_provider.PassInterface();
// TODO(http://crbug.com/876135) Not all sessions want the environment
// provider. This should be refactored to only be passed when requested.
session->environment_provider = environment_provider.PassInterface();
if (display_info_) { if (display_info_) {
session->display_info = display_info_.Clone(); session->display_info = display_info_.Clone();
} }
......
...@@ -18,10 +18,9 @@ namespace device { ...@@ -18,10 +18,9 @@ namespace device {
VRDisplayImpl::VRDisplayImpl( VRDisplayImpl::VRDisplayImpl(
VRDeviceBase* device, VRDeviceBase* device,
mojom::XRFrameDataProviderRequest magic_window_request, mojom::XRFrameDataProviderRequest magic_window_request,
mojom::XREnvironmentIntegrationProviderRequest environment_request,
mojom::XRSessionControllerRequest session_request) mojom::XRSessionControllerRequest session_request)
: magic_window_binding_(this, std::move(magic_window_request)), : magic_window_binding_(this, std::move(magic_window_request)),
environment_binding_(this, std::move(environment_request)), environment_binding_(this),
session_controller_binding_(this, std::move(session_request)), session_controller_binding_(this, std::move(session_request)),
device_(device) { device_(device) {
// Unretained is safe because the binding will close when we are destroyed, // Unretained is safe because the binding will close when we are destroyed,
...@@ -43,6 +42,20 @@ void VRDisplayImpl::GetFrameData( ...@@ -43,6 +42,20 @@ void VRDisplayImpl::GetFrameData(
device_->GetFrameData(std::move(callback)); device_->GetFrameData(std::move(callback));
} }
void VRDisplayImpl::GetEnvironmentIntegrationProvider(
mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_request) {
if (!device_->GetVRDisplayInfo()
->capabilities->canProvideEnvironmentIntegration) {
// Environment integration is not supported. This call should not
// be made on this device.
mojo::ReportBadMessage("Environment integration is not supported.");
return;
}
environment_binding_.Bind(std::move(environment_request));
}
void VRDisplayImpl::UpdateSessionGeometry(const gfx::Size& frame_size, void VRDisplayImpl::UpdateSessionGeometry(const gfx::Size& frame_size,
display::Display::Rotation rotation) { display::Display::Rotation rotation) {
// Check for a valid frame size. // Check for a valid frame size.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h"
#include "device/vr/vr_device.h" #include "device/vr/vr_device.h"
#include "device/vr/vr_export.h" #include "device/vr/vr_export.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "ui/display/display.h" #include "ui/display/display.h"
...@@ -31,10 +32,12 @@ class DEVICE_VR_EXPORT VRDisplayImpl ...@@ -31,10 +32,12 @@ class DEVICE_VR_EXPORT VRDisplayImpl
public: public:
VRDisplayImpl(VRDeviceBase* device, VRDisplayImpl(VRDeviceBase* device,
mojom::XRFrameDataProviderRequest, mojom::XRFrameDataProviderRequest,
mojom::XREnvironmentIntegrationProviderRequest,
mojom::XRSessionControllerRequest); mojom::XRSessionControllerRequest);
~VRDisplayImpl() override; ~VRDisplayImpl() override;
void GetEnvironmentIntegrationProvider(
mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) override;
gfx::Size sessionFrameSize() { return session_frame_size_; }; gfx::Size sessionFrameSize() { return session_frame_size_; };
display::Display::Rotation sessionRotation() { return session_rotation_; }; display::Display::Rotation sessionRotation() { return session_rotation_; };
...@@ -55,7 +58,8 @@ class DEVICE_VR_EXPORT VRDisplayImpl ...@@ -55,7 +58,8 @@ class DEVICE_VR_EXPORT VRDisplayImpl
void OnMojoConnectionError(); void OnMojoConnectionError();
mojo::Binding<mojom::XRFrameDataProvider> magic_window_binding_; mojo::Binding<mojom::XRFrameDataProvider> magic_window_binding_;
mojo::Binding<mojom::XREnvironmentIntegrationProvider> environment_binding_; mojo::AssociatedBinding<mojom::XREnvironmentIntegrationProvider>
environment_binding_;
mojo::Binding<mojom::XRSessionController> session_controller_binding_; mojo::Binding<mojom::XRSessionController> session_controller_binding_;
device::VRDeviceBase* device_; device::VRDeviceBase* device_;
bool restrict_frame_data_ = true; bool restrict_frame_data_ = true;
......
...@@ -33,10 +33,8 @@ class VRDisplayImplTest : public testing::Test { ...@@ -33,10 +33,8 @@ class VRDisplayImplTest : public testing::Test {
std::unique_ptr<VRDisplayImpl> MakeDisplay( std::unique_ptr<VRDisplayImpl> MakeDisplay(
mojom::XRSessionControllerPtr* controller) { mojom::XRSessionControllerPtr* controller) {
mojom::XRFrameDataProviderPtr data_provider; mojom::XRFrameDataProviderPtr data_provider;
mojom::XREnvironmentIntegrationProviderPtr environment_provider;
auto display = std::make_unique<VRDisplayImpl>( auto display = std::make_unique<VRDisplayImpl>(
device(), mojo::MakeRequest(&data_provider), device(), mojo::MakeRequest(&data_provider),
mojo::MakeRequest(&environment_provider),
mojo::MakeRequest(controller)); mojo::MakeRequest(controller));
static_cast<mojom::XRSessionController*>(display.get()) static_cast<mojom::XRSessionController*>(display.get())
->SetFrameDataRestricted(true); ->SetFrameDataRestricted(true);
......
...@@ -146,6 +146,10 @@ class MockRuntime { ...@@ -146,6 +146,10 @@ class MockRuntime {
} else { } else {
this.displayInfo_ = this.getNonImmersiveDisplayInfo(); this.displayInfo_ = this.getNonImmersiveDisplayInfo();
} }
if (fakeDeviceInit.supportsEnvironmentIntegration) {
this.displayInfo_.capabilities.canProvideEnvironmentIntegration = true;
}
} }
// Test methods. // Test methods.
...@@ -323,6 +327,12 @@ class MockRuntime { ...@@ -323,6 +327,12 @@ class MockRuntime {
}); });
} }
getEnvironmentIntegrationProvider(environmentProviderRequest) {
let environmentProviderBinding = new mojo.AssociatedBinding(
device.mojom.XREnvironmentIntegrationProvider, this,
environmentProviderRequest);
}
updateSessionGeometry(frame_size, display_rotation) { updateSessionGeometry(frame_size, display_rotation) {
// This function must exist to ensure that calls to it do not crash, but we // This function must exist to ensure that calls to it do not crash, but we
// do not have any use for this data at present. // do not have any use for this data at present.
...@@ -352,21 +362,12 @@ class MockRuntime { ...@@ -352,21 +362,12 @@ class MockRuntime {
let dataProviderBinding = new mojo.Binding( let dataProviderBinding = new mojo.Binding(
device.mojom.XRFrameDataProvider, this, dataProviderRequest); device.mojom.XRFrameDataProvider, this, dataProviderRequest);
let environmentProviderPtr =
new device.mojom.XREnvironmentIntegrationProviderPtr();
let environmentProviderRequest =
mojo.makeRequest(environmentProviderPtr);
let environmentProviderBinding = new mojo.Binding(
device.mojom.XREnvironmentIntegrationProvider, this,
environmentProviderRequest);
let clientRequest = mojo.makeRequest(this.sessionClient_); let clientRequest = mojo.makeRequest(this.sessionClient_);
return Promise.resolve({ return Promise.resolve({
session: { session: {
submitFrameSink: submit_frame_sink, submitFrameSink: submit_frame_sink,
dataProvider: dataProviderPtr, dataProvider: dataProviderPtr,
environmentProvider: environmentProviderPtr,
clientRequest: clientRequest, clientRequest: clientRequest,
displayInfo: this.displayInfo_ displayInfo: this.displayInfo_
} }
......
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
let testName = "Ensures hit-test returns expected mock results"; let testName = "Ensures hit-test returns expected mock results";
let fakeDeviceInitParams = { supportsImmersive: false }; let fakeDeviceInitParams = { supportsImmersive: false,
supportsEnvironmentIntegration: true };
let requestSessionOptions = [ { let requestSessionOptions = [ {
immersive: false, immersive: false,
environmentIntegration: true,
outputContext: getOutputContext() outputContext: getOutputContext()
} ]; } ];
......
...@@ -94,6 +94,11 @@ int64_t XRDevice::GetSourceId() const { ...@@ -94,6 +94,11 @@ int64_t XRDevice::GetSourceId() const {
return xr_->GetSourceId(); return xr_->GetSourceId();
} }
const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr&
XRDevice::xrEnvironmentProviderPtr() {
return environment_provider_;
}
ScriptPromise XRDevice::requestSession( ScriptPromise XRDevice::requestSession(
ScriptState* script_state, ScriptState* script_state,
const XRSessionCreationOptions* options) { const XRSessionCreationOptions* options) {
...@@ -151,8 +156,7 @@ ScriptPromise XRDevice::requestSession( ...@@ -151,8 +156,7 @@ ScriptPromise XRDevice::requestSession(
device::mojom::blink::XRSessionOptionsPtr session_options = device::mojom::blink::XRSessionOptionsPtr session_options =
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->environment_integration = options->environmentIntegration();
options->environmentIntegration();
session_options->has_user_activation = has_user_activation; session_options->has_user_activation = has_user_activation;
XRPresentationContext* output_context = XRPresentationContext* output_context =
...@@ -185,6 +189,13 @@ void XRDevice::OnRequestSessionReturned( ...@@ -185,6 +189,13 @@ void XRDevice::OnRequestSessionReturned(
return; return;
} }
// immersive sessions must supply display info.
DCHECK(session_ptr->display_info);
// If the session supports environment integration, ensure the device does
// as well.
DCHECK(!environment_integration || session_ptr->display_info->capabilities
->canProvideEnvironmentIntegration);
XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque; XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque;
if (environment_integration) if (environment_integration)
blend_mode = XRSession::kBlendModeAlphaBlend; blend_mode = XRSession::kBlendModeAlphaBlend;
...@@ -192,17 +203,17 @@ void XRDevice::OnRequestSessionReturned( ...@@ -192,17 +203,17 @@ void XRDevice::OnRequestSessionReturned(
XRSession* session = XRSession* session =
new XRSession(this, std::move(session_ptr->client_request), immersive, new XRSession(this, std::move(session_ptr->client_request), immersive,
environment_integration, output_context, blend_mode); environment_integration, output_context, blend_mode);
// immersive sessions must supply display info. session->SetXRDisplayInfo(std::move(session_ptr->display_info));
DCHECK(!immersive || session_ptr->display_info);
if (session_ptr->display_info)
session->SetXRDisplayInfo(std::move(session_ptr->display_info));
sessions_.insert(session); sessions_.insert(session);
if (immersive) { if (immersive) {
frameProvider()->BeginImmersiveSession(session, std::move(session_ptr)); frameProvider()->BeginImmersiveSession(session, std::move(session_ptr));
} else { } else {
magic_window_provider_.Bind(std::move(session_ptr->data_provider)); magic_window_provider_.Bind(std::move(session_ptr->data_provider));
environment_provider_.Bind(std::move(session_ptr->environment_provider)); if (environment_integration) {
magic_window_provider_->GetEnvironmentIntegrationProvider(
mojo::MakeRequest(&environment_provider_));
}
} }
resolver->Resolve(session); resolver->Resolve(session);
......
...@@ -43,10 +43,8 @@ class XRDevice final : public ScriptWrappable { ...@@ -43,10 +43,8 @@ class XRDevice final : public ScriptWrappable {
const { const {
return magic_window_provider_; return magic_window_provider_;
} }
const device::mojom::blink::XREnvironmentIntegrationProviderPtr& const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr&
xrEnvironmentProviderPtr() const { xrEnvironmentProviderPtr();
return environment_provider_;
}
void OnFrameFocusChanged(); void OnFrameFocusChanged();
bool HasFrameFocus() { return IsFrameFocused(); } bool HasFrameFocus() { return IsFrameFocused(); }
...@@ -81,7 +79,7 @@ class XRDevice final : public ScriptWrappable { ...@@ -81,7 +79,7 @@ class XRDevice final : public ScriptWrappable {
bool did_log_request_immersive_session_ = false; bool did_log_request_immersive_session_ = false;
device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_; device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_;
device::mojom::blink::XREnvironmentIntegrationProviderPtr device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr
environment_provider_; environment_provider_;
device::mojom::blink::XRDevicePtr device_ptr_; device::mojom::blink::XRDevicePtr device_ptr_;
}; };
......
...@@ -297,8 +297,17 @@ ScriptPromise XRSession::requestHitTest(ScriptState* script_state, ...@@ -297,8 +297,17 @@ ScriptPromise XRSession::requestHitTest(ScriptState* script_state,
// TODO(https://crbug.com/846411): use coordinate_system. // TODO(https://crbug.com/846411): use coordinate_system.
// TODO(https://crbug.com/843376): Reject the promise if device doesn't // Reject the promise if device doesn't support the hit-test API.
// support the hit-test API. // TODO(https://crbug.com/878936): Get the environment provider without going
// up to device_, since it doesn't know which runtime's environment provider
// we want.
if (!device_->xrEnvironmentProviderPtr()) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(DOMExceptionCode::kNotSupportedError,
"Device does not support hit-test!"));
}
device::mojom::blink::XRRayPtr ray = device::mojom::blink::XRRay::New(); device::mojom::blink::XRRayPtr ray = device::mojom::blink::XRRay::New();
ray->origin = gfx::mojom::blink::Point3F::New(); ray->origin = gfx::mojom::blink::Point3F::New();
......
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