diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/webxr/xr_viewport_scale.https.html | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/webxr/xr_viewport_scale.https.html')
-rw-r--r-- | testing/web-platform/tests/webxr/xr_viewport_scale.https.html | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webxr/xr_viewport_scale.https.html b/testing/web-platform/tests/webxr/xr_viewport_scale.https.html new file mode 100644 index 0000000000..a3e3a4e5bd --- /dev/null +++ b/testing/web-platform/tests/webxr/xr_viewport_scale.https.html @@ -0,0 +1,231 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/webxr_test_constants.js"></script> +<script src="resources/webxr_util.js"></script> +<script src="resources/webxr_test_asserts.js"></script> + +<script> + +let fakeDeviceInitParams = TRACKED_IMMERSIVE_DEVICE; + +let isValidViewport = function(viewport) { + // Ensure the returned object is an XRViewport object + assert_not_equals(viewport, null); + assert_true(viewport instanceof XRViewport); + + // Ensure the viewport dimensions are valid + assert_greater_than_equal(viewport.x, 0); + assert_greater_than_equal(viewport.y, 0); + assert_greater_than_equal(viewport.width, 1); + assert_greater_than_equal(viewport.height, 1); +}; + +let containsViewport = function(outer, inner) { + assert_less_than_equal(inner.x, outer.x); + assert_less_than_equal(inner.y, outer.y); + assert_less_than_equal(inner.x + inner.width, outer.x + outer.width); + assert_less_than_equal(inner.y + inner.height, outer.y + outer.height); +}; + +let isSameViewport = function(a, b) { + return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +}; + +let assertSameViewport = function(a, b) { + assert_equals(a.x, b.x, "viewport x should match"); + assert_equals(a.y, b.y, "viewport y should match"); + assert_equals(a.width, b.width, "viewport width should match"); + assert_equals(a.height, b.height, "viewport height should match"); +}; + +let testFunction = function(name, firstScale, nextFrame, session, fakeDeviceController, t) { + return session.requestReferenceSpace('viewer') + .then((space) => new Promise((resolve) => { + function onFrame(time, xrFrame1) { + let debug = xr_debug.bind(this, name); + debug('first frame'); + let layer = xrFrame1.session.renderState.baseLayer; + + let fullViewports = []; + + let views1 = xrFrame1.getViewerPose(space).views; + + for (view of views1) { + let viewport1a = layer.getViewport(view); + t.step(() => isValidViewport(viewport1a)); + fullViewports.push(viewport1a); + } + + // Now request a changed viewport scale. This must not change the + // viewports within this frame since they were already queried. + // If the UA supports viewport scaling, the change applies on the + // next frame. If it doesn't support viewport scaling, this call + // has no effect. + for (view of views1) { + view.requestViewportScale(firstScale); + } + + t.step(() => { + for (let i = 0; i < views1.length; ++i) { + let viewport1b = layer.getViewport(views1[i]); + assertSameViewport(viewport1b, fullViewports[i]); + } + }); + + if (nextFrame) { + session.requestAnimationFrame((time, xrFrame2) => + nextFrame(name, t, session, space, layer, fullViewports, xrFrame2, resolve)); + } else { + // test is done + resolve(); + } + } + + session.requestAnimationFrame(onFrame); + })); +}; + +let testViewportValid = function(name, t, session, space, layer, fullViewports, xrFrame, resolve) { + let debug = xr_debug.bind(this, name); + debug('second frame'); + let views = xrFrame.getViewerPose(space).views; + for (let i = 0; i < views.length; ++i) { + let viewport = layer.getViewport(views[i]); + t.step(() => isValidViewport(viewport)); + t.step(() => containsViewport(fullViewports[i], viewport)); + } + resolve(); +}; + +let testScaleAppliedNextFrame = function(name, t, session, space, layer, fullViewports, xrFrame, resolve) { + let debug = xr_debug.bind(this, name); + debug('second frame'); + let supportsScaling = false; + let views = xrFrame.getViewerPose(space).views; + for (let i = 0; i < views.length; ++i) { + let viewport = layer.getViewport(views[i]); + t.step(() => isValidViewport(viewport)); + t.step(() => containsViewport(fullViewports[i], viewport)); + if (!isSameViewport(fullViewports[i], viewport)) { + supportsScaling = true; + } + } + debug("supportsScaling=" + supportsScaling); + t.step(() => { + assert_implements_optional(supportsScaling, "requestViewportScale has no effect"); + }); + resolve(); +}; + +let testScaleSameFrame = function(name, t, session, space, layer, fullViewports, xrFrame, resolve) { + let debug = xr_debug.bind(this, name); + debug('second frame'); + let supportsScaling = false; + let views = xrFrame.getViewerPose(space).views; + let viewports2 = []; + for (let i = 0; i < views.length; ++i) { + let viewport2 = layer.getViewport(views[i]); + viewports2.push(viewport2); + if (!isSameViewport(fullViewports[i], viewport2)) { + supportsScaling = true; + } + } + debug("supportsScaling=" + supportsScaling); + if (!supportsScaling) { + // End the test early. + t.step(() => { + assert_implements_optional(false, "requestViewportScale has no effect"); + resolve(); + }); + } + + session.requestAnimationFrame((time, xrFrame3) => { + let views3 = xrFrame3.getViewerPose(space).views; + // Apply a new viewport scale before requesting viewports, + // this should take effect on the same frame. + for (view of views3) { + view.requestViewportScale(0.75); + } + for (let i = 0; i < views3.length; ++i) { + let viewport3 = layer.getViewport(views3[i]); + t.step(() => isValidViewport(viewport3)); + t.step(() => containsViewport(fullViewports[i], viewport3)); + t.step(() => containsViewport(viewport3, viewports2[i])); + t.step(() => { + // We don't know the exact expected size, but it should be in + // between the half-size and full-size viewports. + assert_false(isSameViewport(viewports2[i], viewport3)); + assert_false(isSameViewport(fullViewports[i], viewport3)); + }); + } + resolve(); + }); +}; + +let testRecommendedScale = function(name, t, session, space, layer, fullViewports, xrFrame, resolve) { + let debug = xr_debug.bind(this, name); + debug('second frame'); + let views = xrFrame.getViewerPose(space).views; + let haveRecommendedScale = false; + for (view of views) { + let recommended = view.recommendedViewportScale; + view.requestViewportScale(recommended); + if (recommended !== null && recommended !== undefined) { + haveRecommendedScale = true; + t.step(() => { + assert_greater_than(recommended, 0.0, "recommended scale invalid"); + assert_less_than_equal(recommended, 1.0, "recommended scale invalid"); + }); + } + } + t.step(() => { + assert_implements_optional(haveRecommendedScale, "recommendedViewportScale not provided"); + }); + for (let i = 0; i < views.length; ++i) { + let viewport = layer.getViewport(views[i]); + t.step(() => isValidViewport(viewport)); + t.step(() => containsViewport(fullViewports[i], viewport)); + } + resolve(); +}; + +for (let mode of ['inline', 'immersive-vr']) { + xr_session_promise_test( + "requestViewportScale valid viewport for " + mode + " session", + testFunction.bind(this, "valid viewport (0.5) " + mode, 0.5, testViewportValid), + fakeDeviceInitParams, + mode); + xr_session_promise_test( + "requestViewportScale valid viewport w/ null scale for " + mode + " session", + testFunction.bind(this, "valid viewport (null) " + mode, null, testViewportValid), + fakeDeviceInitParams, + mode); + xr_session_promise_test( + "requestViewportScale valid viewport w/ undefined scale for " + mode + " session", + testFunction.bind(this, "valid viewport (undefined) " + mode, null, testViewportValid), + fakeDeviceInitParams, + mode); + xr_session_promise_test( + "requestViewportScale valid viewport w/ very small scale for " + mode + " session", + testFunction.bind(this, "valid viewport (tiny) " + mode, 1e-6, testViewportValid), + fakeDeviceInitParams, + mode); + xr_session_promise_test( + "requestViewportScale applied next frame for " + mode + " session", + testFunction.bind(this, "scale applied next frame " + mode, 0.5, testScaleAppliedNextFrame), + fakeDeviceInitParams, + mode); + xr_session_promise_test( + "requestViewportScale same frame for " + mode + " session", + testFunction.bind(this, "same frame " + mode, 0.5, testScaleSameFrame), + fakeDeviceInitParams, + mode); + xr_session_promise_test( + "recommendedViewportScale for " + mode + " session", + testFunction.bind(this, "recommendedViewportScale " + mode, 0.5, testRecommendedScale), + fakeDeviceInitParams, + mode); +} + +</script> |