summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/extensions
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /dom/canvas/test/webgl-conf/checkout/conformance/extensions
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/extensions')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/00_test_list.txt6
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-clip-control.html185
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-depth-clamp.html168
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-disjoint-timer-query.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-polygon-offset-clamp.html172
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-sRGB.html34
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-rgtc.html8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-mirror-clamp-to-edge.html217
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/khr-parallel-shader-compile.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-video.html1
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-video.html1
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-blend-func-extended.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-polygon-mode.html185
14 files changed, 1147 insertions, 6 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/00_test_list.txt
index 9a72b67ef0..e121e90676 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/00_test_list.txt
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/00_test_list.txt
@@ -1,15 +1,19 @@
--min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays.html
--min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays-out-of-bounds.html
--min-version 1.0.3 --max-version 1.9.9 ext-blend-minmax.html
+--min-version 1.0.4 ext-clip-control.html
--min-version 1.0.4 ext-color-buffer-half-float.html
+--min-version 1.0.4 ext-depth-clamp.html
--min-version 1.0.4 ext-float-blend.html
--min-version 1.0.4 ext-texture-compression-bptc.html
--min-version 1.0.4 ext-texture-compression-rgtc.html
--min-version 1.0.4 ext-disjoint-timer-query.html
--min-version 1.0.3 --max-version 1.9.9 ext-frag-depth.html
+--min-version 1.0.4 ext-polygon-offset-clamp.html
--min-version 1.0.3 --max-version 1.9.9 ext-shader-texture-lod.html
--min-version 1.0.3 --max-version 1.9.9 ext-sRGB.html
--min-version 1.0.2 ext-texture-filter-anisotropic.html
+--min-version 1.0.4 ext-texture-mirror-clamp-to-edge.html
--min-version 1.0.2 get-extension.html
--min-version 1.0.4 khr-parallel-shader-compile.html
--max-version 1.9.9 oes-standard-derivatives.html
@@ -29,6 +33,7 @@
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float-with-video.html
--min-version 1.0.2 --max-version 1.9.9 oes-element-index-uint.html
--min-version 1.0.4 --max-version 1.9.9 oes-fbo-render-mipmap.html
+--min-version 1.0.4 --max-version 1.9.9 webgl-blend-func-extended.html
webgl-debug-renderer-info.html
webgl-debug-shaders.html
--min-version 1.0.4 webgl-compressed-texture-astc.html
@@ -44,3 +49,4 @@ webgl-debug-shaders.html
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-framebuffer-unsupported.html
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-max-draw-buffers.html
--min-version 1.0.4 webgl-multi-draw.html
+--min-version 1.0.4 webgl-polygon-mode.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-clip-control.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-clip-control.html
new file mode 100644
index 0000000000..f5c557c839
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-clip-control.html
@@ -0,0 +1,185 @@
+<!--
+Copyright (c) 2023 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_clip_control Conformance Tests</title>
+<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="32" height="32" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_clip_control extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c");
+var ext;
+const w = gl.drawingBufferWidth;
+const h = gl.drawingBufferHeight;
+
+function runTestNoExtension() {
+ debug("");
+ debug("Check the parameters without the extension");
+ shouldBeNull("gl.getParameter(0x935C /* CLIP_ORIGIN_EXT */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBeNull("gl.getParameter(0x935D /* CLIP_DEPTH_MODE_EXT */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkEnums() {
+ debug("");
+ debug("Check enums");
+ shouldBe("ext.LOWER_LEFT_EXT", "0x8CA1");
+ shouldBe("ext.UPPER_LEFT_EXT", "0x8CA2");
+
+ shouldBe("ext.NEGATIVE_ONE_TO_ONE_EXT", "0x935E");
+ shouldBe("ext.ZERO_TO_ONE_EXT", "0x935F");
+
+ shouldBe("ext.CLIP_ORIGIN_EXT", "0x935C");
+ shouldBe("ext.CLIP_DEPTH_MODE_EXT", "0x935D");
+}
+
+function checkQueries() {
+ debug("");
+ debug("Check default state");
+ shouldBe('gl.getParameter(ext.CLIP_ORIGIN_EXT)', 'ext.LOWER_LEFT_EXT');
+ shouldBe('gl.getParameter(ext.CLIP_DEPTH_MODE_EXT)', 'ext.NEGATIVE_ONE_TO_ONE_EXT');
+ debug("");
+ debug("Check state updates using the new function");
+ ext.clipControlEXT(ext.UPPER_LEFT_EXT, ext.ZERO_TO_ONE_EXT);
+ shouldBe('gl.getParameter(ext.CLIP_ORIGIN_EXT)', 'ext.UPPER_LEFT_EXT');
+ shouldBe('gl.getParameter(ext.CLIP_DEPTH_MODE_EXT)', 'ext.ZERO_TO_ONE_EXT');
+ ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT);
+ shouldBe('gl.getParameter(ext.CLIP_ORIGIN_EXT)', 'ext.LOWER_LEFT_EXT');
+ shouldBe('gl.getParameter(ext.CLIP_DEPTH_MODE_EXT)', 'ext.ZERO_TO_ONE_EXT');
+ ext.clipControlEXT(ext.UPPER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT);
+ shouldBe('gl.getParameter(ext.CLIP_ORIGIN_EXT)', 'ext.UPPER_LEFT_EXT');
+ shouldBe('gl.getParameter(ext.CLIP_DEPTH_MODE_EXT)', 'ext.NEGATIVE_ONE_TO_ONE_EXT');
+ ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT);
+ shouldBe('gl.getParameter(ext.CLIP_ORIGIN_EXT)', 'ext.LOWER_LEFT_EXT');
+ shouldBe('gl.getParameter(ext.CLIP_DEPTH_MODE_EXT)', 'ext.NEGATIVE_ONE_TO_ONE_EXT');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkDepthMode() {
+ debug("");
+ debug("Check depth mode toggling");
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+
+ const program = wtu.setupProgram(gl, [wtu.simpleVertexShader,
+ wtu.simpleColorFragmentShader]);
+ gl.useProgram(program);
+ const colorLoc = gl.getUniformLocation(program, "u_color");
+ wtu.setupUnitQuad(gl);
+
+ // Draw red at 0 with the default depth mode
+ gl.uniform4f(colorLoc, 1, 0, 0, 1);
+ ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [255, 0, 0, 255]);
+
+ // Draw green at 0, depth test must fail
+ gl.uniform4f(colorLoc, 0, 1, 0, 1);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [255, 0, 0, 255]);
+
+ // Draw green at 0 after switching the depth mode
+ ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [0, 255, 0, 255]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkClipOrigin() {
+ debug("");
+ debug("Check clip origin toggling");
+
+ gl.disable(gl.DEPTH_TEST);
+
+ const vertexShader = `
+ attribute vec4 vPosition;
+ varying float y;
+ void main() {
+ gl_Position = vPosition;
+ y = vPosition.y;
+ }`;
+ const fragmentShader = `
+ precision mediump float;
+ varying float y;
+ void main() {
+ if (y > 0.0) {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ } else {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ }
+ }`;
+
+ const program = wtu.setupProgram(gl, [vertexShader, fragmentShader]);
+ gl.useProgram(program);
+
+ wtu.setupUnitQuad(gl);
+
+ ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h / 2 - 2, [0, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, 0, h / 2 + 2, w, h / 2 - 2, [255, 0, 0, 255]);
+
+ ext.clipControlEXT(ext.UPPER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h / 2 - 2, [255, 0, 0, 255]);
+ wtu.checkCanvasRect(gl, 0, h / 2 + 2, w, h / 2 - 2, [0, 255, 0, 255]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function runTestExtension() {
+ checkEnums();
+ checkQueries();
+ checkDepthMode();
+ checkClipOrigin();
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+ testPassed("WebGL context exists");
+
+ runTestNoExtension();
+
+ ext = gl.getExtension("EXT_clip_control");
+
+ wtu.runExtensionSupportedTest(gl, "EXT_clip_control", ext !== null);
+
+ if (ext !== null) {
+ runTestExtension();
+ } else {
+ testPassed("No EXT_clip_control support -- this is legal");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-depth-clamp.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-depth-clamp.html
new file mode 100644
index 0000000000..6082c9880c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-depth-clamp.html
@@ -0,0 +1,168 @@
+<!--
+Copyright (c) 2023 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_depth_clamp Conformance Tests</title>
+<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="32" height="32" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_depth_clamp extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c");
+var ext;
+const w = gl.drawingBufferWidth;
+const h = gl.drawingBufferHeight;
+
+function runTestNoExtension() {
+ debug("");
+ debug("Check the parameter without the extension");
+ shouldBeNull("gl.getParameter(0x864F /* DEPTH_CLAMP_EXT */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ debug("Check the cap without the extension");
+ gl.disable(0x864F /* DEPTH_CLAMP_EXT */);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "cap unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ gl.enable(0x864F /* DEPTH_CLAMP_EXT */);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "cap unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ shouldBeFalse("gl.isEnabled(0x864F /* DEPTH_CLAMP_EXT */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "cap unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkEnums() {
+ debug("");
+ debug("Check enums");
+ shouldBe("ext.DEPTH_CLAMP_EXT", "0x864F");
+}
+
+function checkQueries() {
+ debug("");
+ debug("Check default state");
+ shouldBeFalse('gl.isEnabled(ext.DEPTH_CLAMP_EXT)');
+ shouldBeFalse('gl.getParameter(ext.DEPTH_CLAMP_EXT)');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ debug("");
+ debug("Check state update using the new capability");
+ gl.enable(ext.DEPTH_CLAMP_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBeTrue('gl.isEnabled(ext.DEPTH_CLAMP_EXT)');
+ shouldBeTrue('gl.getParameter(ext.DEPTH_CLAMP_EXT)');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ gl.disable(ext.DEPTH_CLAMP_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBeFalse('gl.isEnabled(ext.DEPTH_CLAMP_EXT)');
+ shouldBeFalse('gl.getParameter(ext.DEPTH_CLAMP_EXT)');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkClamping() {
+ debug("");
+ debug("Check depth clamp operation");
+
+ // Draw a red quad located beyond the clipping volume.
+ // When depth clamping is enabled, it must be drawn.
+ const vertexShader = `
+ attribute vec2 vPosition;
+ uniform float u_depth;
+ void main() {
+ gl_Position = vec4(vPosition, u_depth, 1.0);
+ }`;
+ const program = wtu.setupProgram(gl, [vertexShader,
+ wtu.simpleColorFragmentShader]);
+ gl.useProgram(program);
+ const colorLoc = gl.getUniformLocation(program, "u_color");
+ const depthLoc = gl.getUniformLocation(program, "u_depth");
+
+ wtu.setupUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ // Red beyond the far plane
+ gl.uniform4f(colorLoc, 1, 0, 0, 1);
+ gl.uniform1f(depthLoc, +2);
+
+ // Clipped
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [255, 255, 255, 255]);
+
+ // Enable depth clamping, disable depth clipping
+ gl.enable(ext.DEPTH_CLAMP_EXT);
+
+ // Not clipped
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [255, 0, 0, 255]);
+
+ // Green beyond the near plane
+ gl.uniform4f(colorLoc, 0, 1, 0, 1);
+ gl.uniform1f(depthLoc, -2);
+
+ // Not clipped
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [0, 255, 0, 255]);
+
+ // Blue beyond the near plane with clamping disabled
+ gl.disable(ext.DEPTH_CLAMP_EXT);
+ gl.uniform4f(colorLoc, 0, 0, 1, 1);
+
+ // Clipped
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, w, h, [255, 255, 255, 255]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function runTestExtension() {
+ checkEnums();
+ checkQueries();
+ checkClamping();
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+ testPassed("WebGL context exists");
+
+ runTestNoExtension();
+
+ ext = gl.getExtension("EXT_depth_clamp");
+
+ wtu.runExtensionSupportedTest(gl, "EXT_depth_clamp", ext !== null);
+
+ if (ext !== null) {
+ runTestExtension();
+ } else {
+ testPassed("No EXT_depth_clamp support -- this is legal");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-disjoint-timer-query.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-disjoint-timer-query.html
index 1fc29cc445..7965987c64 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-disjoint-timer-query.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-disjoint-timer-query.html
@@ -25,7 +25,9 @@ description("This test verifies the functionality of the EXT_disjoint_timer_quer
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas);
+var gl2 = null;
var ext = null;
+var ext2 = null;
var query = null;
var query2 = null;
var elapsed_query = null;
@@ -61,6 +63,8 @@ if (!gl) {
runTimeStampTest();
}
verifyQueryResultsNotAvailable();
+ verifyDeleteQueryBehavior();
+ verifyDeleteQueryErrorBehavior();
window.requestAnimationFrame(checkQueryResults);
}
@@ -245,6 +249,61 @@ function verifyQueryResultsNotAvailable() {
testPassed("Queries' results didn't become available in a spin loop");
}
+function verifyDeleteQueryBehavior() {
+ debug("");
+ debug("Testing deleting an active query should end it.");
+
+ // Use a new context for this test
+ gl2 = wtu.create3DContext(null, null, 1);
+ if (!gl2) return;
+ ext2 = gl2.getExtension("EXT_disjoint_timer_query");
+ if (!ext2) return;
+
+ query = ext2.createQueryEXT();
+ ext2.beginQueryEXT(ext2.TIME_ELAPSED_EXT, query);
+ wtu.glErrorShouldBe(gl2, gl2.NONE, "The query began successfully");
+ ext2.deleteQueryEXT(query);
+ wtu.glErrorShouldBe(gl2, gl2.NONE, "Deletion of the active query succeeds");
+ shouldBeNull("ext2.getQueryEXT(ext2.TIME_ELAPSED_EXT, ext2.CURRENT_QUERY_EXT)");
+ shouldBeFalse("ext2.isQueryEXT(query)");
+ query = ext2.createQueryEXT();
+ ext2.beginQueryEXT(ext2.TIME_ELAPSED_EXT, query);
+ wtu.glErrorShouldBe(gl2, gl2.NONE, "Beginning a new query succeeds");
+ ext2.endQueryEXT(ext2.TIME_ELAPSED_EXT);
+ ext2.deleteQueryEXT(query);
+ wtu.glErrorShouldBe(gl2, gl2.NONE);
+ query = null;
+ ext2 = null;
+ gl2 = null;
+}
+
+function verifyDeleteQueryErrorBehavior() {
+ debug("");
+ debug("Testing deleting a query created by another context.");
+
+ // Use new contexts for this test
+ gl2 = wtu.create3DContext(null, null, 1);
+ var gl3 = wtu.create3DContext(null, null, 1);
+ if (!gl2 || !gl3) return;
+ ext2 = gl2.getExtension("EXT_disjoint_timer_query");
+ var ext3 = gl3.getExtension("EXT_disjoint_timer_query");
+ if (!ext2 || !ext3) return;
+
+ query = ext2.createQueryEXT();
+ ext2.beginQueryEXT(ext2.TIME_ELAPSED_EXT, query);
+ ext3.deleteQueryEXT(query);
+ wtu.glErrorShouldBe(gl3, gl3.INVALID_OPERATION);
+ shouldBeTrue("ext2.isQueryEXT(query)");
+ shouldBe("ext2.getQueryEXT(ext2.TIME_ELAPSED_EXT, ext2.CURRENT_QUERY_EXT)", "query");
+ ext2.endQueryEXT(ext2.TIME_ELAPSED_EXT);
+ ext2.deleteQueryEXT(query);
+ wtu.glErrorShouldBe(gl2, gl2.NONE);
+ query = null;
+ ext2 = null;
+ gl2 = null;
+ gl3 = null;
+}
+
function checkQueryResults() {
if (availability_retry > 0) {
// Make a reasonable attempt to wait for the queries' results to become available.
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-polygon-offset-clamp.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-polygon-offset-clamp.html
new file mode 100644
index 0000000000..ce14e96fc7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-polygon-offset-clamp.html
@@ -0,0 +1,172 @@
+<!--
+Copyright (c) 2023 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_polygon_offset_clamp Conformance Tests</title>
+<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="32" height="32" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_polygon_offset_clamp extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+var ext;
+const w = gl.drawingBufferWidth;
+const h = gl.drawingBufferHeight;
+
+function runTestNoExtension() {
+ debug("");
+ debug("Check the parameter without the extension");
+ shouldBeNull("gl.getParameter(0x8E1B /* POLYGON_OFFSET_CLAMP_EXT */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkEnums() {
+ debug("");
+ debug("Check enums");
+ shouldBe("ext.POLYGON_OFFSET_CLAMP_EXT", "0x8E1B");
+}
+
+function checkQueries() {
+ debug("");
+ debug("Check default state");
+ shouldBe('gl.getParameter(gl.POLYGON_OFFSET_FACTOR)', '0.0');
+ shouldBe('gl.getParameter(gl.POLYGON_OFFSET_UNITS)', '0.0');
+ shouldBe('gl.getParameter(ext.POLYGON_OFFSET_CLAMP_EXT)', '0.0');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ debug("");
+ debug("Check state update using the new function");
+ ext.polygonOffsetClampEXT(1.0, 2.0, 3.0);
+ shouldBe('gl.getParameter(gl.POLYGON_OFFSET_FACTOR)', '1.0');
+ shouldBe('gl.getParameter(gl.POLYGON_OFFSET_UNITS)', '2.0');
+ shouldBe('gl.getParameter(ext.POLYGON_OFFSET_CLAMP_EXT)', '3.0');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ debug("");
+ debug("Check that the unextended function resets the clamp value to zero");
+ gl.polygonOffset(4.0, 5.0);
+ shouldBe('gl.getParameter(gl.POLYGON_OFFSET_FACTOR)', '4.0');
+ shouldBe('gl.getParameter(gl.POLYGON_OFFSET_UNITS)', '5.0');
+ shouldBe('gl.getParameter(ext.POLYGON_OFFSET_CLAMP_EXT)', '0.0');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkClamping() {
+ debug("");
+ debug("Check polygon offset clamp operation");
+
+ // The shader creates a depth slope from left (0) to right (1).
+ //
+ // This test issues two draw calls:
+ //
+ // Draw 2 (green): factor width, offset 0, clamp 0.5, depth test: Greater
+ // ^ | __________________
+ // | | __/ __/
+ // | V __/ __/ <--- Draw 1 (red): factor width, offset 0, clamp 0.25
+ // | __/ __/
+ // | __/ __/
+ // |/ __/
+ // | __/
+ // | __/
+ // |/
+ // |
+ // |
+ // +------------------------------->
+ //
+ // Result: <---------green--------><--red-->
+
+
+ const program = wtu.setupProgram(gl, [wtu.simpleVertexShader,
+ wtu.simpleColorFragmentShader]);
+ gl.useProgram(program);
+ const colorLoc = gl.getUniformLocation(program, "u_color");
+
+ const buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array([-1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1]),
+ gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ gl.enable(gl.POLYGON_OFFSET_FILL);
+ gl.clearColor(0, 0, 0, 1);
+ gl.clearDepth(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ gl.depthFunc(gl.ALWAYS);
+ gl.uniform4f(colorLoc, 1, 0, 0, 1);
+ ext.polygonOffsetClampEXT(w, 0, 0.25);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+
+ gl.depthFunc(gl.GREATER);
+ gl.uniform4f(colorLoc, 0, 1, 0, 1);
+ ext.polygonOffsetClampEXT(w, 0, 0.5);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+
+ wtu.checkCanvasRect(
+ gl,
+ 0, 0, 3 * w / 4 - 1, h,
+ [0, 255, 0, 255], "should be green");
+
+ wtu.checkCanvasRect(
+ gl,
+ 3 * w / 4 + 1, 0, w / 4 - 1, h,
+ [255, 0, 0, 255], "should be red");
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function runTestExtension() {
+ checkEnums();
+ checkQueries();
+ checkClamping();
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+ testPassed("WebGL context exists");
+
+ runTestNoExtension();
+
+ ext = gl.getExtension("EXT_polygon_offset_clamp");
+
+ wtu.runExtensionSupportedTest(gl, "EXT_polygon_offset_clamp", ext !== null);
+
+ if (ext !== null) {
+ runTestExtension();
+ } else {
+ testPassed("No EXT_polygon_offset_clamp support -- this is legal");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-sRGB.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-sRGB.html
index 7e8353f7f2..a997bdb4ab 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-sRGB.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-sRGB.html
@@ -222,6 +222,40 @@ if (!gl) {
runFormatTest(textureFormatFixture, false);
runFormatTest(renderbufferFormatFixture, false);
+ {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ debug("Checking getFramebufferAttachmentParameter with a renderbuffer");
+ {
+ var rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB565, 1, 1);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8210 /* FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT */)');
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(rbo);
+ }
+
+ debug("Checking getFramebufferAttachmentParameter with a texture");
+ {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8210 /* FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT */)');
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ }
+
debug("");
debug("Checking sRGB texture support");
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-rgtc.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-rgtc.html
index 70dcf9ba7b..d9c34af25f 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-rgtc.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-rgtc.html
@@ -120,16 +120,16 @@ function runTestExtension() {
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RED_RGTC1_EXT, 4, 4, 0, gl.RED, gl.UNSIGNED_BYTE, null);
- wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RED_RGTC1_EXT fails with texImage2D");
+ wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_OPERATION], "COMPRESSED_RED_RGTC1_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_SIGNED_RED_RGTC1_EXT, 4, 4, 0, gl.RED, gl.BYTE, null);
- wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_SIGNED_RED_RGTC1_EXT fails with texImage2D");
+ wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_OPERATION], "COMPRESSED_SIGNED_RED_RGTC1_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RED_GREEN_RGTC2_EXT, 4, 4, 0, gl.RG, gl.UNSIGNED_BYTE, null);
- wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RED_GREEN_RGTC2_EXT fails with texImage2D");
+ wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_OPERATION], "COMPRESSED_RED_GREEN_RGTC2_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, 4, 4, 0, gl.RG, gl.BYTE, null);
- wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT fails with texImage2D");
+ wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_OPERATION], "COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT fails with texImage2D");
gl.deleteTexture(tex);
}
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-mirror-clamp-to-edge.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-mirror-clamp-to-edge.html
new file mode 100644
index 0000000000..4e2f980b4b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-mirror-clamp-to-edge.html
@@ -0,0 +1,217 @@
+<!--
+Copyright (c) 2023 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_texture_mirror_clamp_to_edge Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="32" height="32" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_texture_mirror_clamp_to_edge extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c");
+const w = gl.drawingBufferWidth;
+const h = gl.drawingBufferHeight;
+var ext;
+var sampler;
+
+const pnames = ['TEXTURE_WRAP_S', 'TEXTURE_WRAP_T'];
+if (gl.TEXTURE_WRAP_R) {
+ pnames.push('TEXTURE_WRAP_R');
+}
+
+function runTestNoExtension() {
+ debug("");
+ debug("Check the texture parameter without the extension");
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ const MIRROR_CLAMP_TO_EDGE_EXT = 0x8743;
+
+ for (const pname of pnames) {
+ gl.texParameteri(gl.TEXTURE_2D, gl[pname], MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, `value unknown for ${pname} via texParameteri without enabling the extension`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+ gl.texParameterf(gl.TEXTURE_2D, gl[pname], MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, `value unknown for ${pname} via texParameterf without enabling the extension`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+ }
+
+ if (!gl.createSampler) return;
+
+ const sampler = gl.createSampler();
+ for (const pname of pnames) {
+ gl.samplerParameteri(sampler, gl[pname], MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, `value unknown for ${pname} via samplerParameteri without enabling the extension`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+ gl.samplerParameterf(sampler, gl[pname], MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, `value unknown for ${pname} via samplerParameterf without enabling the extension`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+ }
+}
+
+function checkEnums() {
+ debug("");
+ debug("Check enums");
+ shouldBe("ext.MIRROR_CLAMP_TO_EDGE_EXT", "0x8743");
+}
+
+function checkQueries() {
+ debug("");
+ debug("Check texture and sampler state updates");
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ for (const pname of pnames) {
+ gl.texParameteri(gl.TEXTURE_2D, gl[pname], ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from texParameteri");
+ shouldBe(`gl.getTexParameter(gl.TEXTURE_2D, gl.${pname})`, "ext.MIRROR_CLAMP_TO_EDGE_EXT");
+ gl.texParameteri(gl.TEXTURE_2D, gl[pname], gl.REPEAT);
+
+ gl.texParameterf(gl.TEXTURE_2D, gl[pname], ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from texParameterf");
+ shouldBe(`gl.getTexParameter(gl.TEXTURE_2D, gl.${pname})`, "ext.MIRROR_CLAMP_TO_EDGE_EXT");
+ gl.texParameterf(gl.TEXTURE_2D, gl[pname], gl.REPEAT);
+ }
+
+ if (!gl.createSampler) return;
+
+ sampler = gl.createSampler();
+ for (const pname of pnames) {
+ gl.samplerParameteri(sampler, gl[pname], ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from samplerParameteri");
+ shouldBe(`gl.getSamplerParameter(sampler, gl.${pname})`, "ext.MIRROR_CLAMP_TO_EDGE_EXT");
+ gl.samplerParameteri(sampler, gl[pname], gl.REPEAT);
+
+ gl.samplerParameterf(sampler, gl[pname], ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from samplerParameterf");
+ shouldBe(`gl.getSamplerParameter(sampler, gl.${pname})`, "ext.MIRROR_CLAMP_TO_EDGE_EXT");
+ gl.samplerParameterf(sampler, gl[pname], gl.REPEAT);
+ }
+}
+
+function checkSampling() {
+ debug("");
+ debug(`Check texture sampling with mirror-clamp-to-edge mode`);
+
+ wtu.setupUnitQuad(gl);
+ const vs = `precision highp float;
+ attribute vec4 vPosition;
+ varying vec2 texCoord;
+ void main() {
+ gl_Position = vec4(vPosition.xy, 0.0, 1.0);
+ texCoord = vPosition.xy * 2.0;
+ }`;
+ const program = wtu.setupProgram(gl, [vs, wtu.simpleTextureFragmentShader]);
+ gl.useProgram(program);
+
+ const black = [ 0, 0, 0, 255];
+ const red = [255, 0, 0, 255];
+ const green = [ 0, 255, 0, 255];
+ const blue = [ 0, 0, 255, 255];
+ const data = new Uint8Array([...black, ...red, ...green, ...blue]);
+
+ function checkPixels() {
+ function checkPixel(x, y, color) {
+ const screen = (s, t) => s * (t * 0.5 + 0.5);
+ wtu.checkCanvasRect(gl, screen(w, x), screen(h, y), 1, 1, color,
+ `(${x.toFixed(3)}, ${y.toFixed(3)}): ${color} `);
+ }
+ for (const signX of [+1, -1]) {
+ for (const signY of [+1, -1]) {
+ // This function expects screen-space coordinates
+ // normalized to [-1, +1]. The region from [0, 0]
+ // to [+1, +1] behaves like regular clamp-to-edge.
+ // Other three quadrants should be mirrored.
+ checkPixel(signX * 0.125, signY * 0.125, black);
+ checkPixel(signX * 0.375, signY * 0.125, red);
+ checkPixel(signX * 0.750, signY * 0.125, red);
+ checkPixel(signX * 0.125, signY * 0.375, green);
+ checkPixel(signX * 0.125, signY * 0.750, green);
+ checkPixel(signX * 0.375, signY * 0.375, blue);
+ checkPixel(signX * 0.750, signY * 0.375, blue);
+ checkPixel(signX * 0.375, signY * 0.750, blue);
+ checkPixel(signX * 0.750, signY * 0.750, blue);
+ }
+ }
+ }
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, ext.MIRROR_CLAMP_TO_EDGE_EXT);
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture created and configured");
+
+ wtu.drawUnitQuad(gl);
+ checkPixels();
+
+ if (!gl.createSampler) return;
+
+ debug("");
+ debug(`Check texture sampling with mirror-clamp-to-edge mode using a sampler object`);
+
+ const texWithSampler = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texWithSampler);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+
+ sampler = gl.createSampler();
+ gl.bindSampler(0, sampler);
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_T, ext.MIRROR_CLAMP_TO_EDGE_EXT);
+ gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture created and sampler configured");
+
+ wtu.drawUnitQuad(gl);
+ checkPixels();
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ testPassed("context exists");
+
+ runTestNoExtension();
+
+ ext = gl.getExtension("EXT_texture_mirror_clamp_to_edge");
+ wtu.runExtensionSupportedTest(gl, "EXT_texture_mirror_clamp_to_edge", ext !== null);
+
+ if (ext !== null) {
+ checkEnums();
+ checkQueries();
+ checkSampling();
+ } else {
+ testPassed("No EXT_texture_mirror_clamp_to_edge support -- this is legal");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/khr-parallel-shader-compile.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/khr-parallel-shader-compile.html
index 2915a2d2de..6a8b1981e5 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/khr-parallel-shader-compile.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/khr-parallel-shader-compile.html
@@ -169,6 +169,32 @@ let extraCode = '';
testPassed(`COMPLETION_STATUS_KHR sucessfully transitioned from false to true`);
}
+ debug("Checking that compiling lots of programs in parallel eventually completes.");
+ let programs = [];
+ for (let i = 0; i < 256; ++i) {
+ gl.shaderSource(vs, vertexSource());
+ gl.shaderSource(fs, fragmentSource());
+ gl.compileShader(vs);
+ gl.compileShader(fs);
+ let program = gl.createProgram();
+ gl.attachShader(program, vs);
+ gl.attachShader(program, fs);
+ gl.linkProgram(program);
+ programs.push(program);
+ }
+ let allDone = false;
+ while (!allDone) {
+ allDone = true;
+ for (let i = 0; i < programs.length; ++i) {
+ if (!gl.getProgramParameter(programs[i], COMPLETION_STATUS_KHR)) {
+ allDone = false;
+ break;
+ }
+ }
+ if (!allDone) {
+ await new Promise(requestAnimationFrame);
+ }
+ }
debug("Checking that status is true when context is lost.");
if (loseContext) {
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-video.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-video.html
index 3ccbd50f15..cb406706f9 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-video.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-video.html
@@ -33,7 +33,6 @@ function testPrologue(gl) {
<video width="640" height="228" id="vid" controls muted>
<source src="../../resources/red-green.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="../../resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
- <source src="../../resources/red-green.theora.ogv" type='video/ogg; codecs="theora, vorbis"' />
</video>
</body>
</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float.html
index a757cb22ec..8bec35b9cf 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float.html
@@ -60,6 +60,7 @@ debug("");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas);
+var ext = null;
if (!gl) {
testFailed("WebGL context does not exist");
@@ -81,6 +82,33 @@ if (!gl) {
// the extension has not been enabled yet.
runTextureCreationTest(testProgram, false);
+ {
+ debug("");
+ debug("Testing that component type framebuffer attachment queries are rejected with the extension disabled");
+ const fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ const rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB565, 8, 8);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup renderbuffer should succeed.");
+ shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8211 /* FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT */)');
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Query must fail.");
+ gl.deleteRenderbuffer(rbo);
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup texture should succeed.");
+ shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8211 /* FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT */)');
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Query must fail.");
+ gl.deleteTexture(tex);
+
+ gl.deleteFramebuffer(fbo);
+ }
+
if (!gl.getExtension("OES_texture_float")) {
testPassed("No OES_texture_float support -- this is legal");
} else {
@@ -109,6 +137,43 @@ if (!gl) {
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0.5, true);
runFramebufferTest();
+ {
+ debug("");
+ debug("Testing that component type framebuffer attachment queries are accepted with the extension enabled");
+ ext = gl.getExtension("WEBGL_color_buffer_float");
+ shouldBeNonNull('ext');
+ const fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ const rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB565, 8, 8);
+ shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'ext.UNSIGNED_NORMALIZED_EXT');
+ gl.renderbufferStorage(gl.RENDERBUFFER, ext.RGBA32F_EXT, 8, 8);
+ shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'gl.FLOAT');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after valid renderbuffer attachment queries.");
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT,gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, 8, 8);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after depth-stencil renderbuffer setup.");
+ shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)');
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Component type query is not allowed for combined depth-stencil attachments.");
+ gl.deleteRenderbuffer(rbo);
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'ext.UNSIGNED_NORMALIZED_EXT');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8, 8, 0, gl.RGBA, gl.FLOAT, null);
+ shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'gl.FLOAT');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after valid texture attachment queries.");
+ gl.deleteTexture(tex);
+
+ gl.deleteFramebuffer(fbo);
+ }
+
debug("");
debug("Test float32 blending without EXT_float_blend.");
testExtFloatBlend(gl.RGBA);
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-video.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-video.html
index 719b332113..d6076b29f9 100644
--- a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-video.html
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-video.html
@@ -38,7 +38,6 @@ function testPrologue(gl) {
<video width="640" height="228" id="vid" controls muted>
<source src="../../resources/red-green.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="../../resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
- <source src="../../resources/red-green.theora.ogv" type='video/ogg; codecs="theora, vorbis"' />
</video>
</body>
</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-blend-func-extended.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-blend-func-extended.html
new file mode 100644
index 0000000000..62e25adaa2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-blend-func-extended.html
@@ -0,0 +1,26 @@
+<!--
+Copyright (c) 2023 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 1.0 WEBGL_blend_func_extended Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="32" height="32" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 1;
+</script>
+<script src="../../js/tests/webgl-blend-func-extended.js"></script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-polygon-mode.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-polygon-mode.html
new file mode 100644
index 0000000000..fd65f692a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-polygon-mode.html
@@ -0,0 +1,185 @@
+<!--
+Copyright (c) 2023 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL WEBGL_polygon_mode Conformance Tests</title>
+<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="32" height="32" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the WEBGL_polygon_mode extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c");
+var ext;
+const w = gl.drawingBufferWidth;
+const h = gl.drawingBufferHeight;
+
+function runTestNoExtension() {
+ debug("");
+ debug("Check the parameters without the extension");
+ shouldBeNull("gl.getParameter(0x0B40 /* POLYGON_MODE_WEBGL */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBeNull("gl.getParameter(0x2A02 /* POLYGON_OFFSET_LINE_WEBGL */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ debug("Check the cap without the extension");
+ gl.disable(0x2A02 /* POLYGON_OFFSET_LINE_WEBGL */);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "cap unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ gl.enable(0x2A02 /* POLYGON_OFFSET_LINE_WEBGL */);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "cap unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+ shouldBeFalse("gl.isEnabled(0x2A02 /* POLYGON_OFFSET_LINE_WEBGL */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "cap unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkEnums() {
+ debug("");
+ debug("Check enums");
+ shouldBe("ext.POLYGON_MODE_WEBGL", "0x0B40");
+ shouldBe("ext.POLYGON_OFFSET_LINE_WEBGL", "0x2A02");
+ shouldBe("ext.LINE_WEBGL", "0x1B01");
+ shouldBe("ext.FILL_WEBGL", "0x1B02");
+}
+
+function checkQueries() {
+ debug("");
+ debug("Check default state");
+ shouldBe('gl.getParameter(ext.POLYGON_MODE_WEBGL)', 'ext.FILL_WEBGL');
+ shouldBeFalse('gl.getParameter(ext.POLYGON_OFFSET_LINE_WEBGL)');
+ shouldBeFalse('gl.isEnabled(ext.POLYGON_OFFSET_LINE_WEBGL)');
+ debug("");
+ debug("Check state updates");
+ ext.polygonModeWEBGL(gl.FRONT_AND_BACK, ext.LINE_WEBGL);
+ shouldBe('gl.getParameter(ext.POLYGON_MODE_WEBGL)', 'ext.LINE_WEBGL');
+ ext.polygonModeWEBGL(gl.FRONT_AND_BACK, ext.FILL_WEBGL);
+ shouldBe('gl.getParameter(ext.POLYGON_MODE_WEBGL)', 'ext.FILL_WEBGL');
+ debug("");
+ debug("Check errors");
+ ext.polygonModeWEBGL(gl.FRONT, ext.LINE_WEBGL);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "invalid face");
+ ext.polygonModeWEBGL(gl.FRONT_AND_BACK, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "invalid mode");
+ shouldBe('gl.getParameter(ext.POLYGON_MODE_WEBGL)', 'ext.FILL_WEBGL');
+ debug("");
+ debug("Check cap updates");
+ gl.enable(ext.POLYGON_OFFSET_LINE_WEBGL);
+ shouldBeTrue('gl.getParameter(ext.POLYGON_OFFSET_LINE_WEBGL)');
+ shouldBeTrue('gl.isEnabled(ext.POLYGON_OFFSET_LINE_WEBGL)');
+ gl.disable(ext.POLYGON_OFFSET_LINE_WEBGL);
+ shouldBeFalse('gl.getParameter(ext.POLYGON_OFFSET_LINE_WEBGL)');
+ shouldBeFalse('gl.isEnabled(ext.POLYGON_OFFSET_LINE_WEBGL)');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function checkDiagonal(r, g, b) {
+ const pixels = new Uint8Array(w * h * 4);
+ gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ for (let i = 0; i < w; i++)
+ {
+ const baseOffset = (i * w + i) * 4;
+ if (pixels[baseOffset + 0] != r ||
+ pixels[baseOffset + 1] != g ||
+ pixels[baseOffset + 2] != b) {
+ testFailed(`Unexpected diagonal color at (${i}, ${i})`);
+ return;
+ }
+ }
+ testPassed("Expected diagonal color");
+}
+
+function checkLineMode() {
+ debug("");
+ debug("Check line polygon mode");
+
+ gl.enable(gl.DEPTH_TEST);
+
+ const program = wtu.setupProgram(gl, [wtu.simpleVertexShader,
+ wtu.simpleColorFragmentShader]);
+ gl.useProgram(program);
+ const colorLoc = gl.getUniformLocation(program, "u_color");
+
+ wtu.setupUnitQuad(gl);
+
+ // Draw red quad with lines
+ gl.uniform4f(colorLoc, 1, 0, 0, 1);
+ ext.polygonModeWEBGL(gl.FRONT_AND_BACK, ext.LINE_WEBGL);
+ wtu.clearAndDrawUnitQuad(gl);
+
+ // Nothing is drawn inside triangles
+ wtu.checkCanvasRect(gl, 2, 17, 13, 13, [255, 255, 255, 255]);
+ wtu.checkCanvasRect(gl, 17, 2, 13, 13, [255, 255, 255, 255]);
+
+ // Main diagonal is drawn
+ checkDiagonal(255, 0, 0);
+
+ // Test polygon offset
+ gl.polygonOffset(0, -2);
+ gl.enable(gl.POLYGON_OFFSET_FILL);
+
+ // Depth test must fail because line mode uses its own polygon offset toggle
+ gl.uniform4f(colorLoc, 0, 1, 0, 1);
+ wtu.drawUnitQuad(gl);
+ checkDiagonal(255, 0, 0);
+
+ // Depth test must pass
+ gl.enable(ext.POLYGON_OFFSET_LINE_WEBGL)
+ wtu.drawUnitQuad(gl);
+ checkDiagonal(0, 255, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+function runTestExtension() {
+ checkEnums();
+ checkQueries();
+ checkLineMode();
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+ testPassed("WebGL context exists");
+
+ runTestNoExtension();
+
+ ext = gl.getExtension("WEBGL_polygon_mode");
+
+ wtu.runExtensionSupportedTest(gl, "WEBGL_polygon_mode", ext !== null);
+
+ if (ext !== null) {
+ runTestExtension();
+ } else {
+ testPassed("No WEBGL_polygon_mode support -- this is legal");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>