| <!DOCTYPE html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/webxr_util.js"></script> |
| <script src="resources/webxr_test_constants.js"></script> |
| <canvas /> |
| |
| <script> |
| const TEN_SECONDS = 10000; // 10k ms in ten seconds |
| const ONE_MINUTE = 60000; // 60k ms in one minute |
| |
| let immersiveTestName = "XRFrame getViewerPose updates on the next frame for immersive"; |
| let nonImmersiveTestName = "XRFrame getViewerPose updates on the next frame for non-immersive"; |
| |
| let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE; |
| |
| let testFunction = function(session, fakeDeviceController, t) { |
| return session.requestReferenceSpace('viewer') |
| .then((referenceSpace) => new Promise((resolve, reject) => { |
| let counter = 0; |
| let windowFrameTime = 0; |
| let frameTime = 0; |
| let lastFrameTime = 0; |
| |
| let firstFrame = true; |
| |
| function onFrameFirst(time, xrFrame) { |
| lastFrameTime = frameTime; |
| frameTime = time; |
| let now = performance.now(); |
| |
| t.step( () => { |
| if(firstFrame) { |
| // This callback must be the first one called. |
| assert_equals(counter, 0); |
| } else { |
| // If it's a second animation frame, the timestamp must be greater |
| // than the timestamp on a previous frame. |
| assert_greater_than(frameTime, lastFrameTime); |
| // ... but not grater than 10 seconds. |
| assert_approx_equals(frameTime, lastFrameTime, TEN_SECONDS); |
| } |
| |
| // There's going to be some disparity between performance.now() and |
| // the timestamp passed into the callback, but it shouldn't be huge. |
| // If they're more than ten seconds apart something has gone horribly |
| // wrong. |
| assert_approx_equals(frameTime, now, TEN_SECONDS); |
| }); |
| |
| if (firstFrame) { |
| // We also want this method to run for the second animation frame. |
| session.requestAnimationFrame(onFrameFirst); |
| } else { |
| resolve(); |
| } |
| |
| firstFrame = false; |
| counter++; |
| } |
| |
| function onFrameSubsequent(time, xrFrame) { |
| t.step( () => { |
| // The timestamp passed to this callback should be exactly equal to |
| // the one passed to the first callback in this set. |
| assert_equals(time, frameTime); |
| }); |
| |
| counter++; |
| } |
| |
| function onFrameLast(time, xrFrame) { |
| t.step( () => { |
| // Make sure all the previous callbacks fired as expected. |
| assert_equals(counter, 11); |
| }); |
| } |
| |
| session.requestAnimationFrame(onFrameFirst); |
| // Queue up several callbacks |
| for (let i = 0; i < 10; ++i) { |
| session.requestAnimationFrame(onFrameSubsequent); |
| } |
| session.requestAnimationFrame(onFrameLast); |
| |
| })); |
| }; |
| |
| xr_session_promise_test( |
| immersiveTestName, testFunction, fakeDeviceInitParams, 'immersive-vr'); |
| xr_session_promise_test( |
| nonImmersiveTestName, testFunction, fakeDeviceInitParams, 'inline'); |
| |
| </script> |