summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/programs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/00_test_list.txt12
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/get-active-test.html119
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-long-names-test.html153
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-test.html139
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-attribute.html85
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-uniform.html136
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-getshadersource.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-shader-test.html94
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/invalid-UTF-16.html48
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/program-handling.html142
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/program-infolog.html62
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/program-test.html406
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/programs/use-program-crash-with-discard-in-fragment-shader.html77
13 files changed, 1512 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/programs/00_test_list.txt
new file mode 100644
index 0000000000..061caa574a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/00_test_list.txt
@@ -0,0 +1,12 @@
+get-active-test.html
+gl-bind-attrib-location-test.html
+--min-version 1.0.2 gl-bind-attrib-location-long-names-test.html
+gl-get-active-attribute.html
+gl-get-active-uniform.html
+gl-getshadersource.html
+gl-shader-test.html
+invalid-UTF-16.html
+--min-version 1.0.4 program-handling.html
+--min-version 1.0.4 program-infolog.html
+program-test.html
+--min-version 1.0.2 use-program-crash-with-discard-in-fragment-shader.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/get-active-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/get-active-test.html
new file mode 100644
index 0000000000..ce2b4f9b1a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/get-active-test.html
@@ -0,0 +1,119 @@
+<!--
+Copyright (c) 2019 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">
+<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>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Test of getActiveAttrib and getActiveUniform");
+
+var wtu = WebGLTestUtils;
+var context = wtu.create3DContext();
+var context2 = wtu.create3DContext();
+var program = wtu.loadStandardProgram(context);
+var program2 = wtu.loadProgramFromFile(context2,
+ "../../resources/intArrayUniformShader.vert",
+ "../../resources/noopUniformShader.frag");
+
+wtu.glErrorShouldBe(context, context.NO_ERROR);
+shouldBe("context.getActiveUniform(program, 0).name", "'u_modelViewProjMatrix'");
+shouldBe("context.getActiveUniform(program, 0).type", "context.FLOAT_MAT4");
+shouldBe("context.getActiveUniform(program, 0).size", "1");
+shouldBeNull("context.getActiveUniform(program, 1)");
+wtu.glErrorShouldBe(context, context.INVALID_VALUE);
+shouldBeNull("context.getActiveUniform(program, -1)");
+wtu.glErrorShouldBe(context, context.INVALID_VALUE);
+shouldThrow("context.getActiveUniform(null, 0)");
+wtu.glErrorShouldBe(context, context.NO_ERROR);
+
+// we don't know the order the attribs will appear.
+var info = [
+ context.getActiveAttrib(program, 0),
+ context.getActiveAttrib(program, 1)
+];
+for (var ii = 0; ii < info.length; ++ii)
+ shouldBeNonNull("info[ii]");
+
+var expected = [
+ { name: 'a_normal', type: context.FLOAT_VEC3, size: 1 },
+ { name: 'a_vertex', type: context.FLOAT_VEC4, size: 1 }
+];
+
+if (info[0].name != expected[0].name) {
+ var t = info[0];
+ info[0] = info[1];
+ info[1] = t;
+}
+
+for (var ii = 0; ii < info.length; ++ii) {
+ shouldBe("info[ii].name", "expected[ii].name");
+ shouldBe("info[ii].type", "expected[ii].type");
+ shouldBe("info[ii].size", "expected[ii].size");
+}
+
+// we don't know the order the uniforms will appear.
+var info2 = [
+ context2.getActiveUniform(program2, 0),
+ context2.getActiveUniform(program2, 1)
+];
+for (var ii = 0; ii < info2.length; ++ii)
+ shouldBeNonNull("info2[ii]");
+
+var expected2 = [
+ { name: 'ival', type: context2.INT, size: 1 },
+ { name: 'ival2[0]', type: context2.INT, size: 2 }
+];
+
+if (info2[0].name != expected2[0].name) {
+ t = info2[0];
+ info2[0] = info2[1];
+ info2[1] = t;
+}
+
+for (var ii = 0; ii < info2.length; ++ii) {
+ shouldBe("info2[ii].name", "expected2[ii].name");
+ shouldBe("info2[ii].type", "expected2[ii].type");
+ shouldBe("info2[ii].size", "expected2[ii].size");
+}
+
+shouldBeNull("context.getActiveAttrib(program, 2)");
+wtu.glErrorShouldBe(context, context.INVALID_VALUE);
+shouldBeNull("context.getActiveAttrib(program, -1)");
+wtu.glErrorShouldBe(context, context.INVALID_VALUE);
+shouldThrow("context.getActiveAttrib(null, 0)");
+wtu.glErrorShouldBe(context, context.NO_ERROR);
+
+wtu.glErrorShouldBe(context2, context.NO_ERROR);
+
+debug("Check trying to get attribs from different context");
+shouldBeNull("context2.getActiveAttrib(program, 0)");
+wtu.glErrorShouldBe(context2, context2.INVALID_OPERATION);
+shouldBeNull("context2.getActiveUniform(program, 0)");
+wtu.glErrorShouldBe(context2, context2.INVALID_OPERATION);
+
+debug("Check trying to get attribs from deleted program");
+context.deleteProgram(program);
+shouldBeNull("context.getActiveUniform(program, 0)");
+wtu.glErrorShouldBe(context, context.INVALID_VALUE);
+shouldBeNull("context.getActiveAttrib(program, 0)");
+wtu.glErrorShouldBe(context, context.INVALID_VALUE);
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-long-names-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-long-names-test.html
new file mode 100644
index 0000000000..90328bee45
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-long-names-test.html
@@ -0,0 +1,153 @@
+<!--
+Copyright (c) 2019 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 BindAttribLocation Long Names 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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas style="border: 1px solid black;" id="canvas" width="50" height="50"></canvas>
+<script id="vshader" type="text/something-not-javascript">
+attribute vec4 vPosition$(suffix);
+attribute vec4 vColor$(suffix);
+varying vec4 color;
+void main()
+{
+ gl_Position = vPosition$(suffix);
+ color = vColor$(suffix);
+}
+</script>
+<script id="fshader" type="text/something-not-javascript">
+precision mediump float;
+
+varying vec4 color;
+void main()
+{
+ gl_FragColor = color;
+}
+</script>
+<script>
+"use strict";
+description("This test checks using long names with bindAttribLocation work.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+shouldBeNonNull("gl");
+
+debug("");
+debug("Checking gl.bindAttribLocation with long names.");
+
+var program = gl.createProgram();
+
+var suffix = "long";
+for (var ii = 0; ii < 5; ++ii) {
+ suffix = suffix + suffix;
+}
+var replacements = {
+ suffix: suffix
+};
+
+var vsrc = wtu.replaceParams(wtu.getScript("vshader"), replacements);
+var fsrc = wtu.replaceParams(wtu.getScript("fshader"), replacements);
+
+var vs = wtu.loadShader(gl, vsrc, gl.VERTEX_SHADER);
+var fs = wtu.loadShader(gl, fsrc, gl.FRAGMENT_SHADER);
+
+var attribs = {
+ vPosition: "vPosition" + suffix,
+ vColor: "vColor" + suffix
+};
+
+gl.attachShader(program, vs);
+gl.attachShader(program, fs);
+
+var positions = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, positions);
+gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array(
+ [ 1.0, 1.0, 0.0,
+ -1.0, 1.0, 0.0,
+ -1.0, -1.0, 0.0,
+ 1.0, 1.0, 0.0,
+ -1.0, -1.0, 0.0,
+ 1.0, -1.0, 0.0]),
+ gl.STATIC_DRAW);
+
+var colors = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, colors);
+gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array(
+ [ 0,1,0,1,
+ 0,1,0,1,
+ 0,1,0,1,
+ 0,1,0,1,
+ 0,1,0,1,
+ 0,1,0,1]),
+ gl.STATIC_DRAW);
+
+function setBindLocations(colorLocation, positionLocation) {
+ gl.bindAttribLocation(program, positionLocation, attribs.vPosition);
+ gl.bindAttribLocation(program, colorLocation, attribs.vColor);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+ var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0);
+ assertMsg(linked, "program linked successfully");
+
+ debug("vPosition:" + gl.getAttribLocation(program, attribs.vPosition))
+ debug("vColor :" + gl.getAttribLocation(program, attribs.vColor))
+ assertMsg(gl.getAttribLocation(program, attribs.vPosition) == positionLocation,
+ "location of vPosition should be " + positionLocation);
+ assertMsg(gl.getAttribLocation(program, attribs.vColor) == colorLocation,
+ "location of vColor should be " + colorLocation);
+
+ var ploc = gl.getAttribLocation(program, attribs.vPosition);
+ var cloc = gl.getAttribLocation(program, attribs.vColor);
+ gl.bindBuffer(gl.ARRAY_BUFFER, positions);
+ gl.enableVertexAttribArray(positionLocation);
+ gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colors);
+ gl.enableVertexAttribArray(colorLocation);
+ gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
+}
+
+function checkDraw(colorLocation, positionLocation, r, g, b, a) {
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [r, g, b, a], "should be green");
+
+ gl.disableVertexAttribArray(positionLocation);
+ gl.disableVertexAttribArray(colorLocation);
+}
+
+setBindLocations(2, 3);
+checkDraw(2, 3, 0, 255, 0, 255);
+
+setBindLocations(0, 3);
+gl.disableVertexAttribArray(0);
+gl.vertexAttrib4f(0, 1, 0, 0, 1);
+checkDraw(0, 3, 255, 0, 0, 255);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-test.html
new file mode 100644
index 0000000000..6909c64491
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-test.html
@@ -0,0 +1,139 @@
+<!--
+Copyright (c) 2019 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 BindAttribLocation 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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas style="border: 1px solid black;" id="canvas" width="50" height="50"></canvas>
+<script id="vshader" type="text/something-not-javascript">
+attribute vec4 vPosition;
+attribute vec4 vColor;
+varying vec4 color;
+void main()
+{
+ gl_Position = vPosition;
+ color = vColor;
+}
+</script>
+<script id="fshader" type="text/something-not-javascript">
+precision mediump float;
+
+varying vec4 color;
+void main()
+{
+ gl_FragColor = color;
+}
+</script>
+<script>
+"use strict";
+description("This test ensures WebGL implementations don't allow names that start with 'gl_' when calling bindAttribLocation.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+shouldBeNonNull("gl");
+
+debug("");
+debug("Checking gl.bindAttribLocation.");
+
+var program = gl.createProgram();
+gl.bindAttribLocation(program, 0, "gl_foo");
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "bindAttribLocation should return INVALID_OPERATION if name starts with 'gl_'");
+gl.bindAttribLocation(program, 0, "gl_TexCoord0");
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "bindAttribLocation should return INVALID_OPERATION if name starts with 'gl_'");
+
+var vs = wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER);
+var fs = wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER);
+gl.attachShader(program, vs);
+gl.attachShader(program, fs);
+
+var positions = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, positions);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
+
+var colors = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, colors);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ 0,1,0,1,
+ 0,1,0,1,
+ 0,1,0,1]), gl.STATIC_DRAW);
+
+function setBindLocations(colorLocation, positionLocation) {
+ gl.bindAttribLocation(program, positionLocation, "vPosition");
+ gl.bindAttribLocation(program, colorLocation, "vColor");
+ gl.linkProgram(program);
+ gl.useProgram(program);
+ var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0);
+ assertMsg(linked, "program linked successfully");
+
+ debug("vPosition:" + gl.getAttribLocation(program, "vPosition"))
+ debug("vColor :" + gl.getAttribLocation(program, "vColor"))
+ assertMsg(gl.getAttribLocation(program, "vPosition") == positionLocation,
+ "location of vPosition should be " + positionLocation);
+ assertMsg(gl.getAttribLocation(program, "vColor") == colorLocation,
+ "location of vColor should be " + colorLocation);
+
+ var ploc = gl.getAttribLocation(program, "vPosition");
+ var cloc = gl.getAttribLocation(program, "vColor");
+ gl.bindBuffer(gl.ARRAY_BUFFER, positions);
+ gl.enableVertexAttribArray(positionLocation);
+ gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colors);
+ gl.enableVertexAttribArray(colorLocation);
+ gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
+}
+
+function checkDraw(colorLocation, positionLocation, r, g, b, a) {
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ var width = 50;
+ var height = 50;
+
+ // Test several locations
+ wtu.checkCanvasRect(gl, 0, 0, width, 1, [0, 0, 0, 255],
+ "First line should be all black");
+ wtu.checkCanvasRect(gl, 20, 15, 10, 1, [r, g, b, a],
+ "Line 15 should be red for at least 10 rgba pixels starting 20 pixels in");
+ wtu.checkCanvasRect(gl, 0, height - 1, width, 0, [0, 0, 0, 255],
+ "Last line should be all black");
+
+ gl.disableVertexAttribArray(positionLocation);
+ gl.disableVertexAttribArray(colorLocation);
+}
+
+setBindLocations(2, 3);
+checkDraw(2, 3, 0, 255, 0, 255);
+
+setBindLocations(0, 3);
+gl.disableVertexAttribArray(0);
+gl.vertexAttrib4f(0, 1, 0, 0, 1);
+checkDraw(0, 3, 255, 0, 0, 255);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-attribute.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-attribute.html
new file mode 100644
index 0000000000..76dc422eae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-attribute.html
@@ -0,0 +1,85 @@
+<!--
+Copyright (c) 2019 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 getActiveAttrib conformance test.</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 id="example" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute $type attr0;
+void main()
+{
+ gl_Position = vec4(0, 0, 0, attr0$access);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+void main()
+{
+ gl_FragColor = vec4(0,1,0,1);
+}
+</script>
+<script>
+"use strict";
+description("Tests getActiveAttrib for various types");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+
+var tests = [
+{ glType: gl.FLOAT, size: 1, type: 'float', access: ''},
+{ glType: gl.FLOAT_VEC2, size: 1, type: 'vec2', access: '[1]'},
+{ glType: gl.FLOAT_VEC3, size: 1, type: 'vec3', access: '[2]'},
+{ glType: gl.FLOAT_VEC4, size: 1, type: 'vec4', access: '[3]'},
+{ glType: gl.FLOAT_MAT2, size: 1, type: 'mat2', access: '[1][1]'},
+{ glType: gl.FLOAT_MAT3, size: 1, type: 'mat3', access: '[2][2]'},
+{ glType: gl.FLOAT_MAT4, size: 1, type: 'mat4', access: '[3][3]'},
+];
+
+var source = document.getElementById('vshader').text;
+var fs = wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER);
+for (var tt = 0; tt < tests.length; ++tt) {
+ var t = tests[tt];
+ var vs = wtu.loadShader(
+ gl,
+ source.replace('$type', t.type).replace('$access', t.access),
+ gl.VERTEX_SHADER);
+ var program = wtu.setupProgram(gl, [vs, fs]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from setup");
+ var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
+ var found = false;
+ for (var ii = 0; ii < numAttribs; ++ii) {
+ var info = gl.getActiveAttrib(program, ii);
+ if (info.name == 'attr0') {
+ found = true;
+ assertMsg(info.type == t.glType,
+ "type must be " + wtu.glEnumToString(gl, t.glType) + " was " +
+ wtu.glEnumToString(gl, info.type));
+ assertMsg(info.size == t.size,
+ "size must be " + t.size + ' was ' + info.size);
+ }
+ }
+ if (!found) {
+ testFailed("attrib 'attr0' not found");
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-uniform.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-uniform.html
new file mode 100644
index 0000000000..295b5987cc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-uniform.html
@@ -0,0 +1,136 @@
+<!--
+Copyright (c) 2019 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 getActiveUniform conformance test.</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 id="example" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+void main()
+{
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform $type uniform0;
+void main()
+{
+ gl_FragColor = vec4(0,$access,0,1);
+}
+</script>
+<script id="fshaderA" type="x-shader/x-fragment">
+precision mediump float;
+uniform float uniform0;
+void main()
+{
+ gl_FragColor = vec4(0,uniform0,0,1);
+}
+</script>
+<script id="fshaderB" type="x-shader/x-fragment">
+precision mediump float;
+uniform float uniform0;
+uniform float uniform1;
+void main()
+{
+ gl_FragColor = vec4(0,uniform0,uniform1,1);
+}
+</script>
+<script>
+"use strict";
+description("Tests getActiveUniform for various types");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+
+var tests = [
+ { glType: gl.FLOAT, size: 1, type: 'float', access: 'uniform0'},
+ { glType: gl.FLOAT_VEC2, size: 1, type: 'vec2', access: 'uniform0[1]'},
+ { glType: gl.FLOAT_VEC3, size: 1, type: 'vec3', access: 'uniform0[2]'},
+ { glType: gl.FLOAT_VEC4, size: 1, type: 'vec4', access: 'uniform0[3]'},
+ { glType: gl.FLOAT_MAT2, size: 1, type: 'mat2', access: 'uniform0[1][1]'},
+ { glType: gl.FLOAT_MAT3, size: 1, type: 'mat3', access: 'uniform0[2][2]'},
+ { glType: gl.FLOAT_MAT3, size: 1, type: 'mat3', access: 'uniform0[2][2]'},
+ { glType: gl.FLOAT_MAT4, size: 1, type: 'mat4', access: 'uniform0[3][3]'},
+ { glType: gl.INT, size: 1, type: 'int', access: 'float(uniform0)'},
+ { glType: gl.INT_VEC2, size: 1, type: 'ivec2', access: 'float(uniform0[1])'},
+ { glType: gl.INT_VEC3, size: 1, type: 'ivec3', access: 'float(uniform0[2])'},
+ { glType: gl.INT_VEC4, size: 1, type: 'ivec4', access: 'float(uniform0[3])'},
+ { glType: gl.BOOL, size: 1, type: 'bool', access: 'float(uniform0)'},
+ { glType: gl.BOOL_VEC2, size: 1, type: 'bvec2', access: 'float(uniform0[1])'},
+ { glType: gl.BOOL_VEC3, size: 1, type: 'bvec3', access: 'float(uniform0[2])'},
+ { glType: gl.BOOL_VEC4, size: 1, type: 'bvec4', access: 'float(uniform0[3])'},
+ { glType: gl.SAMPLER_2D, size: 1, type: 'sampler2D', access: 'texture2D(uniform0, vec2(0,0)).x'},
+ { glType: gl.SAMPLER_CUBE, size: 1, type: 'samplerCube', access: 'textureCube(uniform0, vec3(0,1,0)).x'}
+];
+
+var vs = wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER);
+var source = document.getElementById('fshader').text;
+
+function createProgram(type, access) {
+ var fs = wtu.loadShader(
+ gl,
+ source.replace('$type', type).replace('$access', access),
+ gl.FRAGMENT_SHADER);
+ var program = wtu.setupProgram(gl, [vs, fs]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from setup");
+ return program;
+}
+
+for (var tt = 0; tt < tests.length; ++tt) {
+ var t = tests[tt];
+ var program = createProgram(t.type, t.access);
+ var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
+ var found = false;
+ for (var ii = 0; ii < numUniforms; ++ii) {
+ var info = gl.getActiveUniform(program, ii);
+ if (info.name == 'uniform0') {
+ found = true;
+ assertMsg(info.type == t.glType,
+ "type must be " + wtu.glEnumToString(gl, t.glType) + " was " +
+ wtu.glEnumToString(gl, info.type));
+ assertMsg(info.size == t.size,
+ "size must be " + t.size + ' was ' + info.size);
+ }
+ }
+ if (!found) {
+ testFailed("uniform 'uniform0' not found");
+ }
+}
+
+var p1 = wtu.setupProgram(gl, [vs, 'fshaderA']);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from program A");
+var p2 = wtu.setupProgram(gl, [vs, 'fshaderB']);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from program B");
+var l1 = gl.getUniformLocation(p1, 'uniform0');
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors getting location of uniform0 p1");
+var l2 = gl.getUniformLocation(p2, 'uniform0');
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors getting location of uniform0 p2");
+
+gl.useProgram(p2);
+gl.uniform1f(l2, 1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors setting uniform 0");
+gl.uniform1f(l1, 2);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "setting a uniform using a location from another program");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-getshadersource.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-getshadersource.html
new file mode 100644
index 0000000000..3461537d4b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-getshadersource.html
@@ -0,0 +1,39 @@
+<!--
+Copyright (c) 2019 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 getShaderSource conformance test.</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 id="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">abc//defNOTASCII</script>
+<script>
+"use strict";
+description("Tests that the source that goes into a shader is what comes out.");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var original = document.getElementById("vshader").text;
+var shader = gl.createShader(gl.VERTEX_SHADER);
+gl.shaderSource(shader, original);
+var source = gl.getShaderSource(shader);
+shouldBe("source", "original");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-shader-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-shader-test.html
new file mode 100644
index 0000000000..6566f77303
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-shader-test.html
@@ -0,0 +1,94 @@
+<!--
+Copyright (c) 2019 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 ShaderL Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<script id="vs" type="x-shader/x-fragment">
+attribute vec4 vPosition;
+varying vec2 texCoord;
+void main() {
+ gl_Position = vPosition;
+ texCoord = vPosition.xy * 0.5 + 0.5;
+}
+</script>
+<script id="fs-green" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragData[0] = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fs-red" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragData[0] = vec4(1, 0, 0, 1);
+}
+</script>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("This test checks a few things about WebGL Shaders.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking shaders.");
+
+ // Create the shader object
+ var shader = gl.createShader(desktopGL['GEOMETRY_SHADER_ARB']);
+ assertMsg(shader == null,
+ "should not be able to create GEOMETRY shader");
+
+ checkDeferredCompliation()
+}
+
+function checkDeferredCompliation() {
+ var vs = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vs, document.getElementById("vs").text);
+ gl.compileShader(vs);
+ var fs = gl.createShader(gl.FRAGMENT_SHADER);
+ // Compile the green shader
+ gl.shaderSource(fs, document.getElementById("fs-green").text);
+ gl.compileShader(fs);
+ // Load the red shader source but do NOT compile it
+ gl.shaderSource(fs, document.getElementById("fs-red").text);
+ var p = gl.createProgram();
+ gl.attachShader(p, vs);
+ gl.attachShader(p, fs);
+ gl.bindAttribLocation(p, 0, "vPosition");
+ gl.linkProgram(p);
+ gl.useProgram(p);
+ wtu.setupUnitQuad(gl, 0, 1);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/invalid-UTF-16.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/invalid-UTF-16.html
new file mode 100644
index 0000000000..238552a5e6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/invalid-UTF-16.html
@@ -0,0 +1,48 @@
+<!--
+Copyright (c) 2019 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">
+<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>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+"use strict";
+description('This test verifies that the internal conversion from UTF16 to UTF8 is robust to invalid inputs. Any DOM entry point which converts an incoming string to UTF8 could be used for this test.');
+
+var array = [];
+array.push(String.fromCharCode(0x48)); // H
+array.push(String.fromCharCode(0x69)); // i
+array.push(String.fromCharCode(0xd87e)); // Bogus
+var string = array.join('');
+
+// In order to make this test not depend on WebGL, the following were
+// attempted:
+// - Send a string to console.log
+// - Submit a mailto: form containing a text input with the bogus
+// string
+// The first code path does not perform a utf8 conversion of the
+// incoming string unless Console::shouldPrintExceptions() returns
+// true. The second seems to sanitize the form's input before
+// converting it to a UTF8 string.
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+var program = gl.createProgram();
+gl.bindAttribLocation(program, 0, string);
+testPassed("bindAttribLocation with invalid UTF-16 did not crash");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-handling.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-handling.html
new file mode 100644
index 0000000000..54138becf1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-handling.html
@@ -0,0 +1,142 @@
+<!--
+Copyright (c) 2019 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 Program Handling Conformance Test</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 a_position;
+ uniform vec4 u_color;
+ varying vec4 v_color;
+ void main()
+ {
+ v_color = u_color;
+ gl_Position = a_position;
+ }
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+ precision mediump float;
+ varying vec4 v_color;
+ void main()
+ {
+ gl_FragColor = v_color;
+ }
+</script>
+<script id="fshader-not-link" type="x-shader/x-fragment">
+ precision mediump float;
+ varying vec4 foo;
+ void main()
+ {
+ gl_FragColor = foo;
+ }
+</script>
+
+<canvas id="canvas" width="16" height="16"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+function compile(gl, shader, src) {
+ var shaderSource = document.getElementById(src).text;
+ gl.shaderSource(shader, shaderSource);
+ gl.compileShader(shader);
+}
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+}
+
+function testProgramInvalidation() {
+ debug('');
+ debug('== Testing invalidation of the current program ==');
+ var vs = wtu.loadShaderFromScript(gl, "vshader");
+ var fs = wtu.loadShaderFromScript(gl, "fshader");
+ var prg = wtu.createProgram(gl, vs, fs);
+ gl.useProgram(prg);
+ const positionLoc = gl.getAttribLocation(prg, 'a_position');
+ const colorLoc = gl.getUniformLocation(prg, 'u_color');
+
+ wtu.setupUnitQuad(gl, positionLoc);
+
+ debug("Draw red with valid program");
+ gl.uniform4fv(colorLoc, [1, 0, 0, 1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+
+ debug("Change fragment shader to one that will not link");
+ compile(gl, fs, "fshader-not-link");
+ debug("Draw orange");
+ gl.uniform4fv(colorLoc, [1, 127/255, 0, 1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 127, 0, 255], "should be orange");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors before relink");
+
+ debug("Try linking");
+ gl.linkProgram(prg);
+ assertMsg(gl.getProgramParameter(prg, gl.LINK_STATUS) == false, "link should fail");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after linkProgram");
+ debug("Attempt to draw green; because link failed, in WebGL, the draw should generate INVALID_OPERATION");
+ gl.uniform4fv(colorLoc, [0, 1, 0, 1]);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "because the current program has been invalidated, uniform* calls generate INVALID_OPERATION");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors before draw");
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "draw with invalidated program should fail");
+ wtu.checkCanvas(gl, [255, 127, 0, 255], "should still be orange");
+}
+
+function testProgramShaderRemoval() {
+ debug('');
+ debug('== Testing removal of shaders from the current program ==');
+ var vs = wtu.loadShaderFromScript(gl, "vshader");
+ var fs = wtu.loadShaderFromScript(gl, "fshader");
+ var prg = wtu.createProgram(gl, vs, fs);
+ gl.useProgram(prg);
+ const positionLoc = gl.getAttribLocation(prg, 'a_position');
+ const colorLoc = gl.getUniformLocation(prg, 'u_color');
+
+ wtu.setupUnitQuad(gl, positionLoc);
+
+ debug("Draw red with valid program");
+ gl.uniform4fv(colorLoc, [1, 0, 0, 1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+
+ debug("Detach and delete shaders");
+ gl.detachShader(prg, vs);
+ gl.detachShader(prg, fs);
+ gl.deleteShader(vs);
+ gl.deleteShader(fs);
+
+ debug("Draw blue to show even though shaders are gone program is still valid");
+ gl.uniform4fv(colorLoc, [0, 0, 1, 1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "should be blue");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+testProgramInvalidation();
+testProgramShaderRemoval();
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-infolog.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-infolog.html
new file mode 100644
index 0000000000..02fa19d912
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-infolog.html
@@ -0,0 +1,62 @@
+<!--
+Copyright (c) 2019 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 Program 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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script id="vertexShader" language="x-shader/x-vertex">
+void main()
+{
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader" language="x-shader/x-fragment">
+precision mediump float;
+void main()
+{
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+description('getProgramInfoLog should not return \\0');
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+}
+
+debug("");
+
+var program = wtu.loadProgramFromScript(gl, 'vertexShader', 'fragmentShader');
+var infolog = gl.getProgramInfoLog(program);
+if (infolog === '\0') {
+ testFailed("getProgramInfoLog should not return '\\0'");
+} else {
+ testPassed("getProgramInfoLog didn't return '\\0'");
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-test.html
new file mode 100644
index 0000000000..34ca68f1d7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/program-test.html
@@ -0,0 +1,406 @@
+<!--
+Copyright (c) 2019 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 Program Compiling/Linking Conformance Test</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 a_position;
+ void main()
+ {
+ gl_Position = a_position;
+ }
+</script>
+<script id="fshader-red" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(1, 0, 0, 1);
+ }
+</script>
+<script id="fshader-green" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+</script>
+<script id="fshader-settable" type="x-shader/x-fragment">
+ precision mediump float;
+ uniform vec4 u_color;
+ void main()
+ {
+ gl_FragColor = u_color;
+ }
+</script>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script type="application/javascript">
+var wtu = WebGLTestUtils;
+let gl;
+function go() {
+ description("Tests that program compiling/linking/using works correctly.");
+
+ debug("");
+ debug("Canvas.getContext");
+
+ gl = wtu.create3DContext("canvas");
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+
+ testPassed("context exists");
+
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ function doArraysHaveSameContents(a, b) {
+ var flags = [];
+ function hasUnusedValue(a, value) {
+ for (var ii = 0; ii < a.length; ++ii) {
+ if (a[ii] === value && !flags[ii]) {
+ flags[ii] = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ try {
+ if (a.length !== b.length) {
+ return false;
+ }
+ for (var ii = 0; ii < a.length; ii++) {
+ if (!hasUnusedValue(b, a[ii])) {
+ return false;
+ }
+ }
+ } catch (ex) {
+ return false;
+ }
+ return true;
+ }
+
+/////// Check compileShader() /////////////////////////////
+
+ var vs = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vs, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex; }");
+ gl.compileShader(vs);
+
+ assertMsg(gl.getShaderParameter(vs, gl.COMPILE_STATUS) == true,
+ "good vertex shader should compile");
+
+ // Verify that constants removed from the WebGL spec generate INVALID_ENUM errors
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point");
+ assertMsg(gl.getShaderParameter(vs, desktopGL['INFO_LOG_LENGTH']) === null, "invalid call to getShaderParameter should return null");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "INFO_LOG_LENGTH is not a valid argument to getShaderParameter in WebGL");
+ assertMsg(gl.getShaderParameter(vs, desktopGL['SHADER_SOURCE_LENGTH']) === null, "invalid call to getShaderParameter should return null");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "SHADER_SOURCE_LENGTH is not a valid argument to getShaderParameter in WebGL");
+
+ var vs2 = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vs2, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex * 0.5; }");
+ gl.compileShader(vs2);
+
+ assertMsg(gl.getShaderParameter(vs2, gl.COMPILE_STATUS) == true,
+ "good vertex shader #2 should compile");
+
+ var vsBad = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vsBad, "WILL NOT COMPILE;");
+ gl.compileShader(vsBad);
+
+ // GLSL 1.0.17 section 10.27. compile shader does not have to return failure.
+ //assertMsg(gl.getShaderParameter(vsBad, gl.COMPILE_STATUS) == false,
+ // "bad vertex shader should fail to compile");
+
+ var fs = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fs, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }");
+ gl.compileShader(fs);
+
+ assertMsg(gl.getShaderParameter(fs, gl.COMPILE_STATUS) == true,
+ "good fragment shader should compile");
+
+ var fs2 = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fs2, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor * 0.5; }");
+ gl.compileShader(fs2);
+
+ assertMsg(gl.getShaderParameter(fs2, gl.COMPILE_STATUS) == true,
+ "good fragment shader #2 should compile");
+
+ var fsBad = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fsBad, "WILL NOT COMPILE;");
+ gl.compileShader(fsBad);
+
+ // GLSL 1.0.17 section 10.27. compile shader does not have to return failure.
+ //assertMsg(gl.getShaderParameter(fsBad, gl.COMPILE_STATUS) == false,
+ // "bad fragment shader should fail to compile");
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point");
+
+/////// Check attachShader() /////////////////////////////
+
+ function checkAttachShader(already_attached_shaders, shader, expected_error_code, errmsg) {
+ var prog = gl.createProgram();
+ for (var i = 0; i < already_attached_shaders.length; ++i)
+ gl.attachShader(prog, already_attached_shaders[i]);
+ if(gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in attachShader()");
+ gl.attachShader(prog, shader);
+ wtu.glErrorShouldBe(gl, expected_error_code, errmsg);
+ }
+
+ checkAttachShader([], vs, gl.NO_ERROR, "attaching a vertex shader should succeed");
+ checkAttachShader([vs], vs, gl.INVALID_OPERATION,
+ "attaching an already attached vertex shader should generate INVALID_OPERATION");
+ checkAttachShader([], fs, gl.NO_ERROR, "attaching a fragment shader should succeed");
+ checkAttachShader([fs], fs, gl.INVALID_OPERATION,
+ "attaching an already attached fragment shader should generate INVALID_OPERATION");
+ checkAttachShader([vs], vs2, gl.INVALID_OPERATION,
+ "attaching shaders of the same type to a program should generate INVALID_OPERATION");
+ checkAttachShader([fs], fs2, gl.INVALID_OPERATION,
+ "attaching shaders of the same type to a program should generate INVALID_OPERATION");
+
+/////// Check detachShader() /////////////////////////////
+
+ function checkDetachShader(already_attached_shaders, shader, expected_error_code, errmsg) {
+ var prog = gl.createProgram();
+ for (var i = 0; i < already_attached_shaders.length; ++i)
+ gl.attachShader(prog, already_attached_shaders[i]);
+ if(gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in attachShader()");
+ gl.detachShader(prog, shader);
+ wtu.glErrorShouldBe(gl, expected_error_code, errmsg);
+ }
+
+ checkDetachShader([vs], vs, gl.NO_ERROR, "detaching a vertex shader should succeed");
+ checkDetachShader([fs], vs, gl.INVALID_OPERATION,
+ "detaching a not already attached vertex shader should generate INVALID_OPERATION");
+ checkDetachShader([fs], fs, gl.NO_ERROR, "detaching a fragment shader should succeed");
+ checkDetachShader([vs], fs, gl.INVALID_OPERATION,
+ "detaching a not already attached fragment shader should generate INVALID_OPERATION");
+
+/////// Check getAttachedShaders() /////////////////////////////
+
+ function checkGetAttachedShaders(shaders_to_attach, shaders_to_detach, expected_shaders, errmsg) {
+ prog = gl.createProgram();
+ for (var i = 0; i < shaders_to_attach.length; ++i)
+ gl.attachShader(prog, shaders_to_attach[i]);
+ if(gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in attachShader()");
+ for (var i = 0; i < shaders_to_detach.length; ++i)
+ gl.detachShader(prog, shaders_to_detach[i]);
+ if(gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in detachShader()");
+ assertMsg(doArraysHaveSameContents(gl.getAttachedShaders(prog), expected_shaders), errmsg);
+ shouldBe('gl.getProgramParameter(prog, gl.ATTACHED_SHADERS)', `${expected_shaders.length}`);
+ }
+ checkGetAttachedShaders([], [], [], "getAttachedShaders should return an empty list by default");
+ checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
+ checkGetAttachedShaders([fs, vs], [], [fs, vs],
+ "attaching some shaders should give the expected list");
+ checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it should leave an empty list");
+ checkGetAttachedShaders([fs, vs], [fs, vs], [],
+ "attaching some shaders and detaching them in same order should leave an empty list");
+ checkGetAttachedShaders([fs, vs], [vs, fs], [],
+ "attaching some shaders and detaching them in random order should leave an empty list");
+ checkGetAttachedShaders([fs, vs], [vs], [fs],
+ "attaching and detaching some shaders should leave the difference list");
+ checkGetAttachedShaders([fs, vs], [fs], [vs],
+ "attaching and detaching some shaders should leave the difference list");
+ checkGetAttachedShaders([fsBad], [], [fsBad],
+ "attaching a shader that failed to compile should still show it in the list");
+ checkGetAttachedShaders([fs, vsBad], [], [fs, vsBad],
+ "attaching shaders, including one that failed to compile, should still show the it in the list");
+
+/////// Check linkProgram() and useProgram /////////////////////////////
+
+ function checkLinkAndUse(shaders, deleteShaderAfterAttach, expected_status, testInvalidEnums, errmsg) {
+ var prog = gl.createProgram();
+ for (var i = 0; i < shaders.length; ++i) {
+ gl.attachShader(prog, shaders[i]);
+ if (deleteShaderAfterAttach)
+ gl.deleteShader(shaders[i]);
+ }
+ gl.bindAttribLocation(prog, 0, "aVertex");
+ gl.bindAttribLocation(prog, 1, "aColor");
+ gl.linkProgram(prog);
+ if (gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in linkProgram()");
+ assertMsg(gl.getProgramParameter(prog, gl.LINK_STATUS) == expected_status, errmsg);
+ var infolog = gl.getProgramInfoLog(prog);
+ if (gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in getProgramInfoLog()");
+ if (typeof(infolog) != "string")
+ assertMsg(false, "getProgramInfoLog() did not return a string");
+ if (expected_status == true && gl.getProgramParameter(prog, gl.LINK_STATUS) == false)
+ debug(infolog);
+ if (gl.getError() != gl.NO_ERROR)
+ assertMsg(false, "unexpected error in getProgramParameter()");
+
+ if (testInvalidEnums) {
+ // Verify that constants removed from the WebGL spec generate INVALID_ENUM errors
+ assertMsg(gl.getProgramParameter(prog, desktopGL['INFO_LOG_LENGTH']) === null, "invalid call to getProgramParameter should return null");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "INFO_LOG_LENGTH is not a valid argument to getProgramParameter in WebGL");
+ assertMsg(gl.getProgramParameter(prog, desktopGL['ACTIVE_ATTRIBUTE_MAX_LENGTH']) === null, "invalid call to getProgramParameter should return null");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "ACTIVE_ATTRIBUTE_MAX_LENGTH is not a valid argument to getProgramParameter in WebGL");
+ assertMsg(gl.getProgramParameter(prog, desktopGL['ACTIVE_UNIFORM_MAX_LENGTH']) === null, "invalid call to getProgramParameter should return null");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "ACTIVE_UNIFORM_MAX_LENGTH is not a valid argument to getProgramParameter in WebGL");
+ }
+
+ gl.useProgram(prog);
+ if (expected_status == true)
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program should succeed");
+ if (expected_status == false)
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
+ return prog;
+ }
+
+ var progGood1 = checkLinkAndUse([vs, fs], false, true, true, "valid program should link");
+ var progGood2 = checkLinkAndUse([vs, fs2], false, true, false, "valid program #2 should link");
+ var progBad1 = checkLinkAndUse([vs], false, false, false, "program with no fragment shader should fail to link");
+ var progBad2 = checkLinkAndUse([fs], false, false, false, "program with no vertex shader should fail to link");
+ var progBad3 = checkLinkAndUse([vsBad, fs], false, false, false, "program with bad vertex shader should fail to link");
+ var progBad4 = checkLinkAndUse([vs, fsBad], false, false, false, "program with bad fragment shader should fail to link");
+ var progBad5 = checkLinkAndUse([vsBad, fsBad], false, false, false, "program with bad shaders should fail to link");
+
+ gl.useProgram(progGood1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program shouldn't generate a GL error");
+
+ var vbuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
+ gl.bufferData(gl.ARRAY_BUFFER,
+ new Float32Array([
+ 0.0, 0.0, 0.0, 1.0,
+ 1.0, 0.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0]),
+ gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttrib3f(1, 1.0, 0.0, 0.0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point #2");
+
+ gl.useProgram(null);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawing with a null program should generate INVALID_OPERATION");
+
+ gl.useProgram(progGood1);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
+
+ gl.useProgram(progBad1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Try to use an invalid program should not change the current rendering state");
+
+ gl.useProgram(progGood2);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
+ gl.detachShader(progGood2, fs2);
+ gl.attachShader(progGood2, fsBad);
+ gl.linkProgram(progGood2);
+ assertMsg(gl.getProgramParameter(progGood2, gl.LINK_STATUS) == false,
+ "linking should fail with in-use formerly good program, with new bad shader attached");
+
+ // In WebGL, an unsuccessful link immediately invalidates the previous valid program.
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawing with a newly-invalidated program should generate INVALID_OPERATION");
+
+ gl.useProgram(progGood1);
+ gl.drawArrays(gl.TRIANGLES, 0, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
+
+ var progGood1 = checkLinkAndUse([vs, fs], true, true, false, "delete shaders after attaching them and before linking program should not affect linkProgram");
+ gl.useProgram(progGood1);
+ gl.drawArrays(gl.TRIANGLES, 0, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
+
+/////// Check deleteProgram() and deleteShader() /////////////////////////////
+
+ gl.useProgram(progGood1);
+ gl.deleteProgram(progGood1);
+ gl.drawArrays(gl.TRIANGLES, 0, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "delete the current program shouldn't change the current rendering state");
+
+ gl.linkProgram(progGood1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "The current program shouldn't be deleted");
+
+ var fs3 = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fs3, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }");
+ gl.compileShader(fs3);
+
+ assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
+ "good fragment shader should compile");
+
+ gl.deleteShader(fs3);
+ gl.compileShader(fs3);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "an unattached shader should be deleted immediately");
+
+ fs3 = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fs3, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }");
+ gl.compileShader(fs3);
+
+ assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
+ "good fragment shader should compile");
+
+ gl.detachShader(progGood1, fs);
+ gl.attachShader(progGood1, fs3);
+
+ gl.deleteShader(fs3);
+ gl.compileShader(fs3);
+ assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
+ "an attached shader shouldn't be deleted");
+
+ gl.useProgram(null);
+ gl.linkProgram(progGood1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked program should be deleted once it's no longer the current program");
+
+ gl.compileShader(fs3);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked shader should be deleted once all its attachments are removed");
+
+//////// Check linkProgram() with relinked program //////////
+ var vs = wtu.loadShaderFromScript(gl, "vshader");
+ var fs = wtu.loadShaderFromScript(gl, "fshader-red");
+ var prg = wtu.createProgram(gl, vs, fs);
+ gl.useProgram(prg);
+ var posLoc = gl.getAttribLocation(prg, "a_position");
+ wtu.setupUnitQuad(gl, posLoc);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+ gl.shaderSource(fs, wtu.getScript("fshader-green"));
+ gl.compileShader(fs);
+ gl.linkProgram(prg);
+ // Program should be new program at this point without calling useProgram
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+ var prg = wtu.setupProgram(gl, ["vshader", "fshader-settable"], ["a_position"]);
+ var colorLoc = gl.getUniformLocation(prg, "u_color");
+ gl.uniform4f(colorLoc, 1, 0, 0, 1);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+ gl.linkProgram(prg);
+ // Program's uniforms should be cleared at this point without calling useProgram
+ wtu.clearAndDrawUnitQuad(gl, [0, 255, 0, 255]);
+ wtu.checkCanvas(gl, [0, 0, 0, 0], "should be tranparent black");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+debug("");
+go();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/programs/use-program-crash-with-discard-in-fragment-shader.html b/dom/canvas/test/webgl-conf/checkout/conformance/programs/use-program-crash-with-discard-in-fragment-shader.html
new file mode 100644
index 0000000000..27dac9a9ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/programs/use-program-crash-with-discard-in-fragment-shader.html
@@ -0,0 +1,77 @@
+<!--
+Copyright (c) 2019 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 Program 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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script id="vertexShader" language="x-shader/x-vertex">
+attribute vec4 ATTR0;
+void main()
+{
+ gl_Position = ATTR0;
+}
+</script>
+<script id="fragmentShader" language="x-shader/x-fragment">
+precision mediump float;
+void main()
+{
+ float _Intensity = exp2(gl_FragCoord.w);
+ if (_Intensity < 0.5) {
+ discard;
+ }
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+description('Regression test for crash in Mac OS AMD OpenGL driver related to use of discard in fragment shader.<br><br>More specifically, triggering the crash seems to require examination of gl_FragCoord.w, use of exp2, and a call to discard in the fragment shader. Thanks to Sheheryar Zakaria and Michael Braithwaite at Turbulenz for the original test case.<br><a href="https://bugs.webkit.org/show_bug.cgi?id=73932">WebKit bug 73932</a><br>');
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+}
+
+debug("");
+
+var program = wtu.loadProgramFromScript(gl, 'vertexShader', 'fragmentShader');
+if (program) {
+ testPassed("Program linked successfully");
+} else {
+ testFailed("Program failed to link");
+}
+
+// Crash occurs here on affected machines
+gl.useProgram(program);
+
+// In some browsers, such as Chrome, the above crash only causes a
+// lost context event to be dispatched, and not synchronously. To verify
+// that everything worked, clear and read back the frame buffer.
+gl.clearColor(1.0, 0.0, 0.0, 1.0);
+gl.clear(gl.COLOR_BUFFER_BIT);
+wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 0, 255],
+ "Color should be red");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>