Commit 986227d3 authored by Anna Offenwanger's avatar Anna Offenwanger Committed by Commit Bot

Clean up the WebXR test folder

Detached the xr test folder from the vr test folder by creating its own
set of helper classes. Converted all tests to promise tests where it
made sense. As much as possible detached chrome specific code for when
we convert tests to WPTs.

Bug: 777567
Change-Id: I90e7800cbf86b09f72937033e4a840d1f5719b61
Reviewed-on: https://chromium-review.googlesource.com/889652
Commit-Queue: Anna Offenwanger <offenwanger@chromium.org>
Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532987}
parent 22d144fd
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script> <script>
let fakeDisplays = fakeVRDisplays(); promise_test((t) => {
setFakeDevices([fakeXRDevices()["FakeGooglePixelPhone"]]);
vr_test((t, mockService) => {
let watcherDone = new Event("watcherdone"); let watcherDone = new Event("watcherdone");
let eventWatcher = new EventWatcher(t, navigator.xr, ["devicechange", let eventWatcher = new EventWatcher(t, navigator.xr, ["devicechange",
"watcherdone"]); "watcherdone"]);
eventWatcher.wait_for(["devicechange", "watcherdone"])
.then( () => {
t.done();
});
// The event should fire when a listener is added even if the devices are not // The event should fire when a listener is added even if the devices are not
// explicity queried with navigator.xr.requestDevice(). // explicity queried with navigator.xr.requestDevice().
function onDeviceChange() { function onDeviceChange() {
t.step( () => { navigator.xr.dispatchEvent(watcherDone);
navigator.xr.dispatchEvent(watcherDone); };
});
}
navigator.xr.addEventListener("devicechange", onDeviceChange, false); navigator.xr.addEventListener("devicechange", onDeviceChange, false);
}, [fakeDisplays["Pixel"]], return eventWatcher.wait_for(["devicechange", "watcherdone"]);
"Test devicechange fires when devices are connected.");
}, "Test devicechange fires when devices are connected.");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script>
let fakeDisplays = fakeVRDisplays();
vr_test((t, mockService) => { <script>
let watcherDone = new Event("watcherdone");
navigator.xr.requestDevice().then( (device) => { let fakeDevices = fakeXRDevices();
runWithUserGesture( () => { let watcherDone = new Event("watcherdone");
device.requestSession({ exclusive: true }).then( (session) => {
let eventWatcher = new EventWatcher(t, session, ["end", "watcherdone"]);
let eventPromise = eventWatcher.wait_for(["end", "watcherdone"]);
function onSessionEnd(event) { xr_session_promise_test( (session, t) => {
t.step( () => { let eventWatcher = new EventWatcher(t, session, ["end", "watcherdone"]);
assert_equals(event.session, session); let eventPromise = eventWatcher.wait_for(["end", "watcherdone"]);
session.dispatchEvent(watcherDone);
});
}
session.addEventListener("end", onSessionEnd, false);
session.end();
return eventPromise; function onSessionEnd(event) {
}, (err) => {
t.step( () => {
assert_unreached("requestSession rejected");
});
}).then( () => {
t.done();
});
});
}, (err) => {
t.step( () => { t.step( () => {
assert_unreached("requestDevice rejected"); assert_equals(event.session, session);
session.dispatchEvent(watcherDone);
}); });
}); }
}, [fakeDisplays["Pixel"]], session.addEventListener("end", onSessionEnd, false);
"Test deviceconnect fires when devices are connected."); session.end();
return eventPromise;
}, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"Test end fires when session ends");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session) => { xr_session_promise_test( (session) => new Promise((resolve) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl); session.baseLayer = new XRWebGLLayer(session, gl);
function onFrame(time, xrFrame) { function onFrame(time, xrFrame) {
t.step( () => {
assert_true(xrFrame instanceof XRPresentationFrame); assert_true(xrFrame instanceof XRPresentationFrame);
}); // Test does not complete until the returned promise resolves.
t.done(); resolve();
} }
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRSession requestAnimationFrame properly calls the provided callback"); "XRSession requestAnimationFrame properly calls the provided callback");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session) => { xr_session_promise_test( (session) => new Promise((resolve) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl); session.baseLayer = new XRWebGLLayer(session, gl);
...@@ -18,12 +19,12 @@ xr_session_test( (t, session) => { ...@@ -18,12 +19,12 @@ xr_session_test( (t, session) => {
function onFrame(time, vrFrame) { function onFrame(time, vrFrame) {
// Intentionally session.requestAnimationFrame at the beginning, ensuring that // Intentionally session.requestAnimationFrame at the beginning, ensuring that
// there's an outstanding callback when t.done() is called. This is to make // there's an outstanding callback when the test completes. This is to make
// sure it doesn't cause any unexpected behavior like it did with // sure it doesn't cause any unexpected behavior like it did with
// crbug.com/679401 // crbug.com/679401
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
if (counter > 10) { if (counter > 10) {
t.done(); resolve();
} }
counter++; counter++;
} }
...@@ -35,7 +36,7 @@ xr_session_test( (t, session) => { ...@@ -35,7 +36,7 @@ xr_session_test( (t, session) => {
session.cancelAnimationFrame(handle - 1); session.cancelAnimationFrame(handle - 1);
session.cancelAnimationFrame(0.5); session.cancelAnimationFrame(0.5);
session.cancelAnimationFrame(null); session.cancelAnimationFrame(null);
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRSession cancelAnimationFrame does not have unexpected behavior when given invalid handles"); "XRSession cancelAnimationFrame does not have unexpected behavior when given invalid handles");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session) => { xr_session_promise_test( (session) => new Promise((resolve, reject) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
let webglLayer = new XRWebGLLayer(session, gl); let webglLayer = new XRWebGLLayer(session, gl);
function onBadFrame(time, vrFrame) { function onBadFrame(time, vrFrame) {
t.step( () => { reject("Callback registered without layer was called");
assert_unreached("Callback registered without layer was called");
});
t.done();
} }
function onGoodFrame(time, vrFrame) { function onGoodFrame(time, vrFrame) {
t.done(); resolve();
} }
// This callback shouldn't be allowed to register, since the session doesn't // This callback shouldn't be allowed to register, since the session doesn't
// have a baseLayer when this call is made. // have a baseLayer when this call is made.
let badHandle = session.requestAnimationFrame(onBadFrame); let badHandle = session.requestAnimationFrame(onBadFrame);
assert_equals(badHandle, 0);
t.step( () => {
assert_equals(badHandle, 0);
});
// Once the base layer is set the callback should be allowed. // Once the base layer is set the callback should be allowed.
session.baseLayer = webglLayer; session.baseLayer = webglLayer;
let goodHandle = session.requestAnimationFrame(onGoodFrame); let goodHandle = session.requestAnimationFrame(onGoodFrame);
assert_not_equals(goodHandle, 0);
t.step( () => { }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
assert_not_equals(goodHandle, 0);
});
}, fakeDisplays["Pixel"], { exclusive: true },
"XRSession requestAnimationFrame must fail if the session has no baseLayer"); "XRSession requestAnimationFrame must fail if the session has no baseLayer");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session) => { xr_session_promise_test( (session) => new Promise((resolve, reject) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl); session.baseLayer = new XRWebGLLayer(session, gl);
function onFrameBad(time, vrFrame) { function onFrameBad(time, vrFrame) {
t.step( () => { reject("Unregistered callback was called");
assert_unreached("Unregistered callback was called");
});
t.done();
} }
let counter = 0; let counter = 0;
...@@ -26,7 +23,7 @@ xr_session_test( (t, session) => { ...@@ -26,7 +23,7 @@ xr_session_test( (t, session) => {
function onFrameGood(time, vrFrame) { function onFrameGood(time, vrFrame) {
counter++; counter++;
if (counter >= 4) { if (counter >= 4) {
t.done(); resolve();
// Intentionally don't return immediately so that session.requestAnimationFrame // Intentionally don't return immediately so that session.requestAnimationFrame
// gets called again to make sure it doesn't cause unexpected behavior // gets called again to make sure it doesn't cause unexpected behavior
// like in crbug.com/679401 // like in crbug.com/679401
...@@ -47,7 +44,7 @@ xr_session_test( (t, session) => { ...@@ -47,7 +44,7 @@ xr_session_test( (t, session) => {
session.cancelAnimationFrame(handle); session.cancelAnimationFrame(handle);
session.requestAnimationFrame(onFrameGood); session.requestAnimationFrame(onFrameGood);
handle2 = session.requestAnimationFrame(onFrameBad); handle2 = session.requestAnimationFrame(onFrameBad);
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRSession requestAnimationFrame callbacks can be unregistered with cancelAnimationFrame"); "XRSession requestAnimationFrame callbacks can be unregistered with cancelAnimationFrame");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => {
// Session must have a baseLayer or else frame requests will be ignored. // Session must have a baseLayer or else frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl); session.baseLayer = new XRWebGLLayer(session, gl);
session.requestFrameOfReference("eyeLevel").then((frameOfRef) => { return session.requestFrameOfReference("eyeLevel")
let expected_pose = VALID_POSE; .then((frameOfRef) => new Promise((resolve, reject) => {
let counter = 0; let expected_pose = VALID_POSE;
let counter = 0;
function onFrame(time, vrFrame) { function onFrame(time, vrFrame) {
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
if (counter == 0) { if (counter == 0) {
t.step( () => { // Expecting to not get a pose since none has been supplied
assert_equals(vrFrame.getDevicePose(frameOfRef), null); assert_equals(vrFrame.getDevicePose(frameOfRef), null);
}, "Expecting to not get a pose since none has been supplied");
mockService.mockVRDisplays_[0].setPose(expected_pose); setPose(expected_pose);
t.step( () => {
// Check that pose does not update pose within the same frame.
assert_equals(vrFrame.getDevicePose(frameOfRef), null); assert_equals(vrFrame.getDevicePose(frameOfRef), null);
}, "Does not update pose within the same frame"); } else {
} else { // Check that pose was updated.
t.step( () => {
let pose = vrFrame.getDevicePose(frameOfRef); let pose = vrFrame.getDevicePose(frameOfRef);
assert_not_equals(pose, null); assert_not_equals(pose, null);
...@@ -39,15 +39,16 @@ xr_session_test( (t, session, mockService) => { ...@@ -39,15 +39,16 @@ xr_session_test( (t, session, mockService) => {
let expectedMatrix = matrixFrom11Pose(expected_pose); let expectedMatrix = matrixFrom11Pose(expected_pose);
assert_matrices_approx_equal(poseMatrix, expectedMatrix); assert_matrices_approx_equal(poseMatrix, expectedMatrix);
}, "Pose was updated in the next frame");
t.done(); // Finished.
resolve();
}
counter++;
} }
counter++;
}
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
}); }));
}, fakeDisplays["Pixel"], { exclusive: true }, }, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRPresentationFrame getDevicePose updates on the next frame"); "XRPresentationFrame getDevicePose updates on the next frame");
</script> </script>
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script> <script>
promise_test(t => navigator.getVRDisplays().then(() => { promise_test((t) => navigator.getVRDisplays().then(() => {
assert_true(navigator.xr == null); assert_true(navigator.xr == null);
}), "Test that access to navigator.xr is blocked once navigator.getVRDisplays has been called."); }), "Test that access to navigator.xr is blocked once navigator.getVRDisplays has been called.");
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script> <script>
promise_test(t => navigator.xr.requestDevice().catch(() => { promise_test((t) => navigator.xr.requestDevice().catch(() => {
return promise_rejects(t, "InvalidStateError", navigator.getVRDisplays()); return promise_rejects(t, "InvalidStateError", navigator.getVRDisplays());
}), "Test that calls to navigator.getVRDisplays are blocked once navigator.xr has been accessed."); }), "Test that calls to navigator.getVRDisplays are blocked once navigator.xr has been accessed.");
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<iframe sandbox="allow-same-origin" id="subframe"></iframe> <iframe sandbox="allow-same-origin" id="subframe"></iframe>
<script> <script>
promise_test(t => { promise_test((t) => {
var nav_xr = window.frames[0].navigator.xr; var nav_xr = window.frames[0].navigator.xr;
document.getElementById("subframe").remove(); document.getElementById("subframe").remove();
return promise_rejects(t, "InvalidStateError", nav_xr.requestDevice()); return promise_rejects(t, "InvalidStateError", nav_xr.requestDevice());
......
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test((t) => {
setFakeDevices([fakeDevices["FakeGooglePixelPhone"]]);
return navigator.xr.requestDevice().then( (device) => { return navigator.xr.requestDevice().then( (device) => {
t.step( () => { assert_true(device != null);
assert_true(device != null); assert_false(device.external);
assert_false(device.external);
}, "requestDevice returned correct results");
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
});
}).then( () => {
t.done();
}); });
}, [fakeDisplays["Pixel"]], }, "navigator.xr.requestDevice properly returns a single device");
"navigator.xr.requestDevice properly returns a single device");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
// TODO(offenwanger) When we know how to we want to select which device to // TODO(offenwanger) When we know how to we want to select which device to
// return, update this test. // return, update this test.
setFakeDevices([fakeDevices["FakeGooglePixelPhone"], fakeDevices["FakeMagicWindowOnly"]]);
return navigator.xr.requestDevice().then( (device) => { return navigator.xr.requestDevice().then( (device) => {
t.step( () => { assert_true(device != null);
assert_true(device != null); assert_false(device.external);
}, "requestDevice returned result");
t.step( () => {
assert_false(device.external);
}, "Attribute for device is correct");
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
});
}).then( () => {
t.done();
}); });
}, [fakeDisplays["Pixel"], fakeDisplays["FakeMagicWindowOnly"]], }, "navigator.xr.requestDevice properly returns one device when there are two");
"navigator.xr.requestDevice properly returns one device when there are two");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
return navigator.xr.requestDevice().then( (device) => { return promise_rejects(t, 'NotFoundError', navigator.xr.requestDevice());
t.step( () => { }, "navigator.xr.requestDevice properly rejects when there are 0 devices");
assert_unreached("requestDevice resolved");
}, "requestDevice resolved when it shouldn't have");
}, (err) => {
t.step( () => {
assert_equals(err.name, "NotFoundError")
t.done();
});
});
}, [],
"navigator.xr.requestDevice properly returns zero devices");
</script> </script>
\ No newline at end of file
// assert_equals can fail when comparing floats due to precision errors, so
// use assert_approx_equals with this constant instead
var FLOAT_EPSILON = 0.000001;
// A valid VRPose for when we don't care about specific values
var VALID_POSE = {
position: [1.1, 2.2, 3.3],
linearVelocity: [0.1, 0.2, 0.3],
linearAcceleration: [0.0, 0.1, 0.2],
orientation: [0.1, 0.2, 0.3, 0.4],
angularVelocity: [1.1, 2.1, 3.1],
angularAcceleration: [1.0, 2.0, 3.0]
}
// func: A function that takes a session and optionally a test object and
// performs tests. If func returns a promise, test will only pass if the promise
// resolves.
function xr_session_promise_test(
func, device, sessionOptions, name, properties) {
if (document.getElementById('webgl-canvas') ||
document.getElementById('webgl2-canvas')) {
webglCanvasSetup();
}
addFakeDevice(device);
promise_test((t) => {
return navigator.xr.requestDevice().then(
(device) => new Promise((resolve, reject) => {
// Perform the session request in a user gesture.
runWithUserGesture(() => {
resolve(device.requestSession(sessionOptions)
.then((session) => func(session, t)));
});
}));
}, name, properties);
}
let webglCanvas, gl;
function webglCanvasSetup() {
let webgl2 = false;
webglCanvas = document.getElementById('webgl-canvas');
if (!webglCanvas) {
webglCanvas = document.getElementById('webgl2-canvas');
webgl2 = true;
}
let glAttributes = {
alpha: false,
antialias: false,
};
gl = webglCanvas.getContext(webgl2 ? 'webgl2' : 'webgl', glAttributes);
}
// TODO(offenwanger): eventSender cannot be used with WPTs. Find another way to
// fake use gestures.
// https://chromium.googlesource.com/chromium/src/+/lkgr/docs/testing/web_platform_tests.md#tests-that-require-testing-apis
function runWithUserGesture(fn) {
function thunk() {
document.removeEventListener('keypress', thunk, false);
fn()
}
document.addEventListener('keypress', thunk, false);
eventSender.keyDown(' ', []);
}
\ No newline at end of file
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script>
let fakeDisplays = fakeVRDisplays();
vr_test( (t) => {
return navigator.xr.requestDevice().then( (device) => {
device.requestSession({ exclusive: true }).then(() => {
assert_unreached("requestSession resolved unexpectedly");
}).catch((e) => {
assert_equals(e.name, "InvalidStateError");
t.done();
});
}, (err) => { <script>
t.step( () => { let fakeDevices = fakeXRDevices();
assert_unreached("getDevices rejected"); promise_test( (t) => {
}); setFakeDevices([fakeDevices["FakeGooglePixelPhone"]]);
}); return navigator.xr.requestDevice().then( (device) =>
}, [fakeDisplays["Pixel"]], promise_rejects(t, 'InvalidStateError', device.requestSession({ exclusive: true })));
"requestSession with an exclusive session outside of a user gesture rejects"); }, "requestSession with an exclusive session outside of a user gesture rejects");
</script>
\ No newline at end of file
</script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script>
let fakeDisplays = fakeVRDisplays();
vr_test( (t) => {
return navigator.xr.requestDevice().then( (device) => {
runWithUserGesture( () => { <script>
device.requestSession({ exclusive: true }).then( (session) => { let fakeDevices = fakeXRDevices();
t.step( () => {
assert_true(session.exclusive);
}, "requestSession resolved as expected");
}, (err) => {
t.step( () => {
assert_unreached("requestSession rejected unexpectedly");
});
}).then( () => {
t.done();
});
});
}, (err) => { xr_session_promise_test( (session) => {
t.step( () => { assert_not_equals(session, null);
assert_unreached("getDevices rejected"); }, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
});
});
}, [fakeDisplays["Pixel"]],
"requestSession for an exclusive session with a user gesture resolves"); "requestSession for an exclusive session with a user gesture resolves");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
return navigator.xr.requestDevice().then( (magicWindowOnlyDevice) => { setFakeDevices([fakeDevices["FakeMagicWindowOnly"]]);
runWithUserGesture( () => {
magicWindowOnlyDevice.requestSession({ exclusive: true }).then(() => { return navigator.xr.requestDevice()
assert_unreached("requestSession resolved unexpectedly"); .then( (magicWindowOnlyDevice) => new Promise((resolve) => {
}, (e) => { runWithUserGesture( () => {
assert_equals(e.name, "NotSupportedError"); resolve(promise_rejects(
t.done(); t,
"NotSupportedError",
magicWindowOnlyDevice.requestSession({ exclusive: true })
))
}); });
}));
}); }, "requesting an exclusive session on an unsupported device rejects");
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
});
});
}, [fakeDisplays["FakeMagicWindowOnly"]],
"requesting an exclusive session on an unsupported device rejects");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
setFakeDevices([fakeDevices["FakeMagicWindowOnly"]]);
return navigator.xr.requestDevice().then( (magicWindowOnlyDevice) => { return navigator.xr.requestDevice().then( (magicWindowOnlyDevice) => {
return promise_rejects(
magicWindowOnlyDevice.supportsSession({ exclusive: true }).then( () => { t,
t.step( () => { "NotSupportedError",
assert_unreached("supportsSession unexpectedly allowed exclusive"); magicWindowOnlyDevice.supportsSession({ exclusive: true })
}); );
}, () => {
// Expected result. Test complete.
t.done();
});
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
});
}); });
}, [fakeDisplays["FakeMagicWindowOnly"]], }, "supportsSession rejects when exclusive session is not supported on device");
"supportsSession rejects when exclusive session is not supported on device");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( () => {
return navigator.xr.requestDevice().then( (device) => { setFakeDevices([fakeDevices["FakeGooglePixelPhone"]]);
return navigator.xr.requestDevice().then( (device) =>
device.supportsSession({ exclusive: true }).then( () => { device.supportsSession({ exclusive: true }));
// Expected result }, "supportsSession resolves when support exclusive session is supported on device");
t.done();
}, () => {
t.step( () => {
assert_unreached("supportsSession unexpectedly rejected exclusive");
});
});
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
});
});
}, [fakeDisplays["Pixel"]],
"supportsSession resolves when support exclusive session is supported on device");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
return navigator.xr.requestDevice().then( (device) => { setFakeDevices([fakeDevices["FakeGooglePixelPhone"]]);
return navigator.xr.requestDevice().then( (device) =>
device.supportsSession().then( () => { promise_rejects(t, 'NotSupportedError', device.supportsSession())
t.step( () => { );
assert_unreached("supportsSession unexpectedly allowed non-exclusive session without an output context"); }, "supportsSession properly identifies supported non-exclusive sessions");
});
}).catch( () => {
// Expected result, test is finished.
t.done();
});
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
});
});
}, [fakeDisplays["Pixel"]],
"supportsSession properly identifies supported non-exclusive sessions");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
return navigator.xr.requestDevice().then( (device) => { setFakeDevices([fakeDevices["FakeGooglePixelPhone"]]);
return navigator.xr.requestDevice().then( (device) => new Promise((resolve) => {
runWithUserGesture( () => { runWithUserGesture( () => {
device.requestSession({ exclusive: true }).then( (session) => { resolve(device.requestSession({ exclusive: true }).then( (session) => {
t.step( () => { assert_true(session.exclusive);
assert_true(session.exclusive); assert_equals(session.device, device);
assert_equals(session.device, device); assert_approx_equals(session.depthNear, 0.1, FLOAT_EPSILON);
assert_approx_equals(session.depthNear, 0.1, FLOAT_EPSILON); assert_approx_equals(session.depthFar, 1000.0, FLOAT_EPSILON);
assert_approx_equals(session.depthFar, 1000.0, FLOAT_EPSILON); }));
}, "requestSession returned correct results");
}, (err) => {
t.step( () => {
assert_unreached("requestSession rejected");
});
}).then( () => {
t.done();
});
});
}, (err) => {
t.step( () => {
assert_unreached("requestDevice rejected");
}); });
}); }));
}, [fakeDisplays["Pixel"]], }, "supportsSession returns expected exclusive session");
"supportsSession returns expected exclusive session");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
vr_test( (t) => { promise_test( (t) => {
return navigator.xr.requestDevice().then( (device) => { setFakeDevices([fakeDevices["FakeGooglePixelPhone"]]);
return navigator.xr.requestDevice().then( (device) => new Promise((resolve) => {
runWithUserGesture( () => { runWithUserGesture( () => {
device.requestSession({ exclusive: true }).then( (session) => { resolve(device.requestSession({ exclusive: true })
runWithUserGesture( () => { .then( (session) => new Promise((resolve) => {
// Requesting a second exclusive session from a device that already runWithUserGesture( () => {
// has an active exclusive session should fail. Exclusive sessions // Requesting a second exclusive session from a device that already
// are, well... exclusive! // has an active exclusive session should fail. Exclusive sessions
promise_rejects(t, "InvalidStateError", device.requestSession({ exclusive: true })).then( () => { // are, well... exclusive!
// End the exclusive session and try again. Now the exclusive resolve(promise_rejects(
// session creation should succeed. t,
session.end().then( () => { "InvalidStateError",
runWithUserGesture( () => { device.requestSession({ exclusive: true })
device.requestSession({ exclusive: true }).then( (session) => { ).then( () => {
}, (err) => { // End the exclusive session and try again. Now the exclusive
t.step( () => { // session creation should succeed.
assert_unreached("requestSession rejected second exclusive session"); return session.end().then( () => new Promise((resolve) => {
runWithUserGesture( () => {
resolve(device.requestSession({ exclusive: true }));
}); });
}).then( () => { }));
t.done(); }));
});
});
});
}); });
}); })));
}, (err) => {
t.step( () => {
assert_unreached("requestSession rejected first exclusive session");
});
}).then( () => {
t.done();
});
return;
});
}, (err) => {
t.step( () => {
assert_unreached("getDevices rejected");
}); });
}); }));
}, [fakeDisplays["Pixel"]], }, "requestSession prevents creation of multiple simultaneous exclusive sessions");
"requestSession prevents creation of multiple simultaneous exclusive sessions");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script>
let fakeDisplays = fakeVRDisplays();
vr_test( (t) => {
return navigator.xr.requestDevice().then( (device) => {
runWithUserGesture( () => {
device.requestSession({ exclusive: true }).then( (session) => {
promise_test( function() {
return promise_rejects(this, new TypeError(),
session.requestFrameOfReference("foo"));
}, "requestFrameOfReference rejected for unknown requested type.");
return Promise.all([ <script>
session.requestFrameOfReference("headModel").then( (frameOfRef) => { let fakeDevices = fakeXRDevices();
t.step( () => {
assert_true(frameOfRef instanceof XRCoordinateSystem);
assert_true(frameOfRef instanceof XRFrameOfReference);
}, "'headModel' Frame of Reference is the correct type.");
}, (err) => {
t.step( () => {
assert_unreached("requestFrameOfReference 'headModel' rejected");
});
}),
session.requestFrameOfReference("eyeLevel").then( (frameOfRef) => {
t.step( () => {
assert_true(frameOfRef instanceof XRCoordinateSystem);
assert_true(frameOfRef instanceof XRFrameOfReference);
}, "'eyeLevel' Frame of Reference is the correct type.");
}, (err) => {
t.step( () => {
assert_unreached("requestFrameOfReference 'eyeLevel' rejected");
});
}),
session.requestFrameOfReference("stage").then( (frameOfRef) => {
t.step( () => {
assert_true(frameOfRef instanceof XRCoordinateSystem);
assert_true(frameOfRef instanceof XRFrameOfReference);
}, "'stage' Frame of Reference is the correct type.");
}, (err) => {
t.step( () => {
assert_unreached("requestFrameOfReference 'stage' rejected");
});
})
]);
}, (err) => { xr_session_promise_test( (session, t) => {
t.step( () => { return promise_rejects(t, new TypeError(), session.requestFrameOfReference("foo"))
assert_unreached("requestSession rejected"); .then(() => Promise.all([
}); session.requestFrameOfReference("headModel").then( (frameOfRef) => {
}).then( () => { assert_true(frameOfRef instanceof XRCoordinateSystem,
t.done(); "headModel frameOfRef is not correct type.");
}); assert_true(frameOfRef instanceof XRFrameOfReference,
}); "headModel frameOfRef is not correct type.");
}, (err) => { }),
t.step( () => { session.requestFrameOfReference("eyeLevel").then( (frameOfRef) => {
assert_unreached("requestDevice rejected"); assert_true(frameOfRef instanceof XRCoordinateSystem,
}); "eyeLevel frameOfRef is not correct type.");
}); assert_true(frameOfRef instanceof XRFrameOfReference,
}, [fakeDisplays["Pixel"]], "eyeLevel frameOfRef is not correct type.");
}),
session.requestFrameOfReference("stage").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"stage frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"stage frameOfRef is not correct type.");
})
]));
}, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"requestFrameOfReference returns the expected objects"); "requestFrameOfReference returns the expected objects");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
let webglLayer = new XRWebGLLayer(session, gl); let webglLayer = new XRWebGLLayer(session, gl);
session.baseLayer = webglLayer; session.baseLayer = webglLayer;
session.requestFrameOfReference("eyeLevel").then((frameOfRef) => { return session.requestFrameOfReference("eyeLevel").then((frameOfRef) => new Promise((resolve) =>{
function onFrame(time, xrFrame) { function onFrame(time, xrFrame) {
t.step( () => { // Ensure that two views are provided.
// Ensure that two views are provided. assert_not_equals(xrFrame.views, null);
assert_not_equals(xrFrame.views, null); assert_equals(xrFrame.views.length, 2);
assert_equals(xrFrame.views.length, 2);
let leftView = xrFrame.views[0];
let leftView = xrFrame.views[0]; let rightView = xrFrame.views[1];
let rightView = xrFrame.views[1];
// Ensure that the views are the right type.
// Ensure that the views are the right type. assert_true(leftView instanceof XRView);
assert_true(leftView instanceof XRView); assert_true(rightView instanceof XRView);
assert_true(rightView instanceof XRView);
// Ensure that they have the expected eye enums.
// Ensure that they have the expected eye enums. assert_equals(leftView.eye, "left");
assert_equals(leftView.eye, "left"); assert_equals(rightView.eye, "right");
assert_equals(rightView.eye, "right");
// Ensure they have the expected projection matrices.
// Ensure they have the expected projection matrices. assert_not_equals(leftView.projectionMatrix, null);
assert_not_equals(leftView.projectionMatrix, null); assert_not_equals(rightView.projectionMatrix, null);
assert_not_equals(rightView.projectionMatrix, null);
let displayLeftEye = fakeDevices["FakeGooglePixelPhone"].leftEye;
let displayLeftEye = fakeDisplays["Pixel"].leftEye; let displayRightEye = fakeDevices["FakeGooglePixelPhone"].rightEye;
let displayRightEye = fakeDisplays["Pixel"].rightEye;
let expectedLeftProjection = perspectiveFromFieldOfView(
let expectedLeftProjection = perspectiveFromFieldOfView( displayLeftEye.fieldOfView, session.depthNear, session.depthFar);
displayLeftEye.fieldOfView, session.depthNear, session.depthFar); let expectedRightProjection = perspectiveFromFieldOfView(
let expectedRightProjection = perspectiveFromFieldOfView( displayRightEye.fieldOfView, session.depthNear, session.depthFar);
displayRightEye.fieldOfView, session.depthNear, session.depthFar);
assert_matrices_approx_equal(leftView.projectionMatrix, expectedLeftProjection);
assert_matrices_approx_equal(leftView.projectionMatrix, expectedLeftProjection); assert_matrices_approx_equal(rightView.projectionMatrix, expectedRightProjection);
assert_matrices_approx_equal(rightView.projectionMatrix, expectedRightProjection);
}, "XRView attributes match the expected values"); // Finished test.
t.done(); resolve();
} }
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
}); }));
}, fakeDisplays["Pixel"], { exclusive: true }, }, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRPresentationFrame contains the expected views"); "XRPresentationFrame contains the expected views");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
let displayLeftEye = fakeDisplays["Pixel"].leftEye; let displayLeftEye = fakeDevices["FakeGooglePixelPhone"].leftEye;
let displayRightEye = fakeDisplays["Pixel"].rightEye; let displayRightEye = fakeDevices["FakeGooglePixelPhone"].rightEye;
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl); session.baseLayer = new XRWebGLLayer(session, gl);
session.requestFrameOfReference("eyeLevel").then((frameOfRef) => { return session.requestFrameOfReference("eyeLevel")
let counter = 0; .then((frameOfRef) => new Promise((resolve) =>{
let counter = 0;
function onFrame(time, xrFrame) { function onFrame(time, xrFrame) {
let leftView = xrFrame.views[0]; let leftView = xrFrame.views[0];
let rightView = xrFrame.views[1]; let rightView = xrFrame.views[1];
if (counter == 0) { if (counter == 0) {
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
t.step( () => {
let expectedLeftProjection = perspectiveFromFieldOfView( let expectedLeftProjection = perspectiveFromFieldOfView(
displayLeftEye.fieldOfView, session.depthNear, session.depthFar); displayLeftEye.fieldOfView, session.depthNear, session.depthFar);
let expectedRightProjection = perspectiveFromFieldOfView( let expectedRightProjection = perspectiveFromFieldOfView(
...@@ -45,9 +45,7 @@ xr_session_test( (t, session, mockService) => { ...@@ -45,9 +45,7 @@ xr_session_test( (t, session, mockService) => {
// account the new session depth values this frame. // account the new session depth values this frame.
assert_matrices_approx_equal(leftView.projectionMatrix, expectedLeftProjection); assert_matrices_approx_equal(leftView.projectionMatrix, expectedLeftProjection);
assert_matrices_approx_equal(rightView.projectionMatrix, expectedRightProjection); assert_matrices_approx_equal(rightView.projectionMatrix, expectedRightProjection);
}, "Projection matrices do not update within the same frame"); } else {
} else {
t.step( () => {
// New depth values should be retained between frames. // New depth values should be retained between frames.
assert_equals(session.depthNear, 1.0); assert_equals(session.depthNear, 1.0);
assert_equals(session.depthFar, 100.0); assert_equals(session.depthFar, 100.0);
...@@ -60,15 +58,14 @@ xr_session_test( (t, session, mockService) => { ...@@ -60,15 +58,14 @@ xr_session_test( (t, session, mockService) => {
// Projection matricies should now reflect the new depth values // Projection matricies should now reflect the new depth values
assert_matrices_approx_equal(leftView.projectionMatrix, expectedLeftProjection); assert_matrices_approx_equal(leftView.projectionMatrix, expectedLeftProjection);
assert_matrices_approx_equal(rightView.projectionMatrix, expectedRightProjection); assert_matrices_approx_equal(rightView.projectionMatrix, expectedRightProjection);
}, "Projection matrices do update on subsequent frames"); resolve();
t.done(); }
counter++;
} }
counter++;
}
session.requestAnimationFrame(onFrame); session.requestAnimationFrame(onFrame);
}); }));
}, fakeDisplays["Pixel"], { exclusive: true }, }, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRView projection matrices update near and far depths on the next frame"); "XRView projection matrices update near and far depths on the next frame");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
let webglLayer = new XRWebGLLayer(session, gl); let webglLayer = new XRWebGLLayer(session, gl);
session.baseLayer = webglLayer; session.baseLayer = webglLayer;
session.requestFrameOfReference("eyeLevel").then((frameOfRef) => { return session.requestFrameOfReference("eyeLevel")
function onFrame(time, xrFrame) { .then((frameOfRef) => new Promise((resolve) =>{
let leftView = xrFrame.views[0]; function onFrame(time, xrFrame) {
let rightView = xrFrame.views[1]; let leftView = xrFrame.views[0];
let rightView = xrFrame.views[1];
let leftViewport = leftView.getViewport(webglLayer); let leftViewport = leftView.getViewport(webglLayer);
let rightViewport = rightView.getViewport(webglLayer); let rightViewport = rightView.getViewport(webglLayer);
// Ensure the views report the expected viewports into the WebGL layer. // Ensure the views report the expected viewports into the WebGL layer.
t.step( () => {
assert_true(leftViewport instanceof XRViewport); assert_true(leftViewport instanceof XRViewport);
assert_true(rightViewport instanceof XRViewport); assert_true(rightViewport instanceof XRViewport);
assert_not_equals(leftViewport, null); assert_not_equals(leftViewport, null);
assert_not_equals(rightViewport, null); assert_not_equals(rightViewport, null);
}, "Viewports are of the right type and not null");
// Exact viewport values don't matter, but they must pass several tests: // Exact viewport values don't matter, but they must pass several tests:
t.step( () => { // Viewports have non-zero widths and heights.
assert_greater_than(leftViewport.width, 0); assert_greater_than(leftViewport.width, 0);
assert_greater_than(leftViewport.height, 0); assert_greater_than(leftViewport.height, 0);
assert_greater_than(rightViewport.width, 0); assert_greater_than(rightViewport.width, 0);
assert_greater_than(rightViewport.height, 0); assert_greater_than(rightViewport.height, 0);
}, "Viewports have non-zero widths and heights");
t.step( () => { // Viewports are located within the framebuffer.
assert_greater_than_equal(leftViewport.x, 0); assert_greater_than_equal(leftViewport.x, 0);
assert_greater_than_equal(leftViewport.y, 0); assert_greater_than_equal(leftViewport.y, 0);
assert_greater_than_equal(leftViewport.x, 0); assert_greater_than_equal(leftViewport.x, 0);
assert_greater_than_equal(leftViewport.y, 0); assert_greater_than_equal(leftViewport.y, 0);
assert_less_than_equal(leftViewport.x + leftViewport.width, webglLayer.framebufferWidth); assert_less_than_equal(
assert_less_than_equal(leftViewport.y + leftViewport.height, webglLayer.framebufferHeight); leftViewport.x + leftViewport.width, webglLayer.framebufferWidth);
assert_less_than_equal(rightViewport.x + rightViewport.width, webglLayer.framebufferWidth); assert_less_than_equal(
assert_less_than_equal(rightViewport.y + rightViewport.height, webglLayer.framebufferHeight); leftViewport.y + leftViewport.height, webglLayer.framebufferHeight);
}, "Viewports are located within the framebuffer"); assert_less_than_equal(
rightViewport.x + rightViewport.width, webglLayer.framebufferWidth);
assert_less_than_equal(
rightViewport.y + rightViewport.height, webglLayer.framebufferHeight);
t.step( () => {
// Assumes that the left viewport will always be physically to the left // Assumes that the left viewport will always be physically to the left
// of the right viewport. // of the right viewport.
assert_less_than_equal(leftViewport.x + leftViewport.width, rightViewport.x); assert_less_than_equal(leftViewport.x + leftViewport.width, rightViewport.x);
}, "XRViewports do not overlap");
t.done();
}
session.requestAnimationFrame(onFrame); resolve();
}); }
}, fakeDisplays["Pixel"], { exclusive: true }, session.requestAnimationFrame(onFrame);
}));
}, fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"XRViewport attributes are valid"); "XRViewport attributes are valid");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => new Promise((resolve, reject) => {
t.step( () => { try {
try { let webglLayerGood = new XRWebGLLayer(session, gl);
let webglLayerGood = new XRWebGLLayer(session, gl); } catch (err) {
} catch (err) { reject("XRWebGLLayer should not fail with valid arguments");
assert_unreached("XRWebGLLayer should not fail with valid arguments"); }
}
});
let lose_context_ext = gl.getExtension('WEBGL_lose_context'); let lose_context_ext = gl.getExtension('WEBGL_lose_context');
webglCanvas.addEventListener('webglcontextlost', (ev) => { webglCanvas.addEventListener('webglcontextlost', (ev) => {
ev.preventDefault(); ev.preventDefault();
t.step( () => { try {
let webglLayerBadContext = new XRWebGLLayer(session, gl);
reject("XRWebGLLayer should fail when created with a lost context");
} catch (err) {
assert_equals(err.name, 'InvalidStateError');
setTimeout(() => { lose_context_ext.restoreContext(); }, 100);
}
});
webglCanvas.addEventListener('webglcontextrestored', (ev) => {
resolve(session.end().then(() => {
try { try {
let webglLayerBadContext = new XRWebGLLayer(session, gl); let webglLayerBadSession = new XRWebGLLayer(session, gl);
assert_unreached("XRWebGLLayer should fail when created with a lost context"); assert_unreached("XRWebGLLayer should fail when created with an ended session");
t.done();
} catch (err) { } catch (err) {
assert_equals(err.name, 'InvalidStateError'); assert_equals(err.name, 'InvalidStateError');
setTimeout(() => { lose_context_ext.restoreContext(); }, 100);
} }
}); }));
});
webglCanvas.addEventListener('webglcontextrestored', (ev) => {
session.end().then(() => {
t.step( () => {
try {
let webglLayerBadSession = new XRWebGLLayer(session, gl);
assert_unreached("XRWebGLLayer should fail when created with an ended session");
} catch (err) {
assert_equals(err.name, 'InvalidStateError');
}
t.done();
});
});
}); });
lose_context_ext.loseContext(); lose_context_ext.loseContext();
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"Ensure a WebGL layer's framebuffer can only be drawn to inside a XR frame"); "Ensure a WebGL layer's framebuffer can only be drawn to inside a XR frame");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => new Promise((resolve, reject) => {
// Session must have a baseLayer or else frame requests will be ignored. // Session must have a baseLayer or else frame requests will be ignored.
let webglLayer = new XRWebGLLayer(session, gl); let webglLayer = new XRWebGLLayer(session, gl);
session.baseLayer = webglLayer; session.baseLayer = webglLayer;
let mockDisplay = mockService.mockVRDisplays_[0];
function onSkipFrame(time, xrFrame) { function onSkipFrame(time, xrFrame) {
// No GL commands issued // No GL commands issued.
session.requestAnimationFrame(onDrawToCanvas); session.requestAnimationFrame(onDrawToCanvas);
} }
function onDrawToCanvas(time, xrFrame) { function onDrawToCanvas(time, xrFrame) {
// Ensure the previous step did not submit a frame // Ensure the previous step did not submit a frame.
t.step( () => { assert_equals(getSubmitFrameCount(), 0);
assert_equals(mockDisplay.getSubmitFrameCount(), 0);
}, "Expecting no frame was submitted during onSkipFrame"); // Clear the canvas.
// Clear the canvas
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
session.requestAnimationFrame(onDrawToFramebuffer); session.requestAnimationFrame(onDrawToFramebuffer);
} }
function onDrawToFramebuffer(time, xrFrame) { function onDrawToFramebuffer(time, xrFrame) {
// Ensure the previous step did not submit a frame // Ensure the previous step did not submit a frame.
t.step( () => { assert_equals(getSubmitFrameCount(), 0);
assert_equals(mockDisplay.getSubmitFrameCount(), 0);
}, "Expecting no frame was submitted during onDrawToCanvas"); // Clear the VRWebGLLayer framebuffer.
// Clear the VRWebGLLayer framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, webglLayer.framebuffer); gl.bindFramebuffer(gl.FRAMEBUFFER, webglLayer.framebuffer);
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
// After the function returns ensure the frame was submitted. // After the function returns ensure the frame was submitted.
window.setTimeout(() => { window.setTimeout(() => {
t.step( () => { assert_equals(getSubmitFrameCount(), 1);
assert_equals(mockDisplay.getSubmitFrameCount(), 1); // Finished test.
}, "Expecting one frame was submitted during onDrawToFramebuffer"); resolve();
t.done();
}, 100); }, 100);
} }
session.requestAnimationFrame(onSkipFrame); session.requestAnimationFrame(onSkipFrame);
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"A frame should be submitted if the base layer was written to during requestAnimationFrame"); "A frame should be submitted if the base layer was written to during requestAnimationFrame");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
// Very simple program setup with no error checking. // Very simple program setup with no error checking.
function setupProgram(gl, vertexSrc, fragmentSrc) { function setupProgram(gl, vertexSrc, fragmentSrc) {
...@@ -31,7 +31,7 @@ function setupProgram(gl, vertexSrc, fragmentSrc) { ...@@ -31,7 +31,7 @@ function setupProgram(gl, vertexSrc, fragmentSrc) {
return program; return program;
} }
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => new Promise((resolve, reject) => {
// Setup simple WebGL geometry to draw with. // Setup simple WebGL geometry to draw with.
let program = setupProgram(gl, let program = setupProgram(gl,
"attribute vec4 vPosition; void main() { gl_Position = vPosition; }", "attribute vec4 vPosition; void main() { gl_Position = vPosition; }",
...@@ -40,7 +40,10 @@ xr_session_test( (t, session, mockService) => { ...@@ -40,7 +40,10 @@ xr_session_test( (t, session, mockService) => {
let vertexObject = gl.createBuffer(); let vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW); gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]),
gl.STATIC_DRAW);
gl.enableVertexAttribArray(0); gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
...@@ -54,44 +57,36 @@ xr_session_test( (t, session, mockService) => { ...@@ -54,44 +57,36 @@ xr_session_test( (t, session, mockService) => {
let xrFramebuffer = webglLayer.framebuffer; let xrFramebuffer = webglLayer.framebuffer;
function runDrawTests(t, expectedError) { function runDrawTests(expectedError) {
t.step( () => { // Make sure we're starting with a clean error slate.
// Make sure we're starting with a clean error slate. assert_equals(gl.getError(), gl.NO_ERROR);
assert_equals(gl.getError(), gl.NO_ERROR);
gl.bindFramebuffer(gl.FRAMEBUFFER, xrFramebuffer); gl.bindFramebuffer(gl.FRAMEBUFFER, xrFramebuffer);
assert_equals(gl.getError(), gl.NO_ERROR); assert_equals(gl.getError(), gl.NO_ERROR);
}, "Framebuffer must be bindable");
t.step( () => { gl.clear(gl.COLOR_BUFFER_BIT);
gl.clear(gl.COLOR_BUFFER_BIT); assert_equals(gl.getError(), gl[expectedError]);
assert_equals(gl.getError(), gl[expectedError]);
gl.clear(gl.DEPTH_BUFFER_BIT); gl.clear(gl.DEPTH_BUFFER_BIT);
assert_equals(gl.getError(), gl[expectedError]); assert_equals(gl.getError(), gl[expectedError]);
}, `Test clearing the framebuffer, expect ${expectedError}`);
t.step( () => { gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.drawArrays(gl.TRIANGLES, 0, 3); assert_equals(gl.getError(), gl[expectedError]);
assert_equals(gl.getError(), gl[expectedError]);
}, `Test drawArrays, expect ${expectedError}`);
t.step( () => { gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0);
gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0); assert_equals(gl.getError(), gl[expectedError]);
assert_equals(gl.getError(), gl[expectedError]);
}, `Test drawElements, expect ${expectedError}`);
} }
// Drawing operations outside of a XR frame should fail. // Drawing operations outside of a XR frame should fail.
runDrawTests(t, "INVALID_FRAMEBUFFER_OPERATION"); runDrawTests("INVALID_FRAMEBUFFER_OPERATION");
// Drawing operations within a XR frame should succeed. // Drawing operations within a XR frame should succeed.
session.requestAnimationFrame((time, xrFrame) => { session.requestAnimationFrame((time, xrFrame) => {
runDrawTests(t, "NO_ERROR"); runDrawTests("NO_ERROR");
t.done(); resolve();
}); });
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"Ensure a WebGL layer's framebuffer can only be drawn to inside a XR frame"); "Ensure a WebGL layer's framebuffer can only be drawn to inside a XR frame");
</script> </script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../vr/resources/fake-vr-displays.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/vr_service.mojom.js"></script> <script src="file:///gen/device/vr/vr_service.mojom.js"></script>
<script src="../vr/resources/mock-vr-service.js"></script> <script src="../xr/resources/xr-device-mocking.js"></script>
<script src="../vr/resources/test-constants.js"></script> <script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas> <canvas id="webgl-canvas"></canvas>
<script src="../vr/resources/presentation-setup.js"></script>
<script> <script>
let fakeDisplays = fakeVRDisplays(); let fakeDevices = fakeXRDevices();
xr_session_test( (t, session, mockService) => { xr_session_promise_test( (session) => new Promise((resolve, reject) => {
// Session must have a baseLayer or frame requests will be ignored. // Session must have a baseLayer or frame requests will be ignored.
let webglLayer = new XRWebGLLayer(session, gl); let webglLayer = new XRWebGLLayer(session, gl);
session.baseLayer = webglLayer; session.baseLayer = webglLayer;
let xrFramebuffer = webglLayer.framebuffer; let xrFramebuffer = webglLayer.framebuffer;
t.step( () => { // Make sure we're starting with a clean error slate.
// Make sure we're starting with a clean error slate. assert_equals(gl.getError(), gl.NO_ERROR);
assert_equals(gl.getError(), gl.NO_ERROR);
assert_not_equals(xrFramebuffer, null);
assert_not_equals(xrFramebuffer, null); assert_greater_than(webglLayer.framebufferWidth, 0);
assert_greater_than(webglLayer.framebufferWidth, 0); assert_greater_than(webglLayer.framebufferHeight, 0);
assert_greater_than(webglLayer.framebufferHeight, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, xrFramebuffer);
gl.bindFramebuffer(gl.FRAMEBUFFER, xrFramebuffer); assert_equals(gl.getError(), gl.NO_ERROR);
assert_equals(gl.getError(), gl.NO_ERROR);
}, "Framebuffer must be non-null, non-zero size, bindable."); gl.deleteFramebuffer(xrFramebuffer);
assert_equals(gl.getError(), gl.INVALID_OPERATION);
t.step( () => {
gl.deleteFramebuffer(xrFramebuffer); // Make sure the framebuffer is still bound after failed attempt to delete.
assert_equals(gl.getError(), gl.INVALID_OPERATION); let boundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
assert_equals(xrFramebuffer, boundFramebuffer);
// Make sure the framebuffer is still bound after failed attempt to delete. assert_equals(gl.getError(), gl.NO_ERROR);
let boundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
assert_equals(xrFramebuffer, boundFramebuffer); // Ensure the framebuffer attachment properties cannot be inspected.
assert_equals(gl.getError(), gl.NO_ERROR); let attachments = [
}, "Ensure the framebuffer cannot be deleted"); gl.COLOR_ATTACHMENT0,
gl.DEPTH_ATTACHMENT,
t.step( () => { gl.STENCIL_ATTACHMENT,
let attachments = [ ];
gl.COLOR_ATTACHMENT0,
gl.DEPTH_ATTACHMENT, let parameters = [
gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
]; gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
let parameters = [ gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ];
gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, for (let attachment of attachments) {
gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, for (let parameter of parameters) {
]; let value = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment, parameter);
assert_equals(value, null);
for (let attachment of attachments) { assert_equals(gl.getError(), gl.INVALID_OPERATION);
for (let parameter of parameters) {
let value = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment, parameter);
assert_equals(value, null);
assert_equals(gl.getError(), gl.INVALID_OPERATION);
}
} }
}, "Ensure the framebuffer attachment properties cannot be inspected"); }
let width = 64; let width = 64;
let height = 64; let height = 64;
t.step( () => { // Ensure the framebuffer texture 2D attachmentments cannot be changed.
var texture = gl.createTexture(); var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture); gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
assert_equals(gl.getError(), gl.INVALID_OPERATION); assert_equals(gl.getError(), gl.INVALID_OPERATION);
}, "Ensure the framebuffer texture 2D attachmentments cannot be changed");
// Ensure the framebuffer renderbuffer attachmentments cannot be changed.
t.step( () => { let renderbuffer = gl.createRenderbuffer();
let renderbuffer = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); gl.framebufferRenderbuffer(
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); gl.FRAMEBUFFER,
assert_equals(gl.getError(), gl.INVALID_OPERATION); gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER,
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); renderbuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); assert_equals(gl.getError(), gl.INVALID_OPERATION);
assert_equals(gl.getError(), gl.INVALID_OPERATION);
}, "Ensure the framebuffer renderbuffer attachmentments cannot be changed"); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
t.step( () => { assert_equals(gl.getError(), gl.INVALID_OPERATION);
assert_equals(gl.checkFramebufferStatus(gl.FRAMEBUFFER), gl.FRAMEBUFFER_UNSUPPORTED);
}, "Framebuffer status must be unsupported outside of a XR frame callback"); // Framebuffer status must be unsupported outside of a XR frame callback.
assert_equals(gl.checkFramebufferStatus(gl.FRAMEBUFFER), gl.FRAMEBUFFER_UNSUPPORTED);
session.requestAnimationFrame((time, xrFrame) => { session.requestAnimationFrame((time, xrFrame) => {
t.step( () => { // Framebuffer status must be complete inside of a XR frame callback.
assert_equals(gl.checkFramebufferStatus(gl.FRAMEBUFFER), gl.FRAMEBUFFER_COMPLETE); assert_equals(gl.checkFramebufferStatus(gl.FRAMEBUFFER), gl.FRAMEBUFFER_COMPLETE);
}, "Framebuffer status must be complete inside of a XR frame callback"); // Finished.
resolve();
t.done();
}); });
}, fakeDisplays["Pixel"], { exclusive: true }, }), fakeDevices["FakeGooglePixelPhone"], { exclusive: true },
"Ensure that the framebuffer given by the WebGL layer is opaque"); "Ensure that the framebuffer given by the WebGL layer is opaque");
</script> </script>
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