Commit f12b0cb2 authored by Patrick To's avatar Patrick To Committed by Commit Bot

Implement OpenXR Rendering Loop

To try out this code with the Microsoft OpenXR Runtime in Chromium, perform the following steps.
    - Install 'Mixed Reality OpenXR Developer Preview' from the Microsoft Store
    - If prompted also download the compatibility pack

Add the following to custom_vars in .gclient, located at the root of the chromium clone:
    "checkout_openxr": True
Add the following to args.gn, located in the out folder:
    enable_openxr = true

gclient sync and build

Once you've built and installed Chromium go to about:flags and:
    - Enable WebVR or WebXR
    - Enable 'OpenXR Support'

Bug: 976430,976436
Change-Id: I8a7c69b3a13349aa9e083d6206121b69a1f724cc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1688443Reviewed-by: default avatarBill Orr <billorr@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Commit-Queue: Patrick To <patrto@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#678528}
parent 5c8058b7
...@@ -158,7 +158,7 @@ void IsolatedXRRuntimeProvider::SetupPollingForDeviceChanges() { ...@@ -158,7 +158,7 @@ void IsolatedXRRuntimeProvider::SetupPollingForDeviceChanges() {
#if BUILDFLAG(ENABLE_OPENXR) #if BUILDFLAG(ENABLE_OPENXR)
if (base::FeatureList::IsEnabled(features::kOpenXR)) { if (base::FeatureList::IsEnabled(features::kOpenXR)) {
should_check_openxr_ = device::OpenXRDevice::IsApiAvailable(); should_check_openxr_ = device::OpenXrDevice::IsApiAvailable();
any_runtimes_available |= should_check_openxr_; any_runtimes_available |= should_check_openxr_;
} }
#endif #endif
...@@ -213,7 +213,7 @@ void IsolatedXRRuntimeProvider::SetWMRRuntimeStatus(RuntimeStatus status) { ...@@ -213,7 +213,7 @@ void IsolatedXRRuntimeProvider::SetWMRRuntimeStatus(RuntimeStatus status) {
#if BUILDFLAG(ENABLE_OPENXR) #if BUILDFLAG(ENABLE_OPENXR)
bool IsolatedXRRuntimeProvider::IsOpenXrHardwareAvailable() { bool IsolatedXRRuntimeProvider::IsOpenXrHardwareAvailable() {
return should_check_openxr_ && device::OpenXRDevice::IsHardwareAvailable(); return should_check_openxr_ && device::OpenXrDevice::IsHardwareAvailable();
} }
void IsolatedXRRuntimeProvider::SetOpenXrRuntimeStatus(RuntimeStatus status) { void IsolatedXRRuntimeProvider::SetOpenXrRuntimeStatus(RuntimeStatus status) {
......
...@@ -16,7 +16,7 @@ class OculusDevice; ...@@ -16,7 +16,7 @@ class OculusDevice;
class OpenVRDevice; class OpenVRDevice;
class MixedRealityDevice; class MixedRealityDevice;
class MixedRealityDeviceStatics; class MixedRealityDeviceStatics;
class OpenXRDevice; class OpenXrDevice;
} // namespace device } // namespace device
class IsolatedXRRuntimeProvider class IsolatedXRRuntimeProvider
...@@ -64,7 +64,7 @@ class IsolatedXRRuntimeProvider ...@@ -64,7 +64,7 @@ class IsolatedXRRuntimeProvider
bool IsOpenXrHardwareAvailable(); bool IsOpenXrHardwareAvailable();
void SetOpenXrRuntimeStatus(RuntimeStatus status); void SetOpenXrRuntimeStatus(RuntimeStatus status);
bool should_check_openxr_ = false; bool should_check_openxr_ = false;
std::unique_ptr<device::OpenXRDevice> openxr_device_; std::unique_ptr<device::OpenXrDevice> openxr_device_;
#endif #endif
device::mojom::IsolatedXRRuntimeProviderClientPtr client_; device::mojom::IsolatedXRRuntimeProviderClientPtr client_;
......
...@@ -226,9 +226,17 @@ if (enable_vr) { ...@@ -226,9 +226,17 @@ if (enable_vr) {
} }
if (enable_openxr) { if (enable_openxr) {
deps += [ "//third_party/openxr" ]
sources += [ sources += [
"openxr/openxr_api_wrapper.cc",
"openxr/openxr_api_wrapper.h",
"openxr/openxr_device.cc", "openxr/openxr_device.cc",
"openxr/openxr_device.h", "openxr/openxr_device.h",
"openxr/openxr_render_loop.cc",
"openxr/openxr_render_loop.h",
"openxr/openxr_util.cc",
"openxr/openxr_util.h",
] ]
} }
} }
......
...@@ -15,15 +15,13 @@ declare_args() { ...@@ -15,15 +15,13 @@ declare_args() {
enable_windows_mr = is_win enable_windows_mr = is_win
# Do not enable OpenXR until it can build without exceptions.
enable_openxr = false enable_openxr = false
# To build with Oculus support, the Oculus SDK for Windows will need to be # To build with Oculus support, the Oculus SDK for Windows will need to be
# installed in third_party/libovr/src. See # installed in third_party/libovr/src. See
# third_party/libovr/README.chromium for details. # third_party/libovr/README.chromium for details.
enable_oculus_vr = checkout_oculus_sdk && is_chrome_branded && is_win enable_oculus_vr = checkout_oculus_sdk && is_chrome_branded && is_win
# Do not enable OpenXR until it can build without exceptions.
enable_openxr = false
} }
declare_args() { declare_args() {
......
...@@ -80,15 +80,6 @@ mojom::XRGamepadDataPtr OculusRenderLoop::GetNextGamepadData() { ...@@ -80,15 +80,6 @@ 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,9 +33,6 @@ class OculusRenderLoop : public XRCompositorCommon { ...@@ -33,9 +33,6 @@ 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;
......
...@@ -215,15 +215,6 @@ mojom::XRFrameDataPtr OpenVRRenderLoop::GetNextFrameData() { ...@@ -215,15 +215,6 @@ 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,9 +34,6 @@ class OpenVRRenderLoop : public XRCompositorCommon { ...@@ -34,9 +34,6 @@ 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;
......
include_rules = [
"+third_party/openxr/include/openxr"
]
This diff is collapsed.
// 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.
#ifndef DEVICE_VR_OPENXR_OPENXR_API_WRAPPER_H_
#define DEVICE_VR_OPENXR_OPENXR_API_WRAPPER_H_
#include <d3d11.h>
#include <stdint.h>
#include <wrl.h>
#include <memory>
#include <vector>
#include "base/macros.h"
#include "third_party/openxr/include/openxr/openxr.h"
#include "third_party/openxr/include/openxr/openxr_platform.h"
namespace gfx {
class Quaternion;
class Point3F;
} // namespace gfx
namespace device {
class OpenXrApiWrapper {
public:
OpenXrApiWrapper();
~OpenXrApiWrapper();
static std::unique_ptr<OpenXrApiWrapper> Create();
static bool IsHardwareAvailable();
static bool IsApiAvailable();
XrResult StartSession(const Microsoft::WRL::ComPtr<ID3D11Device>& d3d_device);
XrResult BeginFrame(Microsoft::WRL::ComPtr<ID3D11Texture2D>* texture);
XrResult EndFrame();
XrResult GetHeadPose(gfx::Quaternion* orientation,
gfx::Point3F* position) const;
XrTime GetPredictedDisplayTime() const;
void GetViewSize(uint32_t* width, uint32_t* height) const;
XrResult GetLuid(LUID* luid) const;
private:
void Reset();
bool Initialize();
void Uninitialize();
bool IsInitialized() const;
XrResult InitializeSystem();
XrResult PickEnvironmentBlendMode(XrSystemId system);
XrResult CreateSession(
const Microsoft::WRL::ComPtr<ID3D11Device>& d3d_device);
XrResult CreateSwapchain();
XrResult CreateSpace(XrReferenceSpaceType type, XrSpace* space);
XrResult CreateViewSpace();
XrResult BeginSession();
XrResult UpdateProjectionLayers();
bool HasInstance() const;
bool HasSystem() const;
bool HasBlendMode() const;
bool HasSession() const;
bool HasColorSwapChain() const;
bool HasSpace(XrReferenceSpaceType type) const;
bool HasFrameState() const;
uint32_t GetRecommendedSwapchainSampleCount() const;
// OpenXR objects
// These objects are valid on successful initialization.
XrInstance instance_;
XrSystemId system_;
std::vector<XrViewConfigurationView> view_configs_;
XrEnvironmentBlendMode blend_mode_;
// These objects are valid only while a session is active,
// and stay constant throughout the lifetime of a session.
XrSession session_;
XrSwapchain color_swapchain_;
std::vector<XrSwapchainImageD3D11KHR> color_swapchain_images_;
XrSpace local_space_;
XrSpace view_space_;
// These objects store information about the current frame. They're
// valid only while a session is active, and they are updated each frame.
XrFrameState frame_state_;
std::vector<XrView> views_;
std::vector<XrCompositionLayerProjectionView> layer_projection_views_;
DISALLOW_COPY_AND_ASSIGN(OpenXrApiWrapper);
};
} // namespace device
#endif // DEVICE_VR_OPENXR_OPENXR_API_WRAPPER_H_
...@@ -5,11 +5,18 @@ ...@@ -5,11 +5,18 @@
#include "device/vr/openxr/openxr_device.h" #include "device/vr/openxr/openxr_device.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "device/vr/openxr/openxr_api_wrapper.h"
#include "device/vr/openxr/openxr_render_loop.h"
namespace device { namespace device {
namespace { namespace {
constexpr float kFramebufferScale = 1.0f;
constexpr float kFov = 45.0f;
constexpr uint32_t kDimension = 1024;
constexpr float kInterpupillaryDistance = 0.1f; // 10cm
// OpenXR doesn't give out display info until you start a session. // OpenXR doesn't give out display info until you start a session.
// However our mojo interface expects display info right away to support WebVR. // However our mojo interface expects display info right away to support WebVR.
// We create a fake display info to use, then notify the client that the display // We create a fake display info to use, then notify the client that the display
...@@ -25,25 +32,22 @@ mojom::VRDisplayInfoPtr CreateFakeVRDisplayInfo(device::mojom::XRDeviceId id) { ...@@ -25,25 +32,22 @@ mojom::VRDisplayInfoPtr CreateFakeVRDisplayInfo(device::mojom::XRDeviceId id) {
display_info->capabilities->has_external_display = true; display_info->capabilities->has_external_display = true;
display_info->capabilities->can_present = true; display_info->capabilities->can_present = true;
display_info->webvr_default_framebuffer_scale = 1.0f; display_info->webvr_default_framebuffer_scale = kFramebufferScale;
display_info->webxr_default_framebuffer_scale = 1.0f; display_info->webxr_default_framebuffer_scale = kFramebufferScale;
display_info->left_eye = mojom::VREyeParameters::New(); display_info->left_eye = mojom::VREyeParameters::New();
display_info->right_eye = mojom::VREyeParameters::New(); display_info->right_eye = mojom::VREyeParameters::New();
constexpr float kFov = 45.0f;
display_info->left_eye->field_of_view = display_info->left_eye->field_of_view =
mojom::VRFieldOfView::New(kFov, kFov, kFov, kFov); mojom::VRFieldOfView::New(kFov, kFov, kFov, kFov);
display_info->right_eye->field_of_view = display_info->right_eye->field_of_view =
display_info->left_eye->field_of_view->Clone(); display_info->left_eye->field_of_view->Clone();
constexpr uint32_t kDimension = 1024;
display_info->left_eye->render_width = kDimension; display_info->left_eye->render_width = kDimension;
display_info->left_eye->render_height = kDimension; display_info->left_eye->render_height = kDimension;
display_info->right_eye->render_width = kDimension; display_info->right_eye->render_width = kDimension;
display_info->right_eye->render_width = kDimension; display_info->right_eye->render_width = kDimension;
constexpr float kInterpupillaryDistance = 0.1f; // 10cm
display_info->left_eye->offset = {-kInterpupillaryDistance * 0.5, 0, 0}; display_info->left_eye->offset = {-kInterpupillaryDistance * 0.5, 0, 0};
display_info->right_eye->offset = {kInterpupillaryDistance * 0.5, 0, 0}; display_info->right_eye->offset = {kInterpupillaryDistance * 0.5, 0, 0};
...@@ -52,53 +56,155 @@ mojom::VRDisplayInfoPtr CreateFakeVRDisplayInfo(device::mojom::XRDeviceId id) { ...@@ -52,53 +56,155 @@ mojom::VRDisplayInfoPtr CreateFakeVRDisplayInfo(device::mojom::XRDeviceId id) {
} // namespace } // namespace
OpenXRDevice::OpenXRDevice() bool OpenXrDevice::IsHardwareAvailable() {
return OpenXrApiWrapper::IsHardwareAvailable();
}
bool OpenXrDevice::IsApiAvailable() {
return OpenXrApiWrapper::IsApiAvailable();
}
OpenXrDevice::OpenXrDevice()
: VRDeviceBase(device::mojom::XRDeviceId::OPENXR_DEVICE_ID), : VRDeviceBase(device::mojom::XRDeviceId::OPENXR_DEVICE_ID),
exclusive_controller_binding_(this), exclusive_controller_binding_(this),
gamepad_provider_factory_binding_(this), gamepad_provider_factory_binding_(this),
compositor_host_binding_(this) { compositor_host_binding_(this),
weak_ptr_factory_(this) {
render_loop_ = std::make_unique<OpenXrRenderLoop>();
SetVRDisplayInfo(CreateFakeVRDisplayInfo(GetId())); SetVRDisplayInfo(CreateFakeVRDisplayInfo(GetId()));
} }
OpenXRDevice::~OpenXRDevice() = default; OpenXrDevice::~OpenXrDevice() {
// Wait for the render loop to stop before completing destruction. This will
bool OpenXRDevice::IsHardwareAvailable() { // ensure that the render loop doesn't get shutdown while it is processing
// TODO(https://crbug.com/976436) // any requests.
return true; if (render_loop_->IsRunning()) {
} render_loop_->Stop();
}
bool OpenXRDevice::IsApiAvailable() {
// TODO(https://crbug.com/976436)
return true;
} }
mojom::IsolatedXRGamepadProviderFactoryPtr OpenXRDevice::BindGamepadFactory() { mojom::IsolatedXRGamepadProviderFactoryPtr OpenXrDevice::BindGamepadFactory() {
mojom::IsolatedXRGamepadProviderFactoryPtr ret; mojom::IsolatedXRGamepadProviderFactoryPtr ret;
gamepad_provider_factory_binding_.Bind(mojo::MakeRequest(&ret)); gamepad_provider_factory_binding_.Bind(mojo::MakeRequest(&ret));
return ret; return ret;
} }
mojom::XRCompositorHostPtr OpenXRDevice::BindCompositorHost() { mojom::XRCompositorHostPtr OpenXrDevice::BindCompositorHost() {
mojom::XRCompositorHostPtr ret; mojom::XRCompositorHostPtr ret;
compositor_host_binding_.Bind(mojo::MakeRequest(&ret)); compositor_host_binding_.Bind(mojo::MakeRequest(&ret));
return ret; return ret;
} }
void OpenXRDevice::RequestSession( void OpenXrDevice::RequestSession(
mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntimeSessionOptionsPtr options,
mojom::XRRuntime::RequestSessionCallback callback) { mojom::XRRuntime::RequestSessionCallback callback) {
std::move(callback).Run(nullptr, nullptr); DCHECK(options->immersive);
if (!render_loop_->IsRunning()) {
render_loop_->Start();
if (!render_loop_->IsRunning()) {
std::move(callback).Run(nullptr, nullptr);
return;
}
if (provider_request_) {
render_loop_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&XRCompositorCommon::RequestGamepadProvider,
base::Unretained(render_loop_.get()),
std::move(provider_request_)));
}
if (overlay_request_) {
render_loop_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&XRCompositorCommon::RequestOverlay,
base::Unretained(render_loop_.get()),
std::move(overlay_request_)));
}
}
auto my_callback =
base::BindOnce(&OpenXrDevice::OnRequestSessionResult,
weak_ptr_factory_.GetWeakPtr(), std::move(callback));
// OpenXR doesn't need to handle anything when presentation has ended, but
// the mojo interface to call to XRCompositorCommon::RequestSession requires
// a method and cannot take nullptr, so passing in base::DoNothing::Once()
// for on_presentation_ended
render_loop_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&XRCompositorCommon::RequestSession,
base::Unretained(render_loop_.get()),
base::DoNothing::Once(), std::move(options),
std::move(my_callback)));
}
void OpenXrDevice::OnRequestSessionResult(
mojom::XRRuntime::RequestSessionCallback callback,
bool result,
mojom::XRSessionPtr session) {
if (!result) {
std::move(callback).Run(nullptr, nullptr);
return;
}
OnStartPresenting();
mojom::XRSessionControllerPtr session_controller;
exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller));
// Use of Unretained is safe because the callback will only occur if the
// binding is not destroyed.
exclusive_controller_binding_.set_connection_error_handler(
base::BindOnce(&OpenXrDevice::OnPresentingControllerMojoConnectionError,
base::Unretained(this)));
uint32_t width, height;
render_loop_->GetViewSize(&width, &height);
display_info_->left_eye->render_width = width;
display_info_->right_eye->render_width = width;
display_info_->left_eye->render_height = height;
display_info_->right_eye->render_height = height;
session->display_info = display_info_.Clone();
std::move(callback).Run(std::move(session), std::move(session_controller));
} }
void OpenXRDevice::SetFrameDataRestricted(bool restricted) { void OpenXrDevice::OnPresentingControllerMojoConnectionError() {
// This method is called when the rendering process exit presents.
render_loop_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&XRCompositorCommon::ExitPresent,
base::Unretained(render_loop_.get())));
OnExitPresent();
exclusive_controller_binding_.Close();
}
void OpenXrDevice::SetFrameDataRestricted(bool restricted) {
// Presentation sessions can not currently be restricted. // Presentation sessions can not currently be restricted.
NOTREACHED(); NOTREACHED();
} }
void OpenXRDevice::GetIsolatedXRGamepadProvider( void OpenXrDevice::GetIsolatedXRGamepadProvider(
mojom::IsolatedXRGamepadProviderRequest provider_request) {} mojom::IsolatedXRGamepadProviderRequest provider_request) {
if (render_loop_->IsRunning()) {
render_loop_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&XRCompositorCommon::RequestGamepadProvider,
base::Unretained(render_loop_.get()),
std::move(provider_request)));
} else {
provider_request_ = std::move(provider_request);
}
}
void OpenXRDevice::CreateImmersiveOverlay( void OpenXrDevice::CreateImmersiveOverlay(
mojom::ImmersiveOverlayRequest overlay_request) {} mojom::ImmersiveOverlayRequest overlay_request) {
if (render_loop_->IsRunning()) {
render_loop_->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&XRCompositorCommon::RequestOverlay,
base::Unretained(render_loop_.get()),
std::move(overlay_request)));
} else {
overlay_request_ = std::move(overlay_request);
}
}
} // namespace device } // namespace device
...@@ -5,19 +5,24 @@ ...@@ -5,19 +5,24 @@
#ifndef DEVICE_VR_OPENXR_OPENXR_DEVICE_H_ #ifndef DEVICE_VR_OPENXR_OPENXR_DEVICE_H_
#define DEVICE_VR_OPENXR_OPENXR_DEVICE_H_ #define DEVICE_VR_OPENXR_OPENXR_DEVICE_H_
#include <memory>
#include "base/macros.h"
#include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h"
#include "device/vr/vr_device_base.h" #include "device/vr/vr_device_base.h"
namespace device { namespace device {
class DEVICE_VR_EXPORT OpenXRDevice class OpenXrRenderLoop;
class DEVICE_VR_EXPORT OpenXrDevice
: public VRDeviceBase, : public VRDeviceBase,
public mojom::XRSessionController, public mojom::XRSessionController,
public mojom::IsolatedXRGamepadProviderFactory, public mojom::IsolatedXRGamepadProviderFactory,
public mojom::XRCompositorHost { public mojom::XRCompositorHost {
public: public:
OpenXRDevice(); OpenXrDevice();
~OpenXRDevice() override; ~OpenXrDevice() override;
static bool IsHardwareAvailable(); static bool IsHardwareAvailable();
static bool IsApiAvailable(); static bool IsApiAvailable();
...@@ -42,12 +47,25 @@ class DEVICE_VR_EXPORT OpenXRDevice ...@@ -42,12 +47,25 @@ class DEVICE_VR_EXPORT OpenXRDevice
void CreateImmersiveOverlay( void CreateImmersiveOverlay(
mojom::ImmersiveOverlayRequest overlay_request) override; mojom::ImmersiveOverlayRequest overlay_request) override;
void OnRequestSessionResult(mojom::XRRuntime::RequestSessionCallback callback,
bool result,
mojom::XRSessionPtr session);
void OnPresentingControllerMojoConnectionError();
std::unique_ptr<OpenXrRenderLoop> render_loop_;
mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_; mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_;
mojo::Binding<mojom::IsolatedXRGamepadProviderFactory> mojo::Binding<mojom::IsolatedXRGamepadProviderFactory>
gamepad_provider_factory_binding_; gamepad_provider_factory_binding_;
mojom::IsolatedXRGamepadProviderRequest provider_request_;
mojo::Binding<mojom::XRCompositorHost> compositor_host_binding_; mojo::Binding<mojom::XRCompositorHost> compositor_host_binding_;
mojom::ImmersiveOverlayRequest overlay_request_;
base::WeakPtrFactory<OpenXrDevice> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(OpenXRDevice); DISALLOW_COPY_AND_ASSIGN(OpenXrDevice);
}; };
} // namespace device } // namespace device
......
// 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 "device/vr/openxr/openxr_render_loop.h"
#include "device/vr/openxr/openxr_api_wrapper.h"
namespace device {
OpenXrRenderLoop::OpenXrRenderLoop() : XRCompositorCommon() {}
OpenXrRenderLoop::~OpenXrRenderLoop() {
Stop();
}
void OpenXrRenderLoop::GetViewSize(uint32_t* width, uint32_t* height) const {
openxr_->GetViewSize(width, height);
}
mojom::XRFrameDataPtr OpenXrRenderLoop::GetNextFrameData() {
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
if (XR_FAILED(openxr_->BeginFrame(&texture))) {
return nullptr;
}
texture_helper_.SetBackbuffer(texture.Get());
mojom::XRFrameDataPtr frame_data = mojom::XRFrameData::New();
frame_data->frame_id = next_frame_id_;
frame_data->time_delta =
base::TimeDelta::FromNanoseconds(openxr_->GetPredictedDisplayTime());
gfx::Quaternion orientation;
gfx::Point3F position;
if (XR_SUCCEEDED(openxr_->GetHeadPose(&orientation, &position))) {
frame_data->pose = mojom::VRPose::New();
frame_data->pose->orientation = orientation;
frame_data->pose->position = position;
}
return frame_data;
}
mojom::XRGamepadDataPtr OpenXrRenderLoop::GetNextGamepadData() {
return nullptr;
}
bool OpenXrRenderLoop::StartRuntime() {
DCHECK(!openxr_);
// The new wrapper object is stored in a temporary variable instead of
// openxr_ so that the local unique_ptr cleans up the object if starting
// a session fails. openxr_ is set later in this method once we know
// starting the session succeeds.
std::unique_ptr<OpenXrApiWrapper> openxr = OpenXrApiWrapper::Create();
if (!openxr)
return false;
texture_helper_.SetUseBGRA(true);
LUID luid;
if (XR_FAILED(openxr->GetLuid(&luid)) ||
!texture_helper_.SetAdapterLUID(luid) ||
!texture_helper_.EnsureInitialized() ||
XR_FAILED(openxr->StartSession(texture_helper_.GetDevice()))) {
texture_helper_.Reset();
return false;
}
// Starting session succeeded so we can set the member variable.
// Any additional code added below this should never fail.
openxr_ = std::move(openxr);
uint32_t width, height;
GetViewSize(&width, &height);
texture_helper_.SetDefaultSize(gfx::Size(width, height));
DCHECK(openxr_);
return true;
}
void OpenXrRenderLoop::StopRuntime() {
openxr_ = nullptr;
texture_helper_.Reset();
}
void OpenXrRenderLoop::OnSessionStart() {
LogViewerType(VrViewerType::OPENXR_UNKNOWN);
}
bool OpenXrRenderLoop::PreComposite() {
return true;
}
bool OpenXrRenderLoop::SubmitCompositedFrame() {
return XR_SUCCEEDED(openxr_->EndFrame());
}
} // namespace device
// 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.
#ifndef DEVICE_VR_OPENXR_OPENXR_RENDER_LOOP_H_
#define DEVICE_VR_OPENXR_OPENXR_RENDER_LOOP_H_
#include <stdint.h>
#include <memory>
#include "base/macros.h"
#include "device/vr/windows/compositor_base.h"
namespace device {
class OpenXrApiWrapper;
class OpenXrRenderLoop : public XRCompositorCommon {
public:
OpenXrRenderLoop();
~OpenXrRenderLoop() override;
void GetViewSize(uint32_t* width, uint32_t* height) const;
private:
// XRDeviceAbstraction:
mojom::XRFrameDataPtr GetNextFrameData() override;
mojom::XRGamepadDataPtr GetNextGamepadData() override;
bool StartRuntime() override;
void StopRuntime() override;
void OnSessionStart() override;
bool PreComposite() override;
bool SubmitCompositedFrame() override;
std::unique_ptr<OpenXrApiWrapper> openxr_;
DISALLOW_COPY_AND_ASSIGN(OpenXrRenderLoop);
};
} // namespace device
#endif // DEVICE_VR_OPENXR_OPENXR_RENDER_LOOP_H_
// 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 "device/vr/openxr/openxr_util.h"
namespace device {
XrPosef PoseIdentity() {
XrPosef pose{};
pose.orientation.w = 1;
return pose;
}
} // namespace device
// 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.
#ifndef DEVICE_VR_OPENXR_OPENXR_UTIL_H_
#define DEVICE_VR_OPENXR_OPENXR_UTIL_H_
#include "third_party/openxr/include/openxr/openxr.h"
namespace device {
// These macros aren't common in Chromium and generally discouraged, so define
// all OpenXR helper macros here so they can be kept track of. This file
// should not be included outside of device/vr/openxr.
// The caller must have a variable of type XrResult named xr_result defined in
// their scope. This macro sets xr_result to |xrcode|.
#define RETURN_IF_XR_FAILED(xrcode) \
do { \
xr_result = (xrcode); \
if (XR_FAILED(xr_result)) \
return xr_result; \
} while (false)
// Returns the identity pose, where the position is {0, 0, 0} and the
// orientation is {0, 0, 0, 1}.
XrPosef PoseIdentity();
} // namespace device
#endif // DEVICE_VR_OPENXR_OPENXR_UTIL_H_
...@@ -374,6 +374,14 @@ void XRCompositorCommon::GetControllerDataAndSendFrameData( ...@@ -374,6 +374,14 @@ void XRCompositorCommon::GetControllerDataAndSendFrameData(
: mojom::XRFrameData::New()); : mojom::XRFrameData::New());
} }
void XRCompositorCommon::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.");
}
void XRCompositorCommon::SubmitOverlayTexture( void XRCompositorCommon::SubmitOverlayTexture(
int16_t frame_id, int16_t frame_id,
mojo::ScopedHandle texture_handle, mojo::ScopedHandle texture_handle,
......
...@@ -67,6 +67,10 @@ class XRCompositorCommon : public base::Thread, ...@@ -67,6 +67,10 @@ class XRCompositorCommon : public base::Thread,
XRFrameDataProvider::GetFrameDataCallback callback, XRFrameDataProvider::GetFrameDataCallback callback,
mojom::XRFrameDataPtr frame_data); mojom::XRFrameDataPtr frame_data);
void GetEnvironmentIntegrationProvider(
device::mojom::XREnvironmentIntegrationProviderAssociatedRequest
environment_provider) final;
void RequestGamepadProvider(mojom::IsolatedXRGamepadProviderRequest request); void RequestGamepadProvider(mojom::IsolatedXRGamepadProviderRequest request);
void RequestOverlay(mojom::ImmersiveOverlayRequest request); void RequestOverlay(mojom::ImmersiveOverlayRequest request);
......
...@@ -859,13 +859,4 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { ...@@ -859,13 +859,4 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
return ret; return ret;
} }
void MixedRealityRenderLoop::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;
}
} // namespace device } // namespace device
...@@ -58,9 +58,6 @@ class MixedRealityRenderLoop : public XRCompositorCommon { ...@@ -58,9 +58,6 @@ class MixedRealityRenderLoop : 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 PreComposite() override; bool PreComposite() override;
bool SubmitCompositedFrame() override; bool SubmitCompositedFrame() override;
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
import("//device/vr/buildflags/buildflags.gni") import("//device/vr/buildflags/buildflags.gni")
if (enable_openxr) { if (enable_openxr) {
component("openxr") { source_set("openxr") {
output_name = "openxr_loader"
sources = [ sources = [
"gen/xr_generated_dispatch_table.c", "gen/xr_generated_dispatch_table.c",
"gen/xr_generated_dispatch_table.h", "gen/xr_generated_dispatch_table.h",
...@@ -69,10 +67,6 @@ if (enable_openxr) { ...@@ -69,10 +67,6 @@ if (enable_openxr) {
"DISABLE_STD_FILESYSTEM", "DISABLE_STD_FILESYSTEM",
] ]
if (is_component_build) {
defines += [ "XRAPI_DLL_EXPORT" ]
}
cflags_cc = [ cflags_cc = [
"-Wno-format", "-Wno-format",
"-Wno-microsoft-cast", "-Wno-microsoft-cast",
......
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