1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
<!doctype html>
<title>Tests for errors with invalid XRLayerInit parameters.</title>
<link rel="help" href="https://immersive-web.github.io/layers/#dom-xrwebglbinding-createquadlayer">
<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>
<script src="./xr_layer_promise_test.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
function testCommonXRLayerInitErrors(createLayerFn, valid_init, t, gl) {
const is_webgl2 = gl instanceof WebGL2RenderingContext;
return new Promise((resolve, reject) => {
const max_texture_size = gl.getParameter(gl.MAX_TEXTURE_SIZE);
if (!is_webgl2) {
// Check an exception on webgl2 color formats.
t.step(() => {
[
0x8058, // GL_RGBA8
0x8051, // GL_RGB8
0x8C41, // GL_SRGB8
0x8C43 // GL_SRGB8_ALPHA8
].forEach((colorFormat) => {
let invalid_color_format = Object.assign({}, valid_init, { colorFormat });
assert_throws_js(TypeError, () => createLayerFn(invalid_color_format), "colorFormat for webgl2 only");
});
});
}
t.step(() => {
// viewPixelWidth and viewPixelHeight must be greater than 0.
let invalid_pixel_width = Object.assign({}, valid_init, { viewPixelWidth: 0 });
assert_throws_js(TypeError, () => createLayerFn(invalid_pixel_width), "viewPixelWidth is 0");
});
t.step(() => {
let invalid_pixel_height = Object.assign({}, valid_init, { viewPixelHeight: 0 });
assert_throws_js(TypeError, () => createLayerFn(invalid_pixel_height), "viewPixelHeight is 0");
});
// viewPixelWidth and viewPixelHeight must not be too large.
t.step(() => {
let large_pixel_width = Object.assign({}, valid_init, { viewPixelWidth: max_texture_size + 1 });
assert_throws_js(TypeError, () => createLayerFn(large_pixel_width), "viewPixelWidth is too large");
});
t.step(() => {
let large_pixel_height = Object.assign({}, valid_init, { viewPixelHeight: max_texture_size + 1 });
assert_throws_js(TypeError, () => createLayerFn(large_pixel_height), "viewPixelHeight is too large");
});
});
};
function testXRLayerInitTextureArrayErrors(createLayerFn, valid_init, t, gl) {
const is_webgl2 = gl instanceof WebGL2RenderingContext;
return new Promise((resolve, reject) => {
let texture_array = Object.assign({}, valid_init, { textureType: 'texture-array', layout: 'stereo' });
if (is_webgl2) {
const layer = createLayerFn(texture_array);
// 'stereo' layout should be supported with 'texture-array'.
assert_equals(layer.layout, 'stereo', "layout is not expected");
} else {
// Check an exception on texture-array.
t.step(() => {
// texture-array is not supported for webgl.
assert_throws_js(TypeError, () => createLayerFn(texture_array), "texture-array for webgl2 only");
});
}
});
}
function testXRLayerInitTransformErrors(createLayerFn, valid_init, t) {
return new Promise((resolve, reject) => {
t.step(() => {
// Check an exception for invalid transform object.
let invalid_transform = Object.assign({}, valid_init, { transform: { x: 0, y: 0, z: 0 } });
assert_throws_js(TypeError, () => createLayerFn(invalid_transform), "Invalid transform object");
});
});
}
function testXRLayerInitLayoutErrors(createLayerFn, valid_init, t, is_cube) {
return new Promise((resolve, reject) => {
t.step(() => {
// 'default' is invalid for all layers.
const default_layout = Object.assign({}, valid_init, { layout: 'default' });
assert_throws_js(TypeError, () => createLayerFn(default_layout), "layout is 'default'");
const stereo_layout = Object.assign({}, valid_init, { layout: 'stereo' });
if (is_cube) {
// We don't support 'stereo' layout for cube layers.
assert_throws_js(TypeError, () => createLayerFn(stereo_layout), "layout is 'stereo'");
} else {
// It should end up as 'stereo-left-right' when 'texture-array' is not used.
const layer = createLayerFn(stereo_layout);
const layout = layer.layout;
assert_equals(layout, 'stereo-left-right', "layout is not expected");
}
resolve();
});
});
};
function testCompositionLayer(xrSession, deviceController, t, { gl, xrBinding, xrSpace }) {
const valid_init = {
space: xrSpace,
viewPixelWidth: 1024,
viewPixelHeight: 1024
};
const create_quad_layer = xrBinding.createQuadLayer.bind(xrBinding);
const create_cylinder_layer = xrBinding.createCylinderLayer.bind(xrBinding);
const create_equirect_layer = xrBinding.createEquirectLayer.bind(xrBinding);
const create_cube_layer = xrBinding.createCubeLayer.bind(xrBinding);
return Promise.resolve()
// Quad layer.
.then(testCommonXRLayerInitErrors(create_quad_layer, valid_init, t, gl))
.then(testXRLayerInitTextureArrayErrors(create_quad_layer, valid_init, t, gl))
.then(testXRLayerInitTransformErrors(create_quad_layer, valid_init, t))
.then(testXRLayerInitLayoutErrors(create_quad_layer, valid_init, t, false /*is_cube*/))
// Cylinder layer.
.then(testCommonXRLayerInitErrors(create_cylinder_layer, valid_init, t, gl))
.then(testXRLayerInitTextureArrayErrors(create_cylinder_layer, valid_init, t, gl))
.then(testXRLayerInitTransformErrors(create_cylinder_layer, valid_init, t))
.then(testXRLayerInitLayoutErrors(create_cylinder_layer, valid_init, t, false /*is_cube*/))
// Equirect layer.
.then(testCommonXRLayerInitErrors(create_equirect_layer, valid_init, t, gl))
.then(testXRLayerInitTextureArrayErrors(create_equirect_layer, valid_init, t, gl))
.then(testXRLayerInitTransformErrors(create_equirect_layer, valid_init, t))
.then(testXRLayerInitLayoutErrors(create_equirect_layer, valid_init, t, false /*is_cube*/))
// Cube layer.
.then(testCommonXRLayerInitErrors(create_cube_layer, valid_init, t, gl))
.then(testXRLayerInitLayoutErrors(create_cube_layer, valid_init, t, true /*is_cube*/));
}
// This method tests XRLayerInit parameters, which are common to the Quad,Cylinder and Equirect layers.
xr_layer_promise_test("Ensure XrWebGLBinding's create layer methods throw the appropriate errors.",
testCompositionLayer, TRACKED_IMMERSIVE_DEVICE, 'immersive-vr', { requiredFeatures: ['layers'] });
</script>
|