Commit 4de1c6cf authored by Kevin Qin's avatar Kevin Qin Committed by Commit Bot

OpenXR Plumb XrVisibility to Blink

XRVisibilityState is always visible when using the OpenXR backend. The
visibility state from the runtime needs to be plumbed back to
Blink/Javascript.

Fixed: 1024032
Change-Id: I98bb2f3e5440b407dfff97a8799c3fecc15f7a85
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1913578Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Commit-Queue: Zheng Qin <zheqi@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#718875}
parent 5c164e1d
......@@ -138,6 +138,31 @@ IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestInsanceLost) {
TestWebXRSessionEndWhenEventTriggered(
this, device_test::mojom::EventType::kInstanceLost);
}
IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestVisibilityChanged) {
MockXRDeviceHookBase transition_mock;
this->LoadUrlAndAwaitInitialization(
this->GetFileUrlForHtmlTestFile("webxr_test_visibility_changed"));
this->EnterSessionWithUserGestureOrFail();
// Wait for JavaScript to submit at least one frame.
ASSERT_TRUE(this->PollJavaScriptBoolean("hasPresentedFrame",
this->kPollTimeoutMedium))
<< "No frame submitted";
this->PollJavaScriptBooleanOrFail("isVisibilityEqualTo('visible')",
this->kPollTimeoutMedium);
device_test::mojom::EventData event_data = {};
event_data.type = device_test::mojom::EventType::kVisibilityVisibleBlurred;
transition_mock.PopulateEvent(event_data);
// TODO(crbug.com/1002742): visible-blurred is forced to hidden in WebXR
this->PollJavaScriptBooleanOrFail("isVisibilityEqualTo('hidden')",
this->kPollTimeoutMedium);
this->RunJavaScriptOrFail("done()");
this->EndTest();
}
#endif // BUILDFLAG(ENABLE_OPENXR)
#endif // OS_WIN
......
<!doctype html>
<!--
Tests WebXR Using OpenXR End Session correctly when XR_SESSION_STATE_STOPPING
event received.
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css">
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<script src="../../../../../../third_party/blink/web_tests/resources/testharness.js"></script>
<script src="../resources/webxr_e2e.js"></script>
<script src="../resources/webxr_boilerplate.js"></script>
<script>
function currentImmersiveSession() {
return sessionInfos[sessionTypes.IMMERSIVE].currentSession;
}
function isVisibilityEqualTo(expected) {
return currentImmersiveSession().visibilityState == expected;
}
</script>
</body>
</html>
......@@ -593,6 +593,18 @@ XrResult OpenXrApiWrapper::ProcessEvents() {
session_ended_ = true;
RETURN_IF_XR_FAILED(xrEndSession(session_));
break;
case XR_SESSION_STATE_SYNCHRONIZED:
visibility_changed_callback_.Run(
device::mojom::XRVisibilityState::HIDDEN);
break;
case XR_SESSION_STATE_VISIBLE:
visibility_changed_callback_.Run(
device::mojom::XRVisibilityState::VISIBLE_BLURRED);
break;
case XR_SESSION_STATE_FOCUSED:
visibility_changed_callback_.Run(
device::mojom::XRVisibilityState::VISIBLE);
break;
default:
break;
}
......@@ -718,6 +730,12 @@ void OpenXrApiWrapper::RegisterInteractionProfileChangeCallback(
std::move(interaction_profile_callback);
}
void OpenXrApiWrapper::RegisterVisibilityChangeCallback(
const base::RepeatingCallback<void(mojom::XRVisibilityState)>&
visibility_changed_callback) {
visibility_changed_callback_ = std::move(visibility_changed_callback);
}
VRTestHook* OpenXrApiWrapper::test_hook_ = nullptr;
ServiceTestHook* OpenXrApiWrapper::service_test_hook_ = nullptr;
void OpenXrApiWrapper::SetTestHook(VRTestHook* hook) {
......
......@@ -14,6 +14,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "device/vr/vr_export.h"
#include "third_party/openxr/src/include/openxr/openxr.h"
#include "third_party/openxr/src/include/openxr/openxr_platform.h"
......@@ -62,6 +63,9 @@ class OpenXrApiWrapper {
void RegisterInteractionProfileChangeCallback(
const base::RepeatingCallback<void(XrResult*)>&
interaction_profile_callback);
void RegisterVisibilityChangeCallback(
const base::RepeatingCallback<void(mojom::XRVisibilityState)>&
visibility_changed_callback);
static void DEVICE_VR_EXPORT SetTestHook(VRTestHook* hook);
......@@ -101,6 +105,8 @@ class OpenXrApiWrapper {
base::RepeatingCallback<void(XrResult*)>
interaction_profile_changed_callback_;
base::RepeatingCallback<void(mojom::XRVisibilityState)>
visibility_changed_callback_;
// Testing objects
static VRTestHook* test_hook_;
......
......@@ -108,17 +108,19 @@ void OpenXrDevice::RequestSession(
base::BindOnce(&OpenXrDevice::OnRequestSessionResult,
weak_ptr_factory_.GetWeakPtr(), std::move(callback));
auto on_visibility_state_changed = base::BindRepeating(
&OpenXrDevice::OnVisibilityStateChanged, weak_ptr_factory_.GetWeakPtr());
// 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(),
base::DoNothing::Repeatedly<mojom::XRVisibilityState>(),
std::move(options), std::move(my_callback)));
FROM_HERE, base::BindOnce(&XRCompositorCommon::RequestSession,
base::Unretained(render_loop_.get()),
base::DoNothing::Once(),
std::move(on_visibility_state_changed),
std::move(options), std::move(my_callback)));
}
void OpenXrDevice::OnRequestSessionResult(
......
......@@ -108,9 +108,8 @@ bool OpenXrRenderLoop::StartRuntime() {
openxr_->RegisterInteractionProfileChangeCallback(
base::BindRepeating(&OpenXRInputHelper::OnInteractionProfileChanged,
input_helper_->GetWeakPtr()));
DCHECK(openxr_);
DCHECK(input_helper_);
openxr_->RegisterVisibilityChangeCallback(base::BindRepeating(
&OpenXrRenderLoop::SetVisibilityState, weak_ptr_factory_.GetWeakPtr()));
InitializeDisplayInfo();
return true;
......
......@@ -51,6 +51,9 @@ class OpenXrRenderLoop : public XRCompositorCommon {
on_display_info_changed_;
mojom::VRDisplayInfoPtr current_display_info_;
// This must be the last member
base::WeakPtrFactory<OpenXrRenderLoop> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(OpenXrRenderLoop);
};
......
......@@ -353,7 +353,7 @@ XrResult OpenXrTestHelper::BeginSession() {
RETURN_IF(session_state_ != XR_SESSION_STATE_READY,
XR_ERROR_SESSION_NOT_READY,
"Session is not XR_ERROR_SESSION_NOT_READY");
SetSessionState(XR_SESSION_STATE_SYNCHRONIZED);
SetSessionState(XR_SESSION_STATE_FOCUSED);
return XR_SUCCESS;
}
......@@ -614,6 +614,10 @@ void OpenXrTestHelper::UpdateEventQueue() {
data = test_hook_->WaitGetEventData();
if (data.type == device_test::mojom::EventType::kSessionLost) {
SetSessionState(XR_SESSION_STATE_STOPPING);
} else if (data.type ==
device_test::mojom::EventType::kVisibilityVisibleBlurred) {
// WebXR Visible-Blurred map to OpenXR Visible
SetSessionState(XR_SESSION_STATE_VISIBLE);
} else if (data.type == device_test::mojom::EventType::kInstanceLost) {
XrEventDataBuffer event_data = {
XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING};
......
......@@ -83,6 +83,7 @@ struct ControllerFrameData {
// Event type is used by test to simulate runtime events.
enum EventType {
kSessionLost,
kVisibilityVisibleBlurred,
kInstanceLost,
kNoEvent
};
......
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