Commit 05e7b56e authored by Kevin Qin's avatar Kevin Qin Committed by Commit Bot

OpenXR Remove Unnecessary Calls that are Called Every Frame

There are several problems with current openxr implementation:
1. stage bounds is fixed and only need to be set once.
2. Some VRDisplayinfo variables don't need to wait for session start
to be populated on every frame.

Change-Id: I9c0e6b8aea3560f5694a0b818f827cd2c0f30e01
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1832484
Commit-Queue: Zheng Qin <zheqi@microsoft.com>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710176}
parent 0f3b5fd3
......@@ -241,6 +241,7 @@ XrResult OpenXrApiWrapper::InitSession(
// It's ok if stage_space_ fails since not all OpenXR devices are required to
// support this reference space.
CreateSpace(XR_REFERENCE_SPACE_TYPE_STAGE, &stage_space_);
UpdateStageBounds();
// Since the objects in these arrays are used on every frame,
// we don't want to create and destroy these objects every frame,
......@@ -638,17 +639,23 @@ std::string OpenXrApiWrapper::GetRuntimeName() const {
}
}
XrResult OpenXrApiWrapper::GetStageBounds(XrExtent2Df* stage_bounds) const {
DCHECK(stage_bounds);
// stage bounds is fixed unless we received event
// XrEventDataReferenceSpaceChangePending
XrResult OpenXrApiWrapper::UpdateStageBounds() {
DCHECK(HasSession());
XrResult xr_result;
xr_result = xrGetReferenceSpaceBoundsRect(
session_, XR_REFERENCE_SPACE_TYPE_STAGE, &stage_bounds_);
if (XR_FAILED(xr_result)) {
stage_bounds_.height = 0;
stage_bounds_.width = 0;
}
return xrGetReferenceSpaceBoundsRect(session_, XR_REFERENCE_SPACE_TYPE_STAGE,
stage_bounds);
return xr_result;
}
bool OpenXrApiWrapper::GetStageParameters(
XrExtent2Df* stage_bounds,
gfx::Transform* local_from_stage) const {
bool OpenXrApiWrapper::GetStageParameters(XrExtent2Df* stage_bounds,
gfx::Transform* local_from_stage) {
DCHECK(stage_bounds);
DCHECK(local_from_stage);
DCHECK(HasSession());
......@@ -659,8 +666,7 @@ bool OpenXrApiWrapper::GetStageParameters(
if (!HasSpace(XR_REFERENCE_SPACE_TYPE_STAGE))
return false;
if (XR_FAILED(GetStageBounds(stage_bounds)))
return false;
*stage_bounds = stage_bounds_;
XrSpaceLocation local_from_stage_location = {XR_TYPE_SPACE_LOCATION};
if (FAILED(xrLocateSpace(local_space_, stage_space_,
......
......@@ -58,7 +58,7 @@ class OpenXrApiWrapper {
XrResult GetLuid(LUID* luid) const;
std::string GetRuntimeName() const;
bool GetStageParameters(XrExtent2Df* stage_bounds,
gfx::Transform* local_from_stage) const;
gfx::Transform* local_from_stage);
static void DEVICE_VR_EXPORT SetTestHook(VRTestHook* hook);
......@@ -92,7 +92,7 @@ class OpenXrApiWrapper {
bool HasFrameState() const;
uint32_t GetRecommendedSwapchainSampleCount() const;
XrResult GetStageBounds(XrExtent2Df* stage_bounds) const;
XrResult UpdateStageBounds();
bool session_ended_;
......@@ -107,6 +107,7 @@ class OpenXrApiWrapper {
XrSystemId system_;
std::vector<XrViewConfigurationView> view_configs_;
XrEnvironmentBlendMode blend_mode_;
XrExtent2Df stage_bounds_;
// These objects are valid only while a session is active,
// and stay constant throughout the lifetime of a session.
......
......@@ -155,12 +155,6 @@ void OpenXrDevice::OnRequestSessionResult(
OnStartPresenting();
EnsureRenderLoop();
gfx::Size view_size = render_loop_->GetViewSize();
display_info_->left_eye->render_width = view_size.width();
display_info_->right_eye->render_width = view_size.width();
display_info_->left_eye->render_height = view_size.height();
display_info_->right_eye->render_height = view_size.height();
session->display_info = display_info_.Clone();
std::move(callback).Run(
......
......@@ -23,10 +23,6 @@ OpenXrRenderLoop::~OpenXrRenderLoop() {
Stop();
}
gfx::Size OpenXrRenderLoop::GetViewSize() const {
return openxr_->GetViewSize();
}
mojom::XRFrameDataPtr OpenXrRenderLoop::GetNextFrameData() {
mojom::XRFrameDataPtr frame_data = mojom::XRFrameData::New();
frame_data->frame_id = next_frame_id_;
......@@ -56,23 +52,21 @@ mojom::XRFrameDataPtr OpenXrRenderLoop::GetNextFrameData() {
frame_data->pose->position = position;
}
bool updated_display_info = UpdateDisplayInfo();
bool updated_eye_parameters = UpdateEyeParameters();
bool updated_stage_parameters = UpdateStageParameters();
if (updated_eye_parameters) {
frame_data->left_eye = current_display_info_->left_eye.Clone();
frame_data->right_eye = current_display_info_->right_eye.Clone();
}
bool updated_stage_parameters = UpdateStageParameters();
if (updated_stage_parameters) {
frame_data->stage_parameters_updated = true;
frame_data->stage_parameters =
current_display_info_->stage_parameters.Clone();
}
if (updated_display_info || updated_eye_parameters ||
updated_stage_parameters) {
if (updated_eye_parameters || updated_stage_parameters) {
main_thread_task_runner_->PostTask(
FROM_HERE, base::BindOnce(on_display_info_changed_,
current_display_info_.Clone()));
......@@ -108,10 +102,11 @@ bool OpenXrRenderLoop::StartRuntime() {
// Starting session succeeded so we can set the member variable.
// Any additional code added below this should never fail.
openxr_ = std::move(openxr);
texture_helper_.SetDefaultSize(GetViewSize());
texture_helper_.SetDefaultSize(openxr_->GetViewSize());
DCHECK(openxr_);
DCHECK(input_helper_);
InitializeDisplayInfo();
return true;
}
......@@ -143,69 +138,56 @@ bool OpenXrRenderLoop::SubmitCompositedFrame() {
}
// Return true if display info has changed.
bool OpenXrRenderLoop::UpdateDisplayInfo() {
bool changed = false;
void OpenXrRenderLoop::InitializeDisplayInfo() {
if (!current_display_info_) {
current_display_info_ = mojom::VRDisplayInfo::New();
current_display_info_->id = device::mojom::XRDeviceId::OPENXR_DEVICE_ID;
current_display_info_->capabilities = mojom::VRDisplayCapabilities::New();
current_display_info_->capabilities->can_provide_environment_integration =
false;
current_display_info_->webvr_default_framebuffer_scale = 1.0f;
current_display_info_->webxr_default_framebuffer_scale = 1.0f;
changed = true;
current_display_info_->right_eye = mojom::VREyeParameters::New();
current_display_info_->left_eye = mojom::VREyeParameters::New();
}
std::string runtime_name = openxr_->GetRuntimeName();
if (current_display_info_->display_name != runtime_name) {
current_display_info_->display_name = runtime_name;
changed = true;
}
current_display_info_->id = device::mojom::XRDeviceId::OPENXR_DEVICE_ID;
current_display_info_->display_name = openxr_->GetRuntimeName();
bool has_position = openxr_->HasPosition();
if (current_display_info_->capabilities->has_position != has_position) {
current_display_info_->capabilities->has_position = has_position;
changed = true;
}
current_display_info_->capabilities = mojom::VRDisplayCapabilities::New();
current_display_info_->capabilities->can_provide_environment_integration =
false;
current_display_info_->capabilities->has_position = openxr_->HasPosition();
// OpenXR is initialized when creating the instance and getting the system
// was successful. If we are able to get a system, then we can present to
// an external display.
bool openxr_initialized = openxr_->IsInitialized();
if (current_display_info_->capabilities->has_external_display !=
openxr_initialized ||
current_display_info_->capabilities->can_present != openxr_initialized) {
current_display_info_->capabilities->has_external_display =
openxr_initialized;
current_display_info_->capabilities->can_present = openxr_initialized;
changed = true;
}
return changed;
current_display_info_->capabilities->has_external_display =
openxr_->IsInitialized();
current_display_info_->capabilities->can_present = openxr_->IsInitialized();
current_display_info_->webvr_default_framebuffer_scale = 1.0f;
current_display_info_->webxr_default_framebuffer_scale = 1.0f;
gfx::Size view_size = openxr_->GetViewSize();
current_display_info_->left_eye->render_width = view_size.width();
current_display_info_->right_eye->render_width = view_size.width();
current_display_info_->left_eye->render_height = view_size.height();
current_display_info_->right_eye->render_height = view_size.height();
// display info can't be send without fov info because of the mojo definition.
current_display_info_->left_eye->field_of_view =
mojom::VRFieldOfView::New(45.0f, 45.0f, 45.0f, 45.0f);
current_display_info_->right_eye->field_of_view =
current_display_info_->left_eye->field_of_view.Clone();
main_thread_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(on_display_info_changed_, current_display_info_.Clone()));
}
// return true if either left_eye or right_eye updated.
bool OpenXrRenderLoop::UpdateEyeParameters() {
bool changed = false;
if (!current_display_info_->left_eye) {
current_display_info_->left_eye = mojom::VREyeParameters::New();
changed = true;
}
if (!current_display_info_->right_eye) {
current_display_info_->right_eye = mojom::VREyeParameters::New();
changed = true;
}
XrView left;
XrView right;
openxr_->GetHeadFromEyes(&left, &right);
gfx::Size view_size = GetViewSize();
gfx::Size view_size = openxr_->GetViewSize();
changed |= UpdateEye(left, view_size, &current_display_info_->left_eye);
......
......@@ -24,8 +24,6 @@ class OpenXrRenderLoop : public XRCompositorCommon {
on_display_info_changed);
~OpenXrRenderLoop() override;
gfx::Size GetViewSize() const;
private:
// XRDeviceAbstraction:
mojom::XRFrameDataPtr GetNextFrameData() override;
......@@ -36,7 +34,7 @@ class OpenXrRenderLoop : public XRCompositorCommon {
bool HasSessionEnded() override;
bool SubmitCompositedFrame() override;
bool UpdateDisplayInfo();
void InitializeDisplayInfo();
bool UpdateEyeParameters();
bool UpdateEye(const XrView& view_head,
const gfx::Size& view_size,
......
......@@ -57,7 +57,7 @@ OpenXrTestHelper::OpenXrTestHelper()
session_state_(XR_SESSION_STATE_UNKNOWN),
swapchain_(XR_NULL_HANDLE),
acquired_swapchain_texture_(0),
next_action_space_(0),
next_space_(0),
next_predicted_display_time_(0) {}
OpenXrTestHelper::~OpenXrTestHelper() = default;
......@@ -71,7 +71,7 @@ void OpenXrTestHelper::Reset() {
system_id_ = 0;
d3d_device_ = nullptr;
acquired_swapchain_texture_ = 0;
next_action_space_ = 0;
next_space_ = 0;
next_predicted_display_time_ = 0;
// vectors
......@@ -230,7 +230,7 @@ XrResult OpenXrTestHelper::GetActionStatePose(XrAction action,
}
XrSpace OpenXrTestHelper::CreateReferenceSpace(XrReferenceSpaceType type) {
XrSpace cur_space = TreatIntegerAsHandle<XrSpace>(++next_action_space_);
XrSpace cur_space = TreatIntegerAsHandle<XrSpace>(++next_space_);
switch (type) {
case XR_REFERENCE_SPACE_TYPE_VIEW:
reference_spaces_[cur_space] = "/reference_space/view";
......@@ -296,7 +296,7 @@ XrActionSet OpenXrTestHelper::CreateActionSet(
}
XrSpace OpenXrTestHelper::CreateActionSpace(XrAction action) {
XrSpace cur_space = TreatIntegerAsHandle<XrSpace>(++next_action_space_);
XrSpace cur_space = TreatIntegerAsHandle<XrSpace>(++next_space_);
action_spaces_[cur_space] = action;
return cur_space;
}
......@@ -334,7 +334,6 @@ XrResult OpenXrTestHelper::BindActionAndPath(XrActionSuggestedBinding binding) {
"not cupported with current test");
current_action.binding = binding.binding;
std::string path_string = PathToString(current_action.binding);
DLOG(ERROR) << path_string;
return XR_SUCCESS;
}
......@@ -550,7 +549,18 @@ void OpenXrTestHelper::LocateSpace(XrSpace space, XrPosef* pose) {
base::Optional<gfx::Transform> transform = base::nullopt;
if (reference_spaces_.count(space) == 1) {
transform = GetPose();
if (reference_spaces_.at(space).compare("/reference_space/local") == 0) {
// this locate space call try to get tranform from stage to local which we
// only need to give it identity matrix.
transform = gfx::Transform();
} else if (reference_spaces_.at(space).compare("/reference_space/view") ==
0) {
// this locate space try to locate transform of head pose
transform = GetPose();
} else {
NOTREACHED()
<< "Only locate reference space for local and view are implemented";
}
} else if (action_spaces_.count(space) == 1) {
XrAction cur_action = action_spaces_.at(space);
ActionProperties cur_action_properties = actions_[cur_action];
......
......@@ -141,7 +141,7 @@ class OpenXrTestHelper : public device::ServiceTestHook {
Microsoft::WRL::ComPtr<ID3D11Device> d3d_device_;
std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D>> textures_arr_;
uint32_t acquired_swapchain_texture_;
uint32_t next_action_space_;
uint32_t next_space_;
XrTime next_predicted_display_time_;
// paths_ is used to keep tracked of strings that already has a corresponding
......
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