summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/attribs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/00_test_list.txt15
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-aliasing.html42
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-matrix.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html82
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-repeated.html68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib-update.html79
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib.html79
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-enable-vertex-attrib.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-matrix-attributes.html136
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-context-switch.html60
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-render.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html191
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-zero-issues.html131
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib.html28
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer-offsets.html190
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer.html171
16 files changed, 1510 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/00_test_list.txt
new file mode 100644
index 0000000000..317fe70233
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/00_test_list.txt
@@ -0,0 +1,15 @@
+--min-version 1.0.3 gl-bindAttribLocation-aliasing.html
+--min-version 1.0.3 gl-bindAttribLocation-matrix.html
+--min-version 1.0.4 gl-bindAttribLocation-nonexistent-attribute.html
+--min-version 1.0.4 gl-bindAttribLocation-repeated.html
+--min-version 1.0.2 gl-disabled-vertex-attrib.html
+--min-version 1.0.4 gl-disabled-vertex-attrib-update.html
+gl-enable-vertex-attrib.html
+--min-version 1.0.3 gl-matrix-attributes.html
+--max-version 1.9.9 gl-vertex-attrib.html
+gl-vertexattribpointer.html
+gl-vertexattribpointer-offsets.html
+--min-version 1.0.2 gl-vertex-attrib-render.html
+gl-vertex-attrib-zero-issues.html
+--min-version 1.0.4 gl-vertex-attrib-unconsumed-out-of-bounds.html
+--min-version 1.0.4 gl-vertex-attrib-context-switch.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-aliasing.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-aliasing.html
new file mode 100644
index 0000000000..aae54715dc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-aliasing.html
@@ -0,0 +1,42 @@
+<!--
+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>
+<script src="../../js/tests/gl-bindattriblocation-aliasing.js"></script>
+<title>bindAttribLocation with aliasing</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script id="vertexShader" type="text/something-not-javascript">
+precision mediump float;
+attribute $(type_1) a_1;
+attribute $(type_2) a_2;
+void main() {
+ gl_Position = $(gl_Position_1) + $(gl_Position_2);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies combinations of valid, active attribute types cannot be bound to the same location with bindAttribLocation.");
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false});
+var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
+
+runBindAttribLocationAliasingTest(wtu, gl, glFragmentShader, wtu.getScript('vertexShader'));
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-matrix.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-matrix.html
new file mode 100644
index 0000000000..ef5fd25b19
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-matrix.html
@@ -0,0 +1,98 @@
+<!--
+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>
+<title>WebGL bindAttribLocation with Matrix Attributes Conformance Test</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script>
+"use strict";
+description("This test verifies that vectors placed via bindAttribLocation right after matricies will fail if there is insufficient room for the matrix.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false});
+
+// Make sure we have room for at least a mat4.
+var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+debug('MAX_VERTEX_ATTRIBUTES is ' + maxAttributes);
+shouldBeGreaterThanOrEqual('maxAttributes', '4');
+
+var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
+
+// Given a matrix dimension, load a vertex shader with a matrix of that dimension
+// and a vector. Ensure that both the vector and matrix are active attributes.
+// Return the compiled vertex shader.
+function loadVertexShader(numMatrixDimensions) {
+ var strVertexShader =
+ 'attribute mat' + numMatrixDimensions + ' matrix;\n' +
+ 'attribute vec' + numMatrixDimensions + ' vector;\n' +
+ 'void main(void) { gl_Position = vec4(vector*matrix';
+ // Ensure the vec4 has the correct number of dimensions in order to be assignable
+ // to gl_Position.
+ for (var ii = numMatrixDimensions; ii < 4; ++ii) {
+ strVertexShader += ",0.0";
+ }
+ strVertexShader += ");}\n";
+ return wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
+}
+
+// Given a vertex shader, matrix location and vector location, create and link
+// a program with glFragmentShader and a vertex shader returned by loadVertexShader
+// attached. Bind the matrix to matrixLocation and the vector to vectorLocation.
+// Return whether the link was successful.
+function createAndLinkProgram(glVertexShader, matrixLocation, vectorLocation) {
+ var glProgram = gl.createProgram();
+ gl.bindAttribLocation(glProgram, matrixLocation, 'matrix');
+ gl.bindAttribLocation(glProgram, vectorLocation, 'vector');
+ gl.attachShader(glProgram, glVertexShader);
+ gl.attachShader(glProgram, glFragmentShader);
+ gl.linkProgram(glProgram);
+ return gl.getProgramParameter(glProgram, gl.LINK_STATUS);
+}
+
+// For each matrix dimension (mat2, mat3 and mat4)
+for (var mm = 2; mm <= 4; ++mm) {
+ debug('Testing ' + mm + ' dimensional matrices');
+ var glVertexShader = loadVertexShader(mm);
+ // Per the WebGL spec: "LinkProgram will fail if the attribute bindings assigned
+ // by bindAttribLocation do not leave enough space to assign a location for an
+ // active matrix attribute which requires multiple contiguous generic attributes."
+ // We will test this by placing the vector after the matrix attribute such that there
+ // is not enough room for the matrix. Vertify the link operation fails.
+
+ // Run the test for each available attribute slot. Go to maxAttributes-mm to leave enough room
+ // for the matrix itself. Leave another slot open for the vector following the matrix.
+ for (var pp = 0; pp <= maxAttributes - mm - 1; ++pp) {
+ // For each matrix dimension, bind the vector right after the matrix such that we leave
+ // insufficient room for the matrix. Verify doing this will fail the link operation.
+ for (var ll = 0; ll < mm; ++ll) {
+ var vectorLocation = pp + ll;
+ assertMsg(!createAndLinkProgram(glVertexShader, /*matrixLocation*/pp, vectorLocation),
+ "Matrix with location " + pp + " and vector with location " + vectorLocation + " should not link.");
+ }
+ // Ensure that once we have left enough room for the matrix, the program links successfully.
+ var vectorLocation = pp + ll;
+ assertMsg(createAndLinkProgram(glVertexShader, /*matrixLocation*/pp, vectorLocation),
+ "Matrix with location " + pp + " and vector with location " + vectorLocation + " should link.");
+ debug('');
+ }
+ 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/attribs/gl-bindAttribLocation-nonexistent-attribute.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html
new file mode 100644
index 0000000000..d6968b5ea4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html
@@ -0,0 +1,82 @@
+<!--
+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>
+<title>bindAttribLocation with nonexistent attribute name</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8"></canvas>
+<script id="vertexShader" type="text/something-not-javascript">
+precision highp float;
+attribute vec4 attr;
+void main() {
+ gl_Position = vec4(attr);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies that calling bindAttribLocation with a non-existent attribute location is fine.");
+
+// OpenGL ES 2.0.25 section 2.10 page 34.
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas);
+var fragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
+var vertexShader = wtu.loadShaderFromScript(gl, 'vertexShader', gl.VERTEX_SHADER);
+assertMsg(vertexShader != null, "Vertex shader compiled successfully.");
+
+var checkAttribLocation = function(program, expectedLocation) {
+ var location = gl.getAttribLocation(program, 'attr');
+ if (location != expectedLocation) {
+ testFailed('Unexpected location for attr: ' + location);
+ } else {
+ testPassed('Location of attr is: ' + location);
+ }
+}
+
+var testProgramNonExistentAttributeBound = function() {
+ var program = gl.createProgram();
+ gl.bindAttribLocation(program, 0, 'attr');
+ gl.bindAttribLocation(program, 1, 'bogus_attr');
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+ var linkStatus = gl.getProgramParameter(program, gl.LINK_STATUS);
+ expectTrue(linkStatus, "Link should succeed even if a non-existent attribute is bound.");
+ if (linkStatus) {
+ checkAttribLocation(program, 0);
+ }
+};
+var testProgramNonExistentAttributeOverlap = function() {
+ var program = gl.createProgram();
+ gl.bindAttribLocation(program, 1, 'attr');
+ gl.bindAttribLocation(program, 1, 'bogus_attr');
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+ var linkStatus = gl.getProgramParameter(program, gl.LINK_STATUS);
+ expectTrue(linkStatus, "Link should succeed even if a non-existent attribute is bound to the same location as an attribute that's present in the shader text.");
+ if (linkStatus) {
+ checkAttribLocation(program, 1);
+ }
+};
+
+testProgramNonExistentAttributeBound();
+testProgramNonExistentAttributeOverlap();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-repeated.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-repeated.html
new file mode 100644
index 0000000000..cfbea4fb63
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-repeated.html
@@ -0,0 +1,68 @@
+<!--
+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 Repeated BindAttribLocation 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="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(0.0,1.0,0.0,1.0);
+ }
+</script>
+
+<script>
+"use strict";
+description("Test repeated loading of programs involving bindAttribLocation calls");
+debug("Regression test for <a href='https://code.google.com/p/chromium/issues/detail?id=510637'>crbug.com/510637</a>");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var g_program;
+var g_attribLocation;
+function setup(attribIndex) {
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition'], [attribIndex]);
+ g_program = program;
+ g_attribLocation = attribIndex;
+ shouldBe("gl.getAttribLocation(g_program, 'vPosition')", "g_attribLocation");
+ return program;
+}
+
+var p0 = setup(0);
+var p3 = setup(3);
+var p1 = setup(1);
+// This call fails the getAttribLocation check on some drivers when
+// Chrome's program binary cache is enabled. On the affected drivers,
+// it returns the bound attribute location from the first binary
+// created. Swapping 0 and 1 above will cause it to return 1 rather
+// than 0.
+p3 = setup(3);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib-update.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib-update.html
new file mode 100644
index 0000000000..3ef12fb9aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib-update.html
@@ -0,0 +1,79 @@
+<!--
+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 Disabled Vertex Attrib Update 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="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+attribute float a_actualValue;
+uniform float u_expectedValue;
+varying float v_result;
+void main() {
+ gl_Position = a_position;
+ v_result = a_actualValue == u_expectedValue ? 1.0 : 0.0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying float v_result;
+void main() {
+ gl_FragColor = v_result > 0.0 ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script>
+// Tests that repeatedly updating a disabled vertex attribute works as expected.
+// This covers an ANGLE bug where dirty bits for current values were ignoring repeated updates.
+// Based on ANGLE test (VertexAttributeTest, DisabledAttribUpdates) from https://github.com/google/angle/blob/f7f0b8c3ab21c52cc2915048959361cf628d95f0/src/tests/gl_tests/VertexAttributeTest.cpp
+"use strict";
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example");
+
+var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+gl.useProgram(program);
+
+var positionLocation = gl.getAttribLocation(program, "a_position");
+var attribLoc = gl.getAttribLocation(program, "a_actualValue");
+gl.vertexAttribPointer(attribLoc, 1, gl.FLOAT, gl.FALSE, 0, 0);
+
+var uniLoc = gl.getUniformLocation(program, "u_expectedValue");
+
+var gridRes = 1;
+wtu.setupIndexedQuad(gl, gridRes, positionLocation);
+
+var testValues = [1, 2, 3, 4];
+for (var i = 0; i < testValues.length; ++i) {
+ var testValue = testValues[i];
+ gl.uniform1f(uniLoc, testValue);
+ gl.vertexAttrib1f(attribLoc, testValue);
+ wtu.clearAndDrawIndexedQuad(gl, gridRes);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+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/attribs/gl-disabled-vertex-attrib.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib.html
new file mode 100644
index 0000000000..f4f8997449
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib.html
@@ -0,0 +1,79 @@
+<!--
+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 Disabled Vertex Attrib 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="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+attribute vec4 a_color;
+varying vec4 v_color;
+bool isCorrectColor(vec4 v) {
+ return v.x == 0.0 && v.y == 0.0 && v.z == 0.0 && v.w == 1.0;
+}
+void main() {
+ gl_Position = a_position;
+ v_color = isCorrectColor(a_color) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 v_color;
+void main() {
+ gl_FragColor = v_color;
+}
+</script>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example");
+
+var numVertexAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+for (var ii = 0; ii < numVertexAttribs; ++ii) {
+ var colorLocation = (ii + 1) % numVertexAttribs;
+ var positionLocation = colorLocation ? 0 : 1;
+
+ if (positionLocation != 0) {
+ // We need to create a new 3d context for testing attrib 0
+ // since we've already effected attrib 0 on other tests.
+ gl = wtu.create3DContext();
+ }
+
+ debug("testing attrib: " + colorLocation);
+ var program = wtu.setupProgram(
+ gl,
+ ['vshader', 'fshader'],
+ ['a_position', 'a_color'],
+ [positionLocation, colorLocation]);
+ var gridRes = 1;
+ wtu.setupIndexedQuad(gl, gridRes, positionLocation);
+ wtu.clearAndDrawIndexedQuad(gl, gridRes);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+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/attribs/gl-enable-vertex-attrib.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-enable-vertex-attrib.html
new file mode 100644
index 0000000000..6425a33a7a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-enable-vertex-attrib.html
@@ -0,0 +1,51 @@
+<!--
+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 Enable Vertex Attrib 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>
+ <script src="../../js/tests/invalid-vertex-attrib-test.js"></script>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("tests that turning on attribs that have no buffer bound fails to draw");
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext("example");
+
+async function runInvalidAttribTests() {
+ const invalidAttribTestFn = createInvalidAttribTestFn(gl);
+
+ function drawArrays(gl) {
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ function drawElements(gl) {
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ }
+
+ await invalidAttribTestFn(drawArrays);
+ await invalidAttribTestFn(drawElements);
+ finishTest();
+}
+runInvalidAttribTests();
+
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-matrix-attributes.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-matrix-attributes.html
new file mode 100644
index 0000000000..fc7ab56b0f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-matrix-attributes.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">
+<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>
+<title>WebGL Matrix Attribute Conformance Test</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script>
+"use strict";
+description("This tests ensures that matrix attribute locations do not clash with other shader attributes.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false});
+
+// Make sure we have room for at least a mat4.
+var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+debug('MAX_VERTEX_ATTRIBUTES is ' + maxAttributes);
+shouldBeGreaterThanOrEqual('maxAttributes', '4');
+
+var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
+
+// prepareMatrixProgram creates a program with glFragmentShader as the fragment shader.
+// The vertex shader has numVector number of vectors and a matrix with numMatrixDimensions
+// dimensions at location numMatrixPosition in the list of attributes.
+// Ensures that every vector and matrix is used by the program.
+// Returns a valid program on successfull link; null on link failure.
+function prepareMatrixProgram(numVectors, numMatrixDimensions, numMatrixPosition) {
+ // Add the matrix and vector attribute declarations. Declare the vectors
+ // to have the same number of components as the matrix so we can perform
+ // operations on them when we assign to gl_Position later on.
+ var strVertexShader = "";
+ for (var ii = 1; ii <= numVectors; ++ii) {
+ if (numMatrixPosition === ii) {
+ strVertexShader += "attribute mat" + numMatrixDimensions + " matrix;\n";
+ }
+ strVertexShader += "attribute vec" + numMatrixDimensions + " vec_" + ii + ";\n";
+ }
+ // numMatrixPosition will be one past numVectors if the caller wants it to be
+ // last. Hence, we need this check outside the loop as well as inside.
+ if (numMatrixPosition === ii) {
+ strVertexShader += "attribute mat" + numMatrixDimensions + " matrix;\n";
+ }
+ // Add the body of the shader. Add up all of the vectors and multiply by the matrix.
+ // The operations we perform do not matter. We just need to ensure that all the vector and
+ // matrix attributes are used.
+ strVertexShader += "void main(void) { \ngl_Position = vec4((";
+ for (var ii = 1; ii <= numVectors; ++ii) {
+ if (ii > 1) {
+ strVertexShader += "+"
+ }
+ strVertexShader += "vec_" + ii;
+ }
+ strVertexShader += ")*matrix";
+ // Ensure the vec4 has the correct number of dimensions in order to be assignable
+ // to gl_Position.
+ for (var ii = numMatrixDimensions; ii < 4; ++ii) {
+ strVertexShader += ",0.0";
+ }
+ strVertexShader += ");}\n";
+ // Load the shader, attach it to a program, and return the link results
+ var glVertexShader = wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
+ var strTest = 'Load shader with ' + numVectors + ' vectors and 1 matrix';
+ if (glVertexShader !== null) {
+ testPassed(strTest);
+
+ var glProgram = gl.createProgram();
+ gl.attachShader(glProgram, glVertexShader);
+ gl.attachShader(glProgram, glFragmentShader);
+ gl.linkProgram(glProgram);
+ if (gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'linkProgram');
+ return glProgram;
+ }
+ } else {
+ testFailed(strTest);
+ }
+ return null;
+}
+
+debug('');
+
+// Test mat2, mat3 and mat4.
+for (var mm = 2; mm <= 4; ++mm) {
+ // Add maxAttribute number of attributes by saving enough room in the attribute
+ // list for a matrix of mm dimensions. All of the other attribute slots will be
+ // filled with vectors.
+ var numVectors = maxAttributes - mm;
+ for (var pp = 1; pp <= numVectors + 1; ++pp) {
+ debug('Test ' + mm + ' dimensional matrix at position ' + pp);
+ var glProgram = prepareMatrixProgram(numVectors, /*numMatrixDimensions*/mm, /*numMatrixPosition*/pp);
+ shouldBeNonNull('glProgram');
+ var attribMatrix = gl.getAttribLocation(glProgram, 'matrix');
+ debug('Matrix is at attribute location ' + attribMatrix);
+ shouldBeTrue('attribMatrix > -1');
+ // Per the spec, when an attribute is a matrix attribute, getAttribLocation
+ // returns the index of the first component of the matrix. The implementation must
+ // leave sufficient room for all the components. Here we ensure none of the vectors
+ // in the shader are assigned attribute locations that belong to the matrix.
+ for (var vv = 1; vv <= numVectors; ++vv) {
+ var strVector = 'vec_' + vv
+ var attribVector = gl.getAttribLocation(glProgram, strVector);
+ debug(strVector + ' is at attribute location ' + attribVector);
+ // Begin with the first attribute location where the matrix begins and ensure
+ // the vector's attribute location is not assigned to the matrix. Loop until
+ // we've checked all of the attribute locations that belong to the matrix.
+ for (var ii = attribMatrix; ii < attribMatrix + mm; ++ii) {
+ var testStr = strVector + ' attribute location: ' + attribVector + '. Should not be ' + ii;
+ if (attribVector !== ii) {
+ testPassed(testStr);
+ } else {
+ testFailed(testStr);
+ }
+ }
+ }
+ debug('');
+ }
+ 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/attribs/gl-vertex-attrib-context-switch.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-context-switch.html
new file mode 100644
index 0000000000..1db1c9a321
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-context-switch.html
@@ -0,0 +1,60 @@
+<!--
+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 Vertex Attrib Context Switch 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="one" width="50" height="50">
+</canvas>
+<canvas id="two" width="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("tests that vertex attrib value is preserved across context switches");
+var wtu = WebGLTestUtils;
+var positionLocation = 0;
+var colorLocation = 1;
+var gridRes = 1;
+
+var canvas1 = document.getElementById("one");
+var gl1 = wtu.create3DContext(canvas1);
+var program1 = wtu.setupSimpleVertexColorProgram(gl1, positionLocation, colorLocation);
+gl1.vertexAttrib4f(colorLocation, 0.0, 1.0, 0.0, 1.0);
+wtu.setupIndexedQuad(gl1, gridRes, positionLocation);
+wtu.clearAndDrawIndexedQuad(gl1, gridRes);
+wtu.checkCanvas(gl1, [0, 255, 0, 255], "should be green 1");
+
+var canvas2 = document.getElementById("two");
+var gl2 = wtu.create3DContext(canvas2);
+var program2 = wtu.setupSimpleVertexColorProgram(gl2, positionLocation, colorLocation);
+wtu.setupIndexedQuad(gl2, gridRes, positionLocation);
+wtu.clearAndDrawIndexedQuad(gl2, gridRes);
+wtu.checkCanvas(gl2, [0, 0, 0, 255], "should be black 1");
+
+wtu.checkCanvas(gl1, [0, 255, 0, 255], "should be green 2");
+
+wtu.clearAndDrawIndexedQuad(gl2, gridRes);
+wtu.checkCanvas(gl2, [0, 0, 0, 255], "should be black 2");
+
+wtu.clearAndDrawIndexedQuad(gl1, gridRes);
+wtu.checkCanvas(gl1, [0, 255, 0, 255], "should be green 3");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-render.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-render.html
new file mode 100644
index 0000000000..b10ebfe688
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-render.html
@@ -0,0 +1,89 @@
+<!--
+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>
+<script id='vshader' type='x-shader'>
+attribute vec4 a;
+attribute vec2 p;
+void main() {
+ gl_Position = vec4(p.x + a.x + a.y + a.z + a.w, p.y, 0.0, 1.0);
+}
+</script>
+<script id='fshader' type='x-shader'>
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+function checkRedPortion(gl, w, low, high) {
+ var buf = new Uint8Array(w * w * 4);
+ gl.readPixels(0, 0, w, w, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var i = 0;
+ for (; i < w; ++i) {
+ if (buf[i * 4 + 0] == 255 && buf[i * 4 + 1] == 0 && buf[i * 4 + 2] == 0 && buf[i * 4 + 3] == 255) {
+ break;
+ }
+ }
+ return low <= i && i <= high;
+}
+
+function runTest() {
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext('testbed', { preserveDrawingBuffer : true });
+ if (!gl) {
+ testFailed('could not create context');
+ return;
+ }
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['p', 'a'])
+
+ gl.enableVertexAttribArray(gl.p);
+ var pos = gl.createBuffer();
+ pos.type = gl.FLOAT;
+ pos.size = 2;
+ pos.num = 4;
+ gl.bindBuffer(gl.ARRAY_BUFFER, pos);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
+
+ gl.vertexAttribPointer(0, pos.size, pos.type, false, 0, 0);
+
+ debug('Test vertexAttrib[1..4]fv by setting different combinations that add up to 1.5 and use that when rendering.');
+ var vals = [[0.5], [0.1,0.4], [0.2,-0.2,0.5], [-1.0,0.3,0.2,2.0]];
+
+ for (var j = 0; j < 4; ++j) {
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl['vertexAttrib' + (j+1) + 'fv'](1, vals[j]);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, pos.num);
+
+ if (checkRedPortion(gl, 50, 50 * 0.7, 50 * 0.8)) {
+ testPassed('Attribute of size ' + (j+1) + ' was set correctly');
+ } else {
+ testFailed('Attribute of size ' + (j+1) + ' was not set correctly');
+ }
+ }
+}
+</script>
+</head>
+<body>
+<canvas id="testbed" width="50" height="50"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Verify that using constant attributes works.');
+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/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html
new file mode 100644
index 0000000000..f704dd643b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html
@@ -0,0 +1,191 @@
+<!--
+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 Unconsumed Vertex Attributes Out of Bounds 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="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+ void main() { }
+</script>
+
+<script id="vshader_attrib" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main() {
+ gl_Position = vPosition;
+ }
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+ void main() {
+ gl_FragColor = vec4(1);
+ }
+</script>
+
+<script>
+"use strict";
+description("Test that unconsumed vertex attributes are not read out of bounds");
+// Tests for http://crbug.com/756293 (driver crash on macOS)
+// and a class of similar bugs that could exist on other systems.
+
+var wtu = WebGLTestUtils;
+var contextVersion = wtu.getDefault3DContextVersion();
+var gl = wtu.create3DContext("example");
+var g_program;
+var g_attribLocation;
+
+var numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+var allocatedBuffer;
+var indexBuffer;
+
+function setupBuffers(numVerts) {
+ var vertices = new Float32Array(numVerts * 3);
+ allocatedBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, allocatedBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+
+ var indices = new Uint16Array(numVerts);
+ for (var ii = 0; ii < numVerts; ++ii) {
+ indices[ii] = ii;
+ }
+
+ indexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+}
+
+var progNoAttribs = wtu.setupProgram(gl, ['vshader', 'fshader'], [], []);
+var progAttrib1 = wtu.setupProgram(gl, ['vshader_attrib', 'fshader'], ['vPosition'], [1]);
+var progAttrib2 = wtu.setupProgram(gl, ['vshader_attrib', 'fshader'], ['vPosition'], [2]);
+setupBuffers(60000);
+
+var unallocatedBuffer = gl.createBuffer();
+var tests = [];
+
+debug("");
+debug("<u>Tests with one unconsumed attribute<u>");
+
+tests.push({
+ name: "drawArrays",
+ errors: gl.NO_ERROR,
+ draw: function() { gl.drawArrays(gl.TRIANGLES, 0, 3); }
+});
+tests.push({
+ name: "drawElements",
+ errors: gl.NO_ERROR,
+ draw: function() { gl.drawElements(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0); }
+});
+
+if (contextVersion >= 2) {
+ tests.push({
+ name: "drawArraysInstanced",
+ errors: gl.NO_ERROR,
+ draw: function() { gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 1); }
+ });
+ tests.push({
+ name: "drawElementsInstanced",
+ errors: gl.NO_ERROR,
+ draw: function() { gl.drawElementsInstanced(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0, 1); }
+ });
+ tests.push({
+ name: "drawRangeElements",
+ errors: gl.NO_ERROR,
+ draw: function() { gl.drawRangeElements(gl.TRIANGLES, 0, 60000, 60000, gl.UNSIGNED_SHORT, 0, 1); }
+ });
+}
+
+// Run tests
+
+// Bound forever
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+
+for (var attrib = 0; attrib < numAttribs; ++attrib) {
+ debug("Attrib " + attrib + " unconsumed");
+ for (var i = 0; i < tests.length; ++i) {
+ var test = tests[i];
+ gl.useProgram(progNoAttribs);
+
+ gl.enableVertexAttribArray(attrib);
+ gl.bindBuffer(gl.ARRAY_BUFFER, unallocatedBuffer);
+ gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
+
+ test.draw();
+
+ gl.disableVertexAttribArray(attrib);
+ wtu.glErrorShouldBe(gl, test.errors, test.name);
+ }
+}
+
+debug("");
+debug("<u>Tests with one consumed attribute and one unconsumed attribute<u>");
+
+var ext = gl.getExtension("ANGLE_instanced_arrays");
+if (!ext) {
+ debug("ANGLE_instanced_arrays not available - skipped");
+} else {
+ tests.push({
+ name: "drawArraysInstancedANGLE",
+ errors: gl.NO_ERROR,
+ draw: function() {
+ ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 3, 1);
+ }
+ });
+ tests.push({
+ name: "drawElementsInstancedANGLE",
+ errors: gl.NO_ERROR,
+ draw: function() {
+ ext.drawElementsInstancedANGLE(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0, 1);
+ }
+ });
+}
+
+// Note these don't trigger the macOS driver crash (http://crbug.com/756293)
+// but they still add potentially useful coverage.
+for (var attrib = 0; attrib < numAttribs; ++attrib) {
+ var consumedAttrib = attrib == 1 ? 2 : 1;
+ var prog = consumedAttrib == 1 ? progAttrib1 : progAttrib2;
+ debug("Attrib " + attrib +
+ " unconsumed (attrib " + consumedAttrib + " consumed)");
+
+ for (var i = 0; i < tests.length; ++i) {
+ var test = tests[i];
+ gl.useProgram(prog);
+
+ gl.enableVertexAttribArray(attrib);
+ gl.bindBuffer(gl.ARRAY_BUFFER, unallocatedBuffer);
+ gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
+
+ // Needed because ANGLE_instanced_arrays requires at least one consumed
+ // attribute to have divisor=0 (which is the default, so we don't need to
+ // call vertexAttribDivisorANGLE here).
+ gl.enableVertexAttribArray(consumedAttrib);
+ gl.bindBuffer(gl.ARRAY_BUFFER, allocatedBuffer);
+ gl.vertexAttribPointer(consumedAttrib, 3, gl.FLOAT, false, 0, 0);
+
+ test.draw();
+
+ gl.disableVertexAttribArray(attrib);
+ gl.disableVertexAttribArray(consumedAttrib);
+ wtu.glErrorShouldBe(gl, test.errors, test.name);
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-zero-issues.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-zero-issues.html
new file mode 100644
index 0000000000..9de9439911
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-zero-issues.html
@@ -0,0 +1,131 @@
+<!--
+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 Enable Vertex Attrib Zero 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="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(0.0,1.0,0.0,1.0);
+ }
+</script>
+
+<script>
+"use strict";
+description("Test some of the issues of the difference between attrib 0 on OpenGL vs WebGL");
+debug("");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var g_program;
+var g_attribLocation;
+function setup(attribIndex) {
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition'], [attribIndex]);
+ g_program = program;
+ g_attribLocation = attribIndex;
+ shouldBe("g_attribLocation", "gl.getAttribLocation(g_program, 'vPosition')");
+ return program;
+}
+
+function setupVerts(numVerts) {
+ var verts = [
+ 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
+ ];
+ var positions = new Float32Array(numVerts * 3);
+ var indices = new Uint16Array(numVerts);
+ for (var ii = 0; ii < numVerts; ++ii) {
+ var ndx = ii % 6;
+ var dst = ii * 3;
+ var src = ndx * 3;
+ for (var jj = 0; jj < 3; ++jj) {
+ positions[dst + jj] = verts[src + jj];
+ }
+ indices[ii] = ii;
+ }
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+ var indexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+}
+
+var p0 = setup(0);
+var p3 = setup(3);
+setupVerts(60000);
+
+for (var ii = 0; ii < 5; ++ii) {
+ // test drawing with attrib 0
+ gl.useProgram(p0);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawElements(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR,
+ "drawing using attrib 0 with 6 verts");
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
+ gl.disableVertexAttribArray(0);
+
+ // test drawing without attrib 0
+ gl.useProgram(p3);
+ gl.enableVertexAttribArray(3);
+ gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 60000);
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR,
+ "drawing using attrib 3 with 60000 verts");
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
+ gl.disableVertexAttribArray(3);
+
+ // This second test of drawing without attrib0 uncovered a bug in chrome
+ // where after the draw without attrib0 the attrib 0 emulation code disabled
+ // attrib 0 and it was never re-enabled so this next draw failed.
+ gl.useProgram(p3);
+ gl.enableVertexAttribArray(3);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawElements(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR,
+ "drawing using attrib 3 with 60000 verts");
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
+ gl.disableVertexAttribArray(3);
+}
+
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib.html
new file mode 100644
index 0000000000..aa69c5e7bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib.html
@@ -0,0 +1,28 @@
+<!--
+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 vertexAttrib 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>
+var contextVersion = 1;
+</script>
+<script src="../../js/tests/gl-vertex-attrib.js"></script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer-offsets.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer-offsets.html
new file mode 100644
index 0000000000..3cb8bd84a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer-offsets.html
@@ -0,0 +1,190 @@
+<!--
+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>vertexattribpointer offsets 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="50" height="50">
+There is supposed to be an example drawing here, but it's not important.
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+ <script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ precision mediump float;
+ uniform vec4 color;
+ void main()
+ {
+ gl_FragColor = color;
+ }
+ </script>
+
+ <script>
+ "use strict";
+ function init()
+ {
+ description("test vertexattribpointer offsets work");
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("example");
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
+
+ var tests = [
+ { data: new Float32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.FLOAT,
+ componentSize: 4,
+ normalize: false,
+ },
+ { data: new Uint16Array([ 0, 32767, 0, 32767, 0, 0, 0, 0, 0]),
+ type: gl.SHORT,
+ componentSize: 2,
+ normalize: true,
+ },
+ { data: new Uint16Array([ 0, 65535, 0, 65535, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_SHORT,
+ componentSize: 2,
+ normalize: true,
+ },
+ { data: new Uint16Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_SHORT,
+ componentSize: 2,
+ normalize: false,
+ },
+ { data: new Uint16Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.SHORT,
+ componentSize: 2,
+ normalize: false,
+ },
+ { data: new Uint8Array([ 0, 127, 0, 127, 0, 0, 0, 0, 0 ]),
+ type: gl.BYTE,
+ componentSize: 1,
+ normalize: true,
+ },
+ { data: new Uint8Array([ 0, 255, 0, 255, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_BYTE,
+ componentSize: 1,
+ normalize: true,
+ },
+ { data: new Uint8Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.BYTE,
+ componentSize: 1,
+ normalize: false,
+ },
+ { data: new Uint8Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_BYTE,
+ componentSize: 1,
+ normalize: false,
+ }
+ ];
+
+ if (wtu.getDefault3DContextVersion() >= 2) {
+ tests.push(...[
+ { data: new Int32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0]),
+ type: gl.INT,
+ componentSize: 4,
+ normalize: false,
+ },
+ { data: new Int32Array([ 0, 2147483647, 0, 2147483647, 0, 0, 0, 0, 0]),
+ type: gl.INT,
+ componentSize: 4,
+ normalize: true,
+ },
+ { data: new Uint32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0]),
+ type: gl.UNSIGNED_INT,
+ componentSize: 4,
+ normalize: false,
+ },
+ { data: new Uint32Array([ 0, 4294967295, 0, 4294967295, 0, 0, 0, 0, 0]),
+ type: gl.UNSIGNED_INT,
+ componentSize: 4,
+ normalize: true,
+ },
+ { data: new Uint16Array([ 0, 0b11110000000000, 0, 0b11110000000000, 0, 0, 0, 0, 0]),
+ type: gl.HALF_FLOAT,
+ componentSize: 2,
+ normalize: false,
+ },
+ { data: new Uint16Array([ 0, 0b11110000000000, 0, 0b11110000000000, 0, 0, 0, 0, 0]),
+ type: gl.HALF_FLOAT,
+ componentSize: 2,
+ normalize: false,
+ }
+ ]);
+ }
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+
+ var colorLoc = gl.getUniformLocation(program, "color");
+ var kNumVerts = 3;
+ var kNumComponents = 3;
+
+ var count = 0;
+ for (var tt = 0; tt < tests.length; ++tt) {
+ var test = tests[tt];
+ for (var oo = 0; oo < 3; ++oo) {
+ for (var ss = 0; ss < 3; ++ss) {
+ var offset = (oo + 1) * test.componentSize;
+ var color = (count % 2) ? [1, 0, 0, 1] : [0, 1, 0, 1];
+ var stride = test.componentSize * kNumComponents + test.componentSize * ss;
+ debug("");
+ debug("check with " + wtu.glEnumToString(gl, test.type) + " at offset: " + offset + " with stride:" + stride + " normalize: " + test.normalize);
+ gl.uniform4fv(colorLoc, color);
+ var data = new Uint8Array(test.componentSize * kNumVerts * kNumComponents + stride * (kNumVerts - 1));
+ var view = new Uint8Array(test.data.buffer);
+ var size = test.componentSize * kNumComponents;
+ for (var jj = 0; jj < kNumVerts; ++jj) {
+ var off1 = jj * size;
+ var off2 = jj * stride;
+ for (var zz = 0; zz < size; ++zz) {
+ data[off2 + zz] = view[off1 + zz];
+ }
+ }
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, data);
+ gl.vertexAttribPointer(0, 3, test.type, test.normalize, stride, offset);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ var buf = new Uint8Array(50 * 50 * 4);
+ gl.readPixels(0, 0, 50, 50, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+
+ var black = [0, 0, 0, 0];
+ var other = [color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255];
+ var otherMsg = "should be " + ((count % 2) ? "red" : "green")
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, black, "should be black", 0);
+ wtu.checkCanvasRect(gl, 0, 49, 1, 1, black, "should be black", 0);
+ wtu.checkCanvasRect(gl, 26, 40, 1, 1, other, otherMsg, 0);
+ wtu.checkCanvasRect(gl, 26, 27, 1, 1, other, otherMsg, 0);
+ wtu.checkCanvasRect(gl, 40, 27, 1, 1, other, otherMsg, 0);
+ ++count;
+ }
+ }
+ }
+ }
+
+ init();
+ var successfullyParsed = true;
+ </script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer.html b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer.html
new file mode 100644
index 0000000000..1276cec7c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer.html
@@ -0,0 +1,171 @@
+<!--
+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 vertexAttribPointer 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>
+"use strict";
+description("This test checks vertexAttribPointer behaviors in WebGL.");
+
+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 gl.vertexAttribPointer.");
+
+ if (!gl.FIXED) {
+ gl.FIXED = 0x140C;
+ }
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(0), gl.STATIC_DRAW);
+
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 4);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "vertexAttribPointer should fail if no buffer is bound and `offset` is non-zero.");
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "vertexAttribPointer should succeed if no buffer is bound and `offset` is zero.");
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+
+
+ if (wtu.getDefault3DContextVersion() < 2) {
+ gl.vertexAttribPointer(0, 1, gl.INT, 0, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
+ "vertexAttribPointer should not support INT");
+ gl.vertexAttribPointer(0, 1, gl.UNSIGNED_INT, 0, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
+ "vertexAttribPointer should not support UNSIGNED_INT");
+ }
+ gl.vertexAttribPointer(0, 1, gl.FIXED, 0, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
+ "vertexAttribPointer should not support FIXED");
+
+ var checkVertexAttribPointer = function(
+ gl, err, reason, size, type, normalize, stride, offset) {
+ gl.vertexAttribPointer(0, size, type, normalize, stride, offset);
+ var succeeded = (err == gl.NO_ERROR);
+ wtu.glErrorShouldBe(gl, err,
+ "gl.vertexAttribPointer(0, " + size +
+ ", gl." + wtu.glEnumToString(gl, type) +
+ ", " + normalize +
+ ", " + stride +
+ ", " + offset +
+ ") should " + (succeeded ? "succeed " : "fail ") + reason);
+ if (succeeded) {
+ shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_SIZE)', size.toString());
+ shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE)', 'gl.' + wtu.glEnumToString(gl, type));
+ shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED)', normalize.toString());
+ shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE)', stride.toString());
+ shouldBe('gl.getVertexAttribOffset(0, gl.VERTEX_ATTRIB_ARRAY_POINTER)', offset.toString());
+ }
+ }
+
+ var types = [
+ { type:gl.BYTE, bytesPerComponent: 1 },
+ { type:gl.UNSIGNED_BYTE, bytesPerComponent: 1 },
+ { type:gl.SHORT, bytesPerComponent: 2 },
+ { type:gl.UNSIGNED_SHORT, bytesPerComponent: 2 },
+ { type:gl.FLOAT, bytesPerComponent: 4 },
+ ];
+
+ if (wtu.getDefault3DContextVersion() >= 2) {
+ types.push(...[
+ { type:gl.INT, bytesPerComponent: 4 },
+ { type:gl.UNSIGNED_INT, bytesPerComponent: 4 },
+ { type:gl.HALF_FLOAT, bytesPerComponent: 2 },
+ { type:gl.INT_2_10_10_10_REV, bytesPerComponent: 4, minSize: 4 },
+ { type:gl.UNSIGNED_INT_2_10_10_10_REV, bytesPerComponent: 4, minSize: 4 },
+ ]);
+ }
+
+ for (var ii = 0; ii < types.length; ++ii) {
+ var info = types[ii];
+ debug("");
+ for (var size = 1; size <= 4; ++size) {
+ debug("");
+ debug("checking: " + wtu.glEnumToString(gl, info.type) + " with size " + size);
+ var bytesPerElement = size * info.bytesPerComponent;
+ var offsetSet = [
+ 0,
+ 1,
+ info.bytesPerComponent - 1,
+ info.bytesPerComponent,
+ info.bytesPerComponent + 1,
+ info.bytesPerComponent * 2];
+ for (var jj = 0; jj < offsetSet.length; ++jj) {
+ var offset = offsetSet[jj];
+ for (var kk = 0; kk < offsetSet.length; ++kk) {
+ var stride = offsetSet[kk];
+ var err = gl.NO_ERROR;
+ var reason = ""
+ if (offset % info.bytesPerComponent != 0) {
+ reason = "because offset is bad";
+ err = gl.INVALID_OPERATION;
+ }
+ if (stride % info.bytesPerComponent != 0) {
+ reason = "because stride is bad";
+ err = gl.INVALID_OPERATION;
+ }
+ if (size < info.minSize) {
+ reason = "because size < minSize";
+ err = gl.INVALID_OPERATION;
+ }
+ checkVertexAttribPointer(
+ gl, err, reason, size, info.type, false, stride, offset);
+ }
+ var stride = Math.floor(255 / info.bytesPerComponent) * info.bytesPerComponent;
+
+ if (offset == 0) {
+ checkVertexAttribPointer(
+ gl, size < info.minSize ? gl.INVALID_OPERATION : gl.NO_ERROR, "at stride limit",
+ size, info.type, false, stride, offset);
+ checkVertexAttribPointer(
+ gl, size < info.minSize ? [gl.INVALID_OPERATION, gl.INVALID_VALUE] : gl.INVALID_VALUE, "over stride limit",
+ size, info.type, false,
+ stride + info.bytesPerComponent, offset);
+ }
+ }
+ }
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>