Commit 16dacd0d authored by Kevin Qin's avatar Kevin Qin Committed by Commit Bot

Validate IPD plumbing gets exposed to JS

Test runtime actually updates IPD after session starts.
In this test, I checked if runtime passed the IPD to
js side. But we have to notice that fov and ipd is only updated in
the following conditions:
1. "when the canvas element for this session's output context is
resized."
2. when "ApplyPendingRenderState()" gets called

Bug: 996502
Change-Id: I26496d0997290fbd2330a2a22e7dd1d40c5226ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1793946
Commit-Queue: Zheng Qin <zheqi@microsoft.com>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/master@{#696688}
parent ea3c4ed6
......@@ -16,6 +16,8 @@ namespace vr {
namespace {
const float kIPD = 0.2f;
struct Frame {
device_test::mojom::SubmittedFrameDataPtr submitted;
device_test::mojom::PoseFrameDataPtr pose;
......@@ -56,7 +58,7 @@ class MyXRMock : public MockXRDeviceHookBase {
device_test::mojom::DeviceConfigPtr GetDeviceConfig() {
auto config = device_test::mojom::DeviceConfig::New();
config->interpupillary_distance = 0.2f;
config->interpupillary_distance = kIPD;
config->projection_left =
device_test::mojom::ProjectionRaw::New(0.1f, 0.2f, 0.3f, 0.4f);
config->projection_right =
......@@ -170,6 +172,9 @@ WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F(TestPresentationPoses) {
// Load the test page, and enter presentation.
t->LoadUrlAndAwaitInitialization(
t->GetFileUrlForHtmlTestFile("test_webxr_poses"));
ASSERT_TRUE(
t->RunJavaScriptAndExtractBoolOrFail("checkMagicWindowViewOffset()"))
<< "view under Magic Window should not have any offset from frame";
t->EnterSessionWithUserGestureOrFail();
// Wait for JavaScript to submit at least one frame.
......@@ -227,6 +232,10 @@ WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F(TestPresentationPoses) {
ASSERT_TRUE(t->RunJavaScriptAndExtractBoolOrFail(base::StringPrintf(
"checkFramePose(%d, %s)", frame_id, GetPoseAsString(frame).c_str())))
<< "JavaScript-side frame cache has incorrect pose";
ASSERT_TRUE(t->RunJavaScriptAndExtractBoolOrFail(
base::StringPrintf("checkFrameLeftEyeIPD(%d, %f)", frame_id, kIPD / 2)))
<< "JavaScript-side frame cache has incorrect eye position";
}
// Tell JavaScript that it is done with the test.
......
......@@ -18,6 +18,9 @@ test can query for whether each submitted frame used the correct pose.
var frame_id = 0;
var frame_data_array = {};
var pose_array = {};
var magic_window_frame_id = 0;
var magic_window_frame_position_array = {};
var magic_window_view_position_array = {};
// We exit presentation before checking stuff that needs the frame of
// reference, so we need to cache its value.
var cached_frame_of_ref = null;
......@@ -33,6 +36,10 @@ test can query for whether each submitted frame used the correct pose.
return true;
}
function PositionCompare(a, b) {
return FloatCompare(a.x, b.x) && FloatCompare(a.y, b.y) && FloatCompare(a.z, b.z);
}
function checkFrameOccurred(frame_id) {
return frame_id in frame_data_array;
}
......@@ -58,6 +65,39 @@ test can query for whether each submitted frame used the correct pose.
return MatrixCompare(pose.transform.matrix, expected);
}
function checkFrameLeftEyeIPD(frame_id, expected) {
let left_eye = null;
if (pose_array[frame_id].views[0].eye == "left") {
left_eye = pose_array[frame_id].views[0];
} else {
left_eye = pose_array[frame_id].views[1];
}
let position = left_eye.transform.position;
console.log(position.x)
return FloatCompare(position.x, expected);
}
function checkMagicWindowViewOffset() {
for (i = 1; i <= magic_window_frame_id; i++) {
let magic_window_frame_position = magic_window_frame_position_array[i];
let magic_window_view_position = magic_window_view_position_array[i];
if (!PositionCompare(magic_window_frame_position, magic_window_view_position)) {
return false;
}
}
return true;
}
onMagicWindowXRFrameCallback = function(session, frame) {
magic_window_frame_id++;
cached_frame_of_ref = sessionInfos[sessionTypes.MAGIC_WINDOW].currentRefSpace;
let pose = frame.getViewerPose(cached_frame_of_ref);
magic_window_frame_position_array[magic_window_frame_id] = pose.transform.position;
let view = pose.views[0];
magic_window_view_position_array[magic_window_frame_id] = view.transform.position;
}
onImmersiveXRFrameCallback = function(session, frame, gl) {
// Encode an index into the clear color.
frame_id++;
......
......@@ -439,7 +439,8 @@ HmdMatrix34_t TestVRSystem::GetEyeToHeadTransform(EVREye eye) {
ret.m[0][0] = 1;
ret.m[1][1] = 1;
ret.m[2][2] = 1;
ret.m[0][3] = (eye == Eye_Left) ? 0.1f : -0.1f;
float ipd = g_test_helper.GetInterpupillaryDistance();
ret.m[0][3] = ((eye == Eye_Left) ? 1 : -1) * ipd / 2;
return ret;
}
......
......@@ -582,6 +582,11 @@ XrResult xrLocateViews(XrSession session,
XR_ERROR_VALIDATION_FAILURE,
"xrLocateViews view_locate_info type invalid");
RETURN_IF_XR_FAILED(g_test_helper.ValidateSpace(view_locate_info->space));
if (view_capacity_input != 0) {
RETURN_IF_FALSE(g_test_helper.UpdateViewFOV(views, view_capacity_input),
XR_ERROR_VALIDATION_FAILURE,
"xrLocateViews UpdateViewFOV failed");
}
return XR_SUCCESS;
}
......
......@@ -458,6 +458,18 @@ bool OpenXrTestHelper::UpdateData() {
return false;
}
bool OpenXrTestHelper::UpdateViewFOV(XrView views[], uint32_t size) {
RETURN_IF(size != 2, XR_ERROR_VALIDATION_FAILURE,
"UpdateViewFOV currently only supports 2 viewports config");
base::AutoLock auto_lock(lock_);
if (test_hook_) {
auto config = test_hook_->WaitGetDeviceConfig();
views[0].pose.position.x = config.interpupillary_distance / 2;
views[1].pose.position.x = -config.interpupillary_distance / 2;
}
return true;
}
XrResult OpenXrTestHelper::ValidateAction(XrAction action) const {
RETURN_IF(actions_.count(action) != 1, XR_ERROR_HANDLE_INVALID,
"ValidateAction: Invalid Action");
......
......@@ -64,6 +64,7 @@ class OpenXrTestHelper : public device::ServiceTestHook {
void GetPose(XrPosef* pose);
std::string PathToString(XrPath path) const;
bool UpdateData();
bool UpdateViewFOV(XrView views[], uint32_t size);
uint32_t NextSwapchainImageIndex();
XrTime NextPredictedDisplayTime();
......
......@@ -135,7 +135,13 @@ bool MockWMRCameraPose::TryGetViewTransform(
float col_major_transform[16];
origin_to_device.matrix().asColMajorf(col_major_transform);
// index of matrix[3][0] in 1d array
int index = 3 * 4;
float original_x = col_major_transform[index];
float ipd = hook.GetHook()->WaitGetDeviceConfig().interpupillary_distance;
col_major_transform[index] = original_x - ipd / 2;
CopyRowMajorFloatArrayToWindowsMatrix(col_major_transform, transform->Left);
col_major_transform[index] = original_x + ipd / 2;
CopyRowMajorFloatArrayToWindowsMatrix(col_major_transform, transform->Right);
return true;
......
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