summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/more/functions
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/more/functions')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBuffer.html48
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBufferBadArgs.html73
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindFramebufferLeaveNonZero.html29
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferData.html66
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferDataBadArgs.html58
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubData.html117
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubDataBadArgs.html79
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2D.html109
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2DBadArgs.html88
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2D.html121
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2DBadArgs.html96
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/deleteBufferBadArgs.html44
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawArrays.html110
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawElements.html122
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTests.html61
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTestsBadArgs.html87
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixels.html42
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixelsBadArgs.html113
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2D.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DBadArgs.html105
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTML.html149
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTMLBadArgs.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2D.html70
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DBadArgs.html114
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTML.html160
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTMLBadArgs.html83
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrix.html69
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrixBadArgs.html143
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformf.html74
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfArrayLen1.html100
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfBadArgs.html105
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformi.html74
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformiBadArgs.html101
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttrib.html121
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribBadArgs.html97
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointer.html85
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointerBadArgs.html71
37 files changed, 3300 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBuffer.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBuffer.html
new file mode 100644
index 0000000000..9011d76168
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBuffer.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testBindBufferARRAY_BUFFER = function(gl) {
+ var b = gl.createBuffer();
+ assert(gl.NO_ERROR == checkError(gl, "genBuffers"));
+ gl.bindBuffer(gl.ARRAY_BUFFER, b);
+ assert(gl.NO_ERROR == checkError(gl, "bindBuffer"));
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ assert(gl.NO_ERROR == checkError(gl, "bindBuffer 0"));
+ gl.deleteBuffer(b);
+ assert(gl.NO_ERROR == checkError(gl, "deleteBuffers"));
+}
+
+Tests.testBindBufferELEMENT_ARRAY_BUFFER = function(gl) {
+ var b = gl.createBuffer();
+ assert(gl.NO_ERROR == checkError(gl, "genBuffers"));
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, b);
+ assert(gl.NO_ERROR == checkError(gl, "bindBuffer"));
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ assert(gl.NO_ERROR == checkError(gl, "bindBuffer 0"));
+ gl.deleteBuffer(b);
+ assert(gl.NO_ERROR == checkError(gl, "deleteBuffers"));
+}
+
+</script>
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBufferBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBufferBadArgs.html
new file mode 100644
index 0000000000..09797cb3d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBufferBadArgs.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testBindBufferARRAY_BUFFER = function(gl) {
+ var b = gl.createBuffer();
+ assertOk("bind buffer", function(){gl.bindBuffer(gl.ARRAY_BUFFER, b)});
+ assertFail("bufferData to null buffer", function() {
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([10]), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([10]));
+ });
+ assertFail("bind to number", function(){
+ gl.bindBuffer(gl.ARRAY_BUFFER, 1000000000);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([10]), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([10]));
+ });
+ assertOk("bind to null", function(){gl.bindBuffer(gl.ARRAY_BUFFER, null)});
+ gl.deleteBuffer(b);
+}
+
+Tests.testBindBufferELEMENT_ARRAY_BUFFER = function(gl) {
+ var b = gl.createBuffer();
+ assertOk("bind buffer", function(){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, b)});
+ assertFail("bufferData to null buffer", function() {
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Float32Array([10]), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([10]));
+ });
+ assertFail("bind to number", function(){
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, 1000000000);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Float32Array([10]), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([10]));
+ });
+ assertOk("bind to null",
+ function(){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null)});
+ gl.deleteBuffer(b);
+}
+Tests.testBindBuffer = function(gl) {
+ assertFail("bind ARRAY_BUFFER to number",
+ function(){gl.bindBuffer(gl.ARRAY_BUFFER, 1);});
+ assertFail("bind ELEMENT_ARRAY_BUFFER to number",
+ function(){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, 1);});
+ assertFail("bind bad target",
+ function(){gl.bindBuffer(gl.FLOAT, 0);});
+ assertFail("bind ARRAY_BUFFER to string",
+ function(){gl.bindBuffer(gl.ARRAY_BUFFER, "foo");});
+ assertFail("bind ELEMENT_ARRAY_BUFFER to string",
+ function(){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, "foo");});
+}
+
+</script>
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindFramebufferLeaveNonZero.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindFramebufferLeaveNonZero.html
new file mode 100644
index 0000000000..1c0bab8e00
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindFramebufferLeaveNonZero.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<title>OpenGL for the web</title>
+
+<script type="application/javascript" src="../util.js"></script>
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+
+ <script type="application/javascript">
+Tests.message = "This was segfaulting when the GL context got GC'd (in glXDestroyContext)";
+Tests.testSeg = function () {
+ var canvas = document.getElementById('canvas');
+ var gl = getGLContext(canvas);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+}
+</script>
+
+</head><body>
+ <canvas id="canvas" width="400" height="400"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferData.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferData.html
new file mode 100644
index 0000000000..25d53e6b7e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferData.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var buf = gl.createBuffer();
+ var ebuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuf);
+ return [gl, buf, ebuf];
+}
+
+Tests.testBufferData = function(gl, buf, ebuf) {
+ var data = [0,0,0,0, 1,0,0,0, 0,1,0,0];
+ gl.bufferData(gl.ARRAY_BUFFER, 12, gl.STATIC_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([]), gl.STATIC_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STATIC_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STREAM_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STREAM_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.DYNAMIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.DYNAMIC_DRAW);
+
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(data), gl.STATIC_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(data), gl.STREAM_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(data), gl.DYNAMIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*2);
+ throwError(gl, "array bufferSubData");
+}
+Tests.testBufferDataElement = function(gl, buf, ebuf) {
+ var data = [0,0,0,0, 1,0,0,0, 0,1,0,0];
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.STATIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STATIC_DRAW);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.STREAM_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STREAM_DRAW);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.DYNAMIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_USAGE), gl.DYNAMIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE), 12*2);
+ throwError(gl, "element array bufferSubData");
+}
+
+Tests.endUnit = function(gl, buf, ebuf) {
+ gl.deleteBuffer(buf);
+ gl.deleteBuffer(ebuf);
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferDataBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferDataBadArgs.html
new file mode 100644
index 0000000000..4a473be0d8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferDataBadArgs.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var buf = gl.createBuffer();
+ var ebuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuf);
+ return [gl, buf, ebuf];
+}
+
+Tests.testBufferData = function(gl) {
+ assertOk("zero size data",
+ function(){gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(0), gl.STATIC_DRAW);});
+ assertFail("bad target",
+ function(){gl.bufferData(gl.TEXTURE_2D, new Float32Array([1,2,3]), gl.STATIC_DRAW);});
+// assertFail("array for data",
+// function(){gl.bufferData(gl.ARRAY_BUFFER, [1,2,3], gl.STATIC_DRAW);});
+ assertFail("bad usage",
+ function(){gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,2,3]), gl.TEXTURE_2D);});
+ assertFail("null data",
+ function(){gl.bufferData(gl.ARRAY_BUFFER, null, gl.STATIC_DRAW);});
+ assertFail("undefined data",
+ function(){gl.bufferData(gl.ARRAY_BUFFER, undefined, gl.STATIC_DRAW);});
+ assertOk(function(){gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Float32Array([1,2,3]), gl.STATIC_DRAW);});
+ throwError(gl, 'bufferData');
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ assertFail(function(){gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,2,3]), gl.STATIC_DRAW);});
+ throwError(gl, 'bufferData');
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ assertFail(function(){gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([1,2,3]), gl.STATIC_DRAW);});
+ throwError(gl, 'bufferData');
+}
+
+Tests.endUnit = function(gl, buf, ebuf) {
+ gl.deleteBuffer(buf);
+ gl.deleteBuffer(ebuf);
+}
+
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubData.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubData.html
new file mode 100644
index 0000000000..df03cf2835
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubData.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = getGLContext(canvas);
+ var buf = gl.createBuffer();
+ var ebuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuf);
+ return [gl, buf, ebuf];
+}
+
+Tests.testBufferSubData = function(gl, buf, ebuf) {
+ var data = [0,0,0,0, 1,0,0,0, 0,1,0,0];
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3,4]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Float32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 32, new Float32Array([1,1,1,1]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STATIC_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STREAM_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Float32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3,4]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STREAM_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Float32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3,4]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Int32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Int16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Int8Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint8Array([1,1,1,1]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.DYNAMIC_DRAW);
+
+ gl.bufferData(gl.ARRAY_BUFFER, 12, gl.STATIC_DRAW);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STATIC_DRAW);
+
+ gl.bufferData(gl.ARRAY_BUFFER, 12*4, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3,4]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Float32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 32, new Float32Array([1,1,1,1]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STATIC_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, 12*4, gl.STREAM_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Float32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3,4]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.STREAM_DRAW);
+ gl.bufferData(gl.ARRAY_BUFFER, 12*4, gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Float32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3,4]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Int32Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Int16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Int8Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint8Array([1,1,1,1]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*4);
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE), gl.DYNAMIC_DRAW);
+
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(data), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Uint16Array([1,2,3,4]));
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(data), gl.STREAM_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Uint16Array([1,2,3,4]));
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(data), gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Uint16Array([1,2,3,4]));
+ assertEquals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), 12*2);
+ throwError(gl, "array bufferSubData");
+}
+Tests.testBufferSubDataElement = function(gl, buf, ebuf) {
+ var data = [0,0,0,0, 1,0,0,0, 0,1,0,0];
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([1,2,3,4]));
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.STREAM_DRAW);
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([1,2,3,4]));
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 16, new Uint16Array([1,1,1,1]));
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([1,2,3,4]));
+ assertEquals(gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE), 12*2);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(data), gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 4, new Uint8Array([1,1,1,1]));
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint8Array([1,2,3,4]));
+ assertEquals(gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE), 12);
+ throwError(gl, "element array bufferSubData");
+}
+
+Tests.endUnit = function(gl, buf, ebuf) {
+ gl.deleteBuffer(buf);
+ gl.deleteBuffer(ebuf);
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubDataBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubDataBadArgs.html
new file mode 100644
index 0000000000..a12adf8ff8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubDataBadArgs.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var buf = gl.createBuffer();
+ var ebuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuf);
+ return [gl, buf, ebuf];
+}
+
+Tests.testBufferData = function(gl) {
+ var data = [0,0,0,0, 1,0,0,0, 0,1,0,0];
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STREAM_DRAW);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.STREAM_DRAW);
+ assertOk("zero length data",
+ function(){gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(0));});
+ assertFail("number for data",
+ function(){gl.bufferSubData(gl.ARRAY_BUFFER, 0, 12);});
+ assertFail("bad target",
+ function(){gl.bufferSubData(gl.TEXTURE_2D, 0, new Float32Array([1,2,3]));});
+ assertFail("array for data",
+ function(){gl.bufferSubData(gl.ARRAY_BUFFER, 0, [1,2,3]);});
+ assertOk("floats in element buffer",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Float32Array([1,2,3]));});
+ assertFail("negative offset",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, -1, new Uint16Array([1,2,3]));});
+ assertFail("offset out of range",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 24, new Uint16Array([1,2,3]));});
+ assertFail("offset out of range",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 2400000, new Uint16Array([1,2,3]));});
+ assertFail("offset out of range",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 19, new Uint16Array([1,2,3]));});
+ assertFail("data too large",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array(data.concat([1])));});
+ assertOk("offset + data.length = end",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 18, new Uint16Array([1,2,3]));});
+ assertOk("offset Infinity",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, Infinity, new Uint16Array([1,2,3]));});
+ assertOk("offset -Infinity",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, -Infinity, new Uint16Array([1,2,3]));});
+ assertOk("offset NaN",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, NaN, new Uint16Array([1,2,3]));});
+ assertOk("good args",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([1,2,3]));});
+ throwError(gl, 'bufferData0');
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ assertFail("setting buffer 0",
+ function(){gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array([1,2,3]));});
+ throwError(gl, 'bufferData1');
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ assertFail("setting buffer 0",
+ function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([1,2,3]));});
+ throwError(gl, 'bufferData2');
+}
+
+Tests.endUnit = function(gl, buf, ebuf) {
+ gl.deleteBuffer(buf);
+ gl.deleteBuffer(ebuf);
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2D.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2D.html
new file mode 100644
index 0000000000..8aaebf396d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2D.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var texCubeMap = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex, texCubeMap) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.deleteTexture(tex);
+ gl.deleteTexture(texCubeMap);
+}
+
+Tests.testTexImage2D = function(gl) {
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,1,1,0);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,2,1,0);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,1,2,0);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,16,16,0);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 15,15,1,1,0);
+ var valid_targets = [
+ gl.TEXTURE_2D,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ valid_targets.forEach(function(t) {
+ assertOk(function(){gl.copyTexImage2D(t, 0, gl.RGBA, 0,0,1,1,0);});
+ });
+}
+Tests.testRoundtrip = function(gl) {
+ var sh = new Filter(gl, 'identity-flip-vert', 'identity-frag');
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var buf = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ assertEquals([255,0,0,255], [buf[0], buf[1], buf[2], buf[3]]);
+ // red texture
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,16,16,0);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.clearColor(0.0, 0.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ // blue framebuffer
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ assertEquals([0,0,255,255], [buf[0], buf[1], buf[2], buf[3]]);
+ sh.apply(); // paint it with texture
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ assertEquals([255,0,0,255], [buf[0], buf[1], buf[2], buf[3]]);
+ sh.destroy();
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="identity-flip-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, 0.0, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="identity-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform sampler2D Texture;
+
+varying vec4 texCoord0;
+void main()
+{
+ vec4 c = texture2D(Texture, texCoord0.st);
+ gl_FragColor = c;
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2DBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2DBadArgs.html
new file mode 100644
index 0000000000..802fbc971f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2DBadArgs.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+}
+
+Tests.testTexImage2D = function(gl) {
+ assertOk("height > backHeight", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 17,1,0);
+ });
+ assertOk("width > backWidth", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 1,17,0);
+ });
+ assertOk("x + width > backWidth", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16,0, 1,1,0);
+ });
+ assertOk("y + height > backHeight", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,16, 1,1,0);
+ });
+ assertOk("Negative X", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, -1,0, 1,1,0);
+ });
+ assertOk("Negative Y", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,-1, 1,1,0);
+ });
+ assertFail("Negative height", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, -1,1,0);
+ });
+ assertFail("Negative width", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 1,-1,0);
+ });
+ assertFail("Non 0 border", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 1,1,1);
+ });
+ assertFail("Negative border",function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 1,1,-1);
+ });
+ assertOk("Good Args", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 16,16,0);
+ });
+ assertFail("NPOT texture to > level 0", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 1, gl.RGBA, 0,0, 15,16,0);
+ });
+ assertFail("Bad target", function(){
+ gl.copyTexImage2D(gl.FLOAT, 0, gl.RGBA, 0,0, 16,16,0);
+ });
+ assertFail("Bad internal format", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.FLOAT, 0,0, 16,16,0);
+ });
+ assertFail("Negative level", function(){
+ gl.copyTexImage2D(gl.TEXTURE_2D, -1, gl.RGBA, 0,0, 16,16,0);
+ });
+}
+
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2D.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2D.html
new file mode 100644
index 0000000000..82262e3d68
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2D.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var texCubeMap = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex,texCubeMap) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.deleteTexture(tex);
+ gl.deleteTexture(texCubeMap);
+}
+
+
+Tests.testTexImage2D = function(gl) {
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,16,16,0);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,1,1);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,2,1);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,1,2);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0,16,16);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 15,15,1,1);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 1,1, 0,0,15,15);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 15,15, 0,0,1,1);
+ var valid_targets = [
+ gl.TEXTURE_2D,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ valid_targets.forEach(function(t) {
+ assertOk(function(){
+ gl.copyTexImage2D(t, 0, gl.RGBA, 0,0,1,1,0);
+ gl.copyTexSubImage2D(t, 0, 0,0,0,0,1,1);
+ });
+ });
+}
+Tests.testRoundtrip = function(gl) {
+ var sh = new Filter(gl, 'identity-flip-vert', 'identity-frag');
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var buf = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ assertEquals([255,0,0,255], [buf[0], buf[1], buf[2], buf[3]]);
+ // red texture
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, document.getElementById('gl'));
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0,0,0,16,16);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.clearColor(0.0, 0.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ // blue framebuffer
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ assertEquals([0,0,255,255], [buf[0], buf[1], buf[2], buf[3]]);
+ sh.apply(); // paint with texture
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ assertEquals([255,0,0,255], [buf[0], buf[1], buf[2], buf[3]]);
+ sh.destroy();
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="identity-flip-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, 0.0, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="identity-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform sampler2D Texture;
+
+varying vec4 texCoord0;
+void main()
+{
+ vec4 c = texture2D(Texture, texCoord0.st);
+ gl_FragColor = c;
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2DBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2DBadArgs.html
new file mode 100644
index 0000000000..a170c6c78e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2DBadArgs.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+}
+
+Tests.testTexImage2D = function(gl) {
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0, 16,16, 0);
+ assertGLError(gl, gl.INVALID_VALUE, "width > dst tex width", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0, 17,1);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "height > dst tex height", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0, 1,17);
+ });
+ // The spec says the source image dimensions can be out of range.
+ assertOk("x > dst tex width", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 16,0, 1,1);
+ });
+ assertOk("y > dst tex width", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,16, 1,1);
+ });
+ assertOk("x < 0", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, -1,0, 1,1);
+ });
+ assertOk("y < 0", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,-1, 1,1);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "width < 0", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0, -1,1);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "height < 0", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0, 1,-1);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "xoffset < 0", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, -1,0, 0,0, 16,16);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "yoffset < 0", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,-1, 0,0, 16,16);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "dimension out of range", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 4,0, 0,0, 16,16);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "dimension out of range", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,4, 0,0, 16,16);
+ });
+ assertOk("x < 0 full width", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, -1,0, 16,16);
+ });
+ assertOk("y < 0 full height", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,-1, 16,16);
+ });
+ assertOk(function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, 0,0, 16,16);
+ });
+ assertGLError(gl, gl.INVALID_ENUM, "bad target", function(){
+ gl.copyTexSubImage2D(gl.FLOAT, 0, 0,0, 0,0, 16,16);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "", function(){
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, -1, 0,0, 0,0, 16,16);
+ });
+}
+
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/deleteBufferBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/deleteBufferBadArgs.html
new file mode 100644
index 0000000000..a373448631
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/deleteBufferBadArgs.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = getGLContext(canvas);
+ return [gl];
+}
+
+Tests.testDeleteBuffer = function(gl) {
+ assertThrowNoGLError(gl, "number ", function(){ gl.deleteBuffer(1); });
+ assertGLError(gl, gl.NO_ERROR, "null", function(){ gl.deleteBuffer(null); });
+ assertThrowNoGLError(gl, "0", function(){ gl.deleteBuffer(0); });
+ assertThrowNoGLError(gl, "false", function(){ gl.deleteBuffer(false); });
+ assertThrowNoGLError(gl, "true", function(){ gl.deleteBuffer(true); });
+ assertThrowNoGLError(gl, "{}", function(){ gl.deleteBuffer({}); });
+ var tex = gl.createTexture();
+ assertThrowNoGLError(gl, "tex as buf", function(){ gl.deleteBuffer(tex); });
+ var buf = gl.createBuffer();
+ assertOk(function(){ gl.deleteBuffer(buf); });
+ assertOk(function(){ gl.deleteBuffer(buf); });
+ assertOk(function(){ gl.deleteBuffer(buf); });
+ assertOk(function(){ gl.deleteTexture(tex); });
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawArrays.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawArrays.html
new file mode 100644
index 0000000000..7fdefbb636
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawArrays.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+var verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0];
+var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0];
+var texcoords = [0.0,0.0, 1.0,0.0, 0.0,1.0];
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var prog = new Shader(gl, 'vert', 'frag');
+ prog.use();
+ var sh = prog.shader.program;
+// log(gl.getShaderInfoLog(prog.shaders[1]));
+ var v = gl.getAttribLocation(sh, 'Vertex');
+ var n = gl.getAttribLocation(sh, 'Normal');
+ var t = gl.getAttribLocation(sh, 'Tex');
+ return [gl,prog,v,n,t];
+}
+
+Tests.setup = function(gl, prog, v,n,t) {
+ assert(0 == gl.getError());
+ return [gl, prog, v,n,t];
+}
+Tests.teardown = function(gl, prog, v,n,t) {
+ gl.disableVertexAttribArray(v);
+ gl.disableVertexAttribArray(n);
+ gl.disableVertexAttribArray(t);
+}
+
+Tests.endUnit = function(gl, prog, v,n,t) {
+ prog.destroy();
+}
+
+Tests.testDrawArraysVBO = function(gl, prog, v,n,t) {
+ var vbo = new VBO(gl, {size:3, data:Quad.vertices});
+ vbo.draw(v);
+ assert(0 == checkError(gl, "vbo.draw"));
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 5, 1);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 6);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 1, 5);});
+ vbo.destroy();
+ assert(0 == checkError(gl, "vbo.destroy"));
+}
+
+Tests.testDrawArraysVBOMulti = function(gl, prog, v,n,t) {
+ // creates VBOs for the quad arrays, binds them with
+ // vertexAttribPointer and calls drawArrays
+ var vbo = new VBO(gl,
+ {size:3, data:Quad.vertices},
+ {size:3, data:Quad.normals},
+ {size:2, data:Quad.texcoords});
+ vbo.draw(v, n, t);
+ assert(0 == checkError(gl, "vbo.draw"));
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 5, 1);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 6);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 1, 5);});
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo.vbos[1]);
+ gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 5, 1);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 6);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 1, 5);});
+ vbo.destroy();
+ assert(0 == checkError(gl, "vbo.destroy"));
+}
+
+
+</script>
+<script id="vert" type="x-shader/x-vertex">
+ attribute vec3 Vertex;
+ attribute vec3 Normal;
+ attribute vec2 Tex;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ gl_Position = vec4(Vertex * Normal, 1.0);
+ texCoord0 = vec4(Tex,0.0,0.0) + gl_Position;
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+ precision mediump float;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ vec4 c = texCoord0;
+ gl_FragColor = c;
+ }
+</script>
+
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawElements.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawElements.html
new file mode 100644
index 0000000000..f0c3bb3d27
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawElements.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+var verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0];
+var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0];
+var texcoords = [0.0,0.0, 1.0,0.0, 0.0,1.0];
+var indices = [0,1,2]
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var prog = new Shader(gl, 'vert', 'frag');
+ prog.use();
+ var sh = prog.shader.program;
+ var v = gl.getAttribLocation(sh, 'Vertex');
+ var n = gl.getAttribLocation(sh, 'Normal');
+ var t = gl.getAttribLocation(sh, 'Tex');
+ return [gl,prog,v,n,t];
+}
+
+Tests.setup = function(gl, prog, v,n,t) {
+ assert(0 == gl.getError());
+ return [gl, prog, v,n,t];
+}
+Tests.teardown = function(gl, prog, v,n,t) {
+ gl.disableVertexAttribArray(v);
+ gl.disableVertexAttribArray(n);
+ gl.disableVertexAttribArray(t);
+}
+
+Tests.endUnit = function(gl, prog, v,n,t) {
+ prog.destroy();
+}
+
+Tests.testDrawElementsVBO = function(gl, prog, v,n,t) {
+ var vbo = new VBO(gl,
+ {size:3, data:Quad.vertices},
+ {elements:true, data:Quad.indices});
+ vbo.draw(v);
+ assert(gl.NO_ERROR == checkError(gl, "vbo.draw"));
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 5, gl.UNSIGNED_SHORT, 1*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 0, gl.UNSIGNED_SHORT, 2*1);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 1, gl.UNSIGNED_SHORT, 5*2);});
+ vbo.destroy();
+ assert(gl.NO_ERROR == checkError(gl, "vbo.destroy"));
+}
+
+Tests.testDrawElementsVBOMulti = function(gl, prog, v,n,t) {
+ // creates VBOs for the quad arrays, binds them with
+ // vertexAttribPointer and calls drawElements
+ var vbo = new VBO(gl,
+ {size:3, data:Quad.vertices},
+ {size:3, data:Quad.normals},
+ {size:2, data:Quad.texcoords},
+ {elements:true, data:Quad.indices});
+ vbo.draw(v, n, t);
+ assert(gl.NO_ERROR == checkError(gl, "vbo.draw"));
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 5, gl.UNSIGNED_SHORT, 1*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 0, gl.UNSIGNED_SHORT, 2*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 1, gl.UNSIGNED_SHORT, 5*2);});
+ assertGLError(gl, gl.INVALID_OPERATION, "count + offset out of range",
+ function(){gl.drawElements(gl.TRIANGLES, 1, gl.UNSIGNED_SHORT, 6*2);});
+ assertGLError(gl, gl.INVALID_OPERATION, "count + offset out of range 2",
+ function(){gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 1*2);});
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo.vbos[1]);
+ gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 5, gl.UNSIGNED_SHORT, 1*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 0, gl.UNSIGNED_SHORT, 2*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0*2);});
+ assertOk(function(){gl.drawElements(gl.TRIANGLES, 1, gl.UNSIGNED_SHORT, 5*2);});
+ assertGLError(gl, gl.INVALID_OPERATION, "count + offset out of range 3",
+ function(){gl.drawElements(gl.TRIANGLES, 1, gl.UNSIGNED_SHORT, 6*2);});
+ assertGLError(gl, gl.INVALID_OPERATION, "count + offset out of range 4",
+ function(){gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 1*2);});
+ vbo.destroy();
+ assert(gl.NO_ERROR == checkError(gl, "vbo.destroy"));
+}
+
+
+</script>
+<script id="vert" type="x-shader/x-vertex">
+ attribute vec3 Vertex;
+ attribute vec3 Normal;
+ attribute vec2 Tex;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ gl_Position = vec4(Vertex * Normal, 1.0);
+ texCoord0 = vec4(Tex,0.0,0.0) + gl_Position;
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+ precision mediump float;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ vec4 c = texCoord0;
+ gl_FragColor = c;
+ }
+</script>
+
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTests.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTests.html
new file mode 100644
index 0000000000..54c1cb0603
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTests.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testIs = function(gl) {
+ var tex = loadTexture(gl, document.getElementById('2d'));
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var fbo = new FBO(gl, 1, 1);
+ fbo.use();
+ var prog = gl.createProgram();
+ var sh1 = gl.createShader(gl.VERTEX_SHADER);
+ var sh2 = gl.createShader(gl.FRAGMENT_SHADER);
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ assert("tex", gl.isTexture(tex));
+ assert("fbo", gl.isFramebuffer(fbo.fbo));
+ assert("rbo", gl.isRenderbuffer(fbo.rbo));
+ assert("prog", gl.isProgram(prog));
+ assert("sh1", gl.isShader(sh1));
+ assert("sh2", gl.isShader(sh2));
+ assert("buf", gl.isBuffer(buf));
+ gl.deleteTexture(tex);
+ gl.deleteFramebuffer(fbo.fbo);
+ gl.deleteRenderbuffer(fbo.rbo);
+ gl.deleteProgram(prog);
+ gl.deleteShader(sh1);
+ gl.deleteShader(sh2);
+ gl.deleteBuffer(buf);
+ // NOTE: we purposely do not unbind things.
+ assert("tex", !gl.isTexture(tex));
+ assert("fbo", !gl.isFramebuffer(fbo.fbo));
+ assert("rbo", !gl.isRenderbuffer(fbo.rbo));
+ assert("prog", !gl.isProgram(prog));
+ assert("sh1", !gl.isShader(sh1));
+ assert("sh2", !gl.isShader(sh2));
+ assert("buf", !gl.isBuffer(buf));
+}
+
+</script>
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+ <canvas id="2d" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTestsBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTestsBadArgs.html
new file mode 100644
index 0000000000..4d7548140b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTestsBadArgs.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<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_element" width="1" height="1"></canvas>
+<script type="application/javascript">
+
+function runTest()
+{
+ shouldThrow("gl.isBuffer(gl.createFramebuffer())");
+ shouldThrow("gl.isBuffer(gl.createProgram())");
+ shouldThrow("gl.isBuffer(gl.createRenderbuffer())");
+ shouldThrow("gl.isBuffer(gl.createShader(gl.VERTEX_SHADER))");
+ shouldThrow("gl.isBuffer(gl.createTexture())");
+
+ shouldThrow("gl.isFramebuffer(gl.createBuffer())");
+ shouldThrow("gl.isFramebuffer(gl.createProgram())");
+ shouldThrow("gl.isFramebuffer(gl.createRenderbuffer())");
+ shouldThrow("gl.isFramebuffer(gl.createShader(gl.VERTEX_SHADER))");
+ shouldThrow("gl.isFramebuffer(gl.createTexture())");
+
+ shouldThrow("gl.isProgram(gl.createBuffer())");
+ shouldThrow("gl.isProgram(gl.createFramebuffer())");
+ shouldThrow("gl.isProgram(gl.createRenderbuffer())");
+ shouldThrow("gl.isProgram(gl.createShader(gl.VERTEX_SHADER))");
+ shouldThrow("gl.isProgram(gl.createTexture())");
+
+ shouldThrow("gl.isRenderbuffer(gl.createBuffer())");
+ shouldThrow("gl.isRenderbuffer(gl.createFramebuffer())");
+ shouldThrow("gl.isRenderbuffer(gl.createProgram())");
+ shouldThrow("gl.isRenderbuffer(gl.createShader(gl.VERTEX_SHADER))");
+ shouldThrow("gl.isRenderbuffer(gl.createTexture())");
+
+ shouldThrow("gl.isShader(gl.createBuffer())");
+ shouldThrow("gl.isShader(gl.createFramebuffer())");
+ shouldThrow("gl.isShader(gl.createProgram())");
+ shouldThrow("gl.isShader(gl.createRenderbuffer())");
+ shouldThrow("gl.isShader(gl.createTexture())");
+
+ shouldThrow("gl.isTexture(gl.createBuffer())");
+ shouldThrow("gl.isTexture(gl.createFramebuffer())");
+ shouldThrow("gl.isTexture(gl.createProgram())");
+ shouldThrow("gl.isTexture(gl.createRenderbuffer())");
+ shouldThrow("gl.isTexture(gl.createShader(gl.VERTEX_SHADER))");
+
+ shouldBe("gl.isBuffer(null)", "false");
+ shouldBe("gl.isBuffer(undefined)", "false");
+
+ shouldBe("gl.isFramebuffer(null)", "false");
+ shouldBe("gl.isFramebuffer(undefined)", "false");
+
+ shouldBe("gl.isProgram(null)", "false");
+ shouldBe("gl.isProgram(undefined)", "false");
+
+ shouldBe("gl.isRenderbuffer(null)", "false");
+ shouldBe("gl.isRenderbuffer(undefined)", "false");
+
+ shouldBe("gl.isShader(null)", "false");
+ shouldBe("gl.isShader(undefined)", "false");
+
+ shouldBe("gl.isTexture(null)", "false");
+ shouldBe("gl.isTexture(undefined)", "false");
+}
+
+description("Tests type checking for isX() functions");
+var gl = WebGLTestUtils.create3DContext(document.getElementById("canvas_element"));
+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/more/functions/readPixels.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixels.html
new file mode 100644
index 0000000000..61589b0a80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixels.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testReadPixels = function(gl) {
+ var id = new Uint8Array(16 * 16 * 4);
+ assertOk(function(){gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);});
+ assertOk(function(){gl.readPixels(0,0,16,16,gl.RGBA, gl.UNSIGNED_BYTE, id);});
+ assertOk(function(){gl.readPixels(15,15,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);});
+}
+Tests.testReadPixelsRGBA = function(gl) {
+ gl.clearColor(1, 0, 1, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var id = new Uint8Array(4);
+ gl.readPixels(1,2,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertArrayEquals([255, 0, 255, 0], id);
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixelsBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixelsBadArgs.html
new file mode 100644
index 0000000000..3d155ed61b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixelsBadArgs.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript" src="../../../js/webgl-test-utils.js"></script>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+<canvas id="c" width="128" height="128"></canvas>
+<img id="i">
+<script type="application/javascript">
+var wtu = WebGLTestUtils;
+var defaultImgUrl = "https://get.webgl.org/conformance-resources/opengl_logo.jpg";
+var localImgUrl = "../../../resources/opengl_logo.jpg";
+
+Tests.autoinit = false; // Prevents the test from running until the image is loaded
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testReadPixels = function(gl) {
+ // we can't know if this is going to fail because of negative width
+ // or because the buffer size doesn't match the dimensions.
+ assertSomeGLError(gl, "negative width",
+ function(){gl.readPixels(0,0,-1,1, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));});
+ assertSomeGLError(gl, "negative height",
+ function(){gl.readPixels(0,0,1,-1, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));});
+ assertOk("negative x",
+ function(){gl.readPixels(-1,0,1,1, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));});
+ assertOk("negative y",
+ function(){gl.readPixels(0,-1,1,1, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));});
+ assertOk("height > backbuffer height",
+ function(){gl.readPixels(0,0,16,17, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(16*17*4));});
+ assertOk("width > backbuffer width",
+ function(){gl.readPixels(0,0,17,16, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(17*16*4));});
+ assertOk("width, height = 0",
+ function(){gl.readPixels(0,0,0,0, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(0));});
+ // we can't know if this is going to fail because of negative width
+ // or because the buffer size doesn't match the dimensions.
+ assertSomeGLError(gl, "bad format",
+ function(){gl.readPixels(0,0,1,1, gl.FLOAT, gl.UNSIGNED_BYTE,
+ new Uint8Array(4*4));});
+ // we can't know if this is going to fail because of negative width
+ // or because the buffer size doesn't match the dimensions.
+ assertSomeGLError(gl, "bad type",
+ function(){gl.readPixels(0,0,1,1, gl.ALPHA, gl.FLOAT,
+ new Uint8Array(1*4));});
+}
+
+Tests.testReadPixelsSOPIMG = function(gl) {
+ var img = document.getElementById("i");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // SOP failure
+ assertThrowNoGLError(gl, "throw because img is from another domain",
+ function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);});
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ assertOk("canvas still origin-clean",
+ function(){gl.readPixels(0,0,1,1, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));});
+ gl.deleteTexture(tex);
+}
+Tests.testReadPixelsSOPCanvas = function(gl) {
+ var img = document.getElementById("i");
+ var c = document.getElementById("c");
+ c.getContext("2d").drawImage(img, 0, 0);
+ assertFail("canvas throws because not origin clean",
+ function(){c.getContext("2d").getImageData(0,0,1,1);});
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // SOP failure
+ assertThrowNoGLError(gl, "throw because canvas is not origin clean",
+ function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);});
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ assertOk("canvas still origin-clean",
+ function(){gl.readPixels(0,0,1,1, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));});
+ gl.deleteTexture(tex);
+}
+
+Tests.endUnit = function(gl) {
+};
+
+(async function() {
+ const img = document.getElementById('i');
+ try {
+ await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
+ } catch (e) {
+ testFailed(`Image setup failed (${e}).`);
+ finishTest();
+ return;
+ }
+ initTests();
+})();
+</script>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2D.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2D.html
new file mode 100644
index 0000000000..5da8b6313f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2D.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var texCubeMap = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex,texCubeMap) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.deleteTexture(tex);
+ gl.deleteTexture(texCubeMap);
+}
+
+Tests.testTexImage2D = function(gl) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0]));
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,2,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0]));
+ var valid_targets = [
+ gl.TEXTURE_2D,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ valid_targets.forEach(function(t) {
+ assertOk(function(){gl.texImage2D(t, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));});
+ });
+}
+
+Tests.testTexImage2DNull = function(gl) {
+ assertOk(function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);});
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DBadArgs.html
new file mode 100644
index 0000000000..c818d1b1a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DBadArgs.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+}
+
+Tests.testTexImage2D = function(gl) {
+ var data = new Uint8Array(4);
+ assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,1,0,gl.RGBA,gl.UNSIGNED_BYTE, data);
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,2,0,gl.RGBA,gl.UNSIGNED_BYTE, data);
+ });
+ assertGLError(gl, gl.INVALID_ENUM, "bad target", function(){
+ gl.texImage2D(gl.FLOAT, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ assertGLErrorIn(gl, [gl.INVALID_ENUM, gl.INVALID_VALUE],
+ "bad internal format/format", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.FLOAT, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "border > 0", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,48,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ // The spec says zero size is OK. If you disagree please list the section
+ // in the spec that details this issue.
+ assertOk("zero size", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0,0,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "negative width", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, -1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "negative height", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,-1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
+ });
+ assertGLErrorIn(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "bad format", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
+ });
+ assertGLErrorIn(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "bad type", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.TEXTURE_2D, null);
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array(3));
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_SHORT_5_6_5, null);
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1,1,0,gl.RGB,gl.UNSIGNED_SHORT_4_4_4_4, null);
+ });
+
+ assertThrows(gl, true, "too few args", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE);
+ });
+ assertThrows(gl, false, "too many args", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null, null);
+ });
+
+ assertThrows(gl, true, "bad TexSourceType", function(){
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, window);
+ });
+ assertThrows(gl, true, "fake TexSourceType", function(){
+ var fakeObj = {
+ get width() { throw 7 },
+ get height() { throw 7 },
+ data: new Uint8ClampedArray(10)
+ };
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, fakeObj);
+ });
+}
+
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTML.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTML.html
new file mode 100644
index 0000000000..5cc78d1635
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTML.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript" src="../../../js/webgl-test-utils.js"></script>
+<script id="identity-flip-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, 0.0, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="identity-hflip-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(1.0-Tex.s, Tex.t, 0.0, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="identity-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform sampler2D Texture;
+
+varying vec4 texCoord0;
+void main()
+{
+ vec4 c = texture2D(Texture, texCoord0.st);
+ gl_FragColor = c;
+}
+</script>
+</head>
+<body>
+<canvas id="gl" width="256" height="256"></canvas>
+<canvas id="c" width="256" height="256"></canvas>
+<img id="i" width="256" height="256" src="data:image/png;base64,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">
+<img id="i2">
+
+<script>
+var wtu = WebGLTestUtils;
+var defaultImgUrl = "https://get.webgl.org/conformance-resources/thunderbird-logo-64x64.png";
+var localImgUrl = "../../../resources/thunderbird-logo-64x64.png";
+
+Tests.autoinit = false; // Prevents the test from running until the image is loaded
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ gl.viewport(0,0,canvas.width,canvas.height);
+ gl.clearColor(0,0,1,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.disable(gl.DEPTH_TEST);
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var texCubeMap = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
+ return [gl]
+}
+
+Tests.teardown = function(gl, tex, texCubeMap) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.deleteTexture(texCubeMap);
+}
+
+Tests.testTexImage2D = function(gl) {
+ gl.enable(gl.BLEND);
+ var img = document.getElementById('i');
+ var c = document.getElementById('c');
+ var ctx = c.getContext('2d');
+ ctx.drawImage(img,0,0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ var f = new Filter(gl, 'identity-flip-vert', 'identity-frag');
+ gl.blendFunc(gl.ONE, gl.ZERO);
+ f.apply();
+ f.destroy();
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ f = new Filter(gl, 'identity-hflip-vert', 'identity-frag');
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+ f.apply();
+ f.destroy();
+ var valid_targets = [
+ gl.TEXTURE_2D,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ valid_targets.forEach(function(t) {
+ assertOk(function(){gl.texImage2D(t, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);});
+ assertOk(function(){gl.texImage2D(t, 1, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);});
+ });
+}
+
+Tests.testTexImage2DNonSOP = function(gl) {
+ var img = document.getElementById('i2');
+ var c = document.getElementById('c');
+ var ctx = c.getContext('2d');
+ ctx.drawImage(img,0,0);
+ assertThrowNoGLError(gl, "texImage2D with cross-origin image should throw exception.",
+ function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);});
+ assertThrowNoGLError(gl, "texImage2D with dirty origin canvas should throw exception.",
+ function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);});
+}
+
+Tests.endUnit = function(gl) {
+};
+
+(async function() {
+ const img = document.getElementById('i2');
+ try {
+ await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
+ } catch (e) {
+ testFailed(`Image setup failed (${e}).`);
+ finishTest();
+ return;
+ }
+ initTests();
+})();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTMLBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTMLBadArgs.html
new file mode 100644
index 0000000000..0953cd8884
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTMLBadArgs.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!--
+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.
+-->
+<meta charset="utf-8">
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ return [gl, tex];
+}
+
+Tests.testTexImage2D = function(gl) {
+ var b = document.createElement('b');
+ var div = document.createElement('div');
+ var c = document.getElementById('c');
+ assertFail("bad element b",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, b); });
+ assertFail("bad element div",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, div); });
+ assertFail("no element",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, 0); });
+ assertFail("string as data",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, "foo"); });
+ assertOk("canvas as data",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertFail("bad target",
+ function() {gl.texImage2D(gl.FLOAT, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+}
+
+Tests.endUnit = function(gl, tex) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+<canvas id="c" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2D.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2D.html
new file mode 100644
index 0000000000..ef0912aa8f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2D.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var texCubeMap = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex,texCubeMap) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.deleteTexture(texCubeMap);
+}
+
+Tests.testTexSubImage2D = function(gl) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,2,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 2,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,2,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 1,0, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,1, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 1,1, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texImage2D(gl.TEXTURE_2D, 1,gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texSubImage2D(gl.TEXTURE_2D, 1, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ var valid_targets = [
+ gl.TEXTURE_2D,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ valid_targets.forEach(function(t) {
+ assertOk(function(){
+ gl.texImage2D(t, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ gl.texSubImage2D(t, 0, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ });
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DBadArgs.html
new file mode 100644
index 0000000000..9573607b3b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DBadArgs.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ return [gl]
+}
+
+Tests.teardown = function(gl,tex) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+}
+
+Tests.testTexImage2D = function(gl) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2,2,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]));
+ assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, 2,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, 1,2,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_ENUM, "bad target", function(){
+ gl.texSubImage2D(gl.FLOAT, 0, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "width out of range", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, 3,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "height out of range", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, 1,3,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "dimension out of range", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D,0, 1,1, 2,1, gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "dimension out of range", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D,0, 1,1, 1,2, gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]));
+ });
+ assertOk("zero size", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, 0,0,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertSomeGLError(gl, "negative width", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, -1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertSomeGLError(gl, "negative height", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, 1,-1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "negative x", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,-1,1,1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_VALUE, "negative y", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0,1,-1,1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLErrorIn(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], "bad format", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.FLOAT,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
+ });
+ assertGLErrorIn(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], "bad type", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.RGBA,gl.TEXTURE_2D, new Uint8Array([0,0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "not enough data", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "format does not match internal format", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.RGB,gl.UNSIGNED_BYTE, new Uint8Array([0,0,0]));
+ });
+ assertGLError(gl, gl.INVALID_OPERATION, "type does not match original", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_SHORT_4_4_4_4, new Uint16Array([0]));
+ });
+
+ assertThrows(gl, true, "too few args", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE);
+ });
+ assertThrows(gl, false, "too many args", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]), null);
+ });
+
+ assertThrows(gl, true, "bad TexSourceType", function(){
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, window);
+ });
+ assertThrows(gl, true, "fake TexSourceType", function(){
+ var fakeObj = {
+ get width() { throw 7 },
+ get height() { throw 7 },
+ data: new Uint8ClampedArray(10)
+ };
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, fakeObj);
+ });
+}
+
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTML.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTML.html
new file mode 100644
index 0000000000..4f8ec2aa09
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTML.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript" src="../../../js/webgl-test-utils.js"></script>
+<script id="identity-flip-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, 0.0, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="identity-hflip-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(1.0-Tex.s, Tex.t, 0.0, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="identity-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform sampler2D Texture;
+
+varying vec4 texCoord0;
+void main()
+{
+ vec4 c = texture2D(Texture, texCoord0.st);
+ gl_FragColor = c;
+}
+</script>
+</head><body>
+<canvas id="gl" width="256" height="256"></canvas>
+<canvas id="c" width="256" height="256"></canvas>
+<img id="i" width="256" height="256" src="data:image/png;base64,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">
+<img id="i2">
+
+<script>
+var wtu = WebGLTestUtils;
+var defaultImgUrl = "https://get.webgl.org/conformance-resources/thunderbird-logo-64x64.png";
+var localImgUrl = "../../../resources/thunderbird-logo-64x64.png";
+
+Tests.autoinit = false; // Prevents the test from running until the image is loaded
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+
+ gl.viewport(0,0,canvas.width,canvas.height);
+ gl.clearColor(0,0,1,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.disable(gl.DEPTH_TEST);
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var texCubeMap = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap);
+ return [gl]
+}
+
+Tests.teardown = function(gl, tex, texCubeMap) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.deleteTexture(texCubeMap);
+}
+
+Tests.testTexImage2D = function(gl) {
+ gl.enable(gl.BLEND);
+ var img = document.getElementById('i');
+ var c = document.getElementById('c');
+ var ctx = c.getContext('2d');
+ ctx.drawImage(img,0,0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, img);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ var f = new Filter(gl, 'identity-flip-vert', 'identity-frag');
+ gl.blendFunc(gl.ONE, gl.ZERO);
+ f.apply();
+ f.destroy();
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ f = new Filter(gl, 'identity-hflip-vert', 'identity-frag');
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+ f.apply();
+ f.destroy();
+ var valid_targets = [
+ gl.TEXTURE_2D,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ valid_targets.forEach(function(t) {
+ assertOk(function(){
+ gl.texImage2D(t, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ gl.texSubImage2D(t, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ });
+ assertOk(function(){
+ gl.texImage2D(t, 1, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ gl.texSubImage2D(t, 1, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ });
+ });
+}
+
+Tests.testTexImage2DNonSOP = function(gl) {
+ var img = document.getElementById('i2');
+ var c = document.getElementById('c');
+ var ctx = c.getContext('2d');
+ ctx.drawImage(img,0,0);
+ assertThrowNoGLError(gl, "texImage2D with cross-origin image should throw exception.",
+ function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);});
+ assertThrowNoGLError(gl, "texSubImage2D with cross-origin image should throw exception.",
+ function(){gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, img);});
+ assertThrowNoGLError(gl, "texImage2D with dirty origin canvas should throw exception.",
+ function(){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);});
+ assertThrowNoGLError(gl, "texSubImage2D with dirty origin canvas should throw exception.",
+ function(){gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, c);});
+}
+
+Tests.endUnit = function(gl) {
+};
+
+(async function() {
+ const img = document.getElementById('i2');
+ try {
+ await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
+ } catch (e) {
+ testFailed(`Image setup failed (${e}).`);
+ finishTest();
+ return;
+ }
+ initTests();
+})();
+</script>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTMLBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTMLBadArgs.html
new file mode 100644
index 0000000000..0d860bcaaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTMLBadArgs.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ return [gl, tex];
+}
+
+Tests.testTexImage2D = function(gl) {
+ var b = document.createElement('b');
+ var div = document.createElement('div');
+ var c = document.getElementById('c');
+ assertOk("make texture",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_VALUE, "y + height > texture height",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 1, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_VALUE, "x + width > texture width",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_VALUE, "negative x",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_VALUE, "negative y",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, -1, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_VALUE, "negative level",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, -1, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertThrowNoGLError(gl, "bad element b",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, b); });
+ assertThrowNoGLError(gl, "bad element div",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, div); });
+ assertThrowNoGLError(gl, "no element",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, 0); });
+ assertThrowNoGLError(gl, "string as data",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0,0, 0, gl.RGBA, gl.UNSIGNED_BYTE, "foo"); });
+ assertGLError(gl, gl.INVALID_ENUM, "bad target",
+ function() {gl.texSubImage2D(gl.FLOAT, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertOk("good args",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_OPERATION, "format not same as original",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGB, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_OPERATION, "type not same as original",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, c); });
+ assertOk("make texture RGB",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, c); });
+ assertOk("format same as original RGB",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGB, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_OPERATION, "format not same as original RGB",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_OPERATION, "type not same as original RGB",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, c); });
+ assertOk("make texture RGBA 4_4_4_4",
+ function() {gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, c); });
+ assertOk("format same as original RGBA 4_4_4_4",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, c); });
+ assertGLError(gl, gl.INVALID_OPERATION, "format not same as original RGBA 4_4_4_4",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGB, gl.UNSIGNED_BYTE, c); });
+ assertGLError(gl, gl.INVALID_OPERATION, "type not same as original RGBA 4_4_4_4",
+ function() {gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, gl.RGBA, gl.UNSIGNED_BYTE, c); });
+}
+
+Tests.endUnit = function(gl, tex) {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+<canvas id="c" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrix.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrix.html
new file mode 100644
index 0000000000..cae388fd4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrix.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testUniformf = function(gl) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var foo = f.uniform('foo');
+ var bar = f.uniform('bar');
+ var bar3 = f.uniform('bar3');
+ gl.uniformMatrix4fv(foo, false, [1,0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);
+ gl.uniformMatrix2fv(bar, false, [2,1, 2,2]);
+ gl.uniformMatrix3fv(bar3, false, [2,2,2, 2,2,2, 2,1,2]);
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertEquals([1,2,3,8], [d[0], d[1], d[2], d[3]]);
+ sh.destroy();
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform mat2 bar;
+uniform mat3 bar3;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, bar[0][1]+bar3[2][1], 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform mat4 foo;
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(foo[0][0]/256.0, foo[1][1]/256.0, foo[2][2]/256.0, foo[3][3]*texCoord0.z/256.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrixBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrixBadArgs.html
new file mode 100644
index 0000000000..1355cd547f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrixBadArgs.html
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var unwrappedGL = getGLContext(canvas);
+ var gl = wrapGLContext(unwrappedGL);
+ return [gl, unwrappedGL];
+}
+
+Tests.testUniformf = function(gl, unwrappedGL) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var fm4 = f.uniform('fm4');
+ var fm2 = f.uniform('fm2');
+ var fm3 = f.uniform('fm3');
+ assertGLError(gl, gl.INVALID_VALUE, "bad transpose 4fv",
+ function(){gl.uniformMatrix4fv(fm4, true, [1,0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);});
+ assertGLError(gl, gl.INVALID_VALUE, "bad transpose 3fv",
+ function(){gl.uniformMatrix3fv(fm3, true, [1,0,0, 0,2,0, 0,0,3]);});
+ assertGLError(gl, gl.INVALID_VALUE, "bad transpose 2fv",
+ function(){gl.uniformMatrix2fv(fm2, true, [1,0, 0,2]);});
+ assertThrowNoGLError(gl, "bad location",
+ function(){gl.uniformMatrix4fv(588939, false, [1,0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);});
+ assertThrowNoGLError(gl, "bad location (negative)",
+ function(){gl.uniformMatrix4fv(-588939, false, [1,0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);});
+ assertGLError(gl, gl.INVALID_VALUE, "17 values to 4fv",
+ function(){gl.uniformMatrix4fv(fm4, false, [0,1,0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);});
+ assertGLError(gl, gl.INVALID_VALUE, "5 values to 2fv",
+ function(){gl.uniformMatrix2fv(fm2, false, [0,2,1, 2,2]);});
+ assertGLError(gl, gl.INVALID_VALUE, "10 values to 3fv",
+ function(){gl.uniformMatrix3fv(fm3, false, [0,2,2,2, 2,2,2, 2,1,2]);});
+ assertGLError(gl, gl.INVALID_VALUE, "too few values to 4fv",
+ function(){gl.uniformMatrix4fv(fm4, false, [0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);});
+ assertGLError(gl, gl.INVALID_VALUE, "too few values to 2fv",
+ function(){gl.uniformMatrix2fv(fm2, false, [1, 2,2]);});
+ assertGLError(gl, gl.INVALID_VALUE, "too few values to 2fv",
+ function(){gl.uniformMatrix2fv(fm2, false, []);});
+ assertThrowNoGLError(gl, "string for data",
+ function(){gl.uniformMatrix2fv(fm2, false, "fm4");});
+ assertGLError(gl, gl.INVALID_VALUE, "too few values to 3fv",
+ function(){gl.uniformMatrix3fv(fm3, false, [2,2, 2,2,2, 2,1,2]);});
+ gl.uniformMatrix4fv(fm4, false, [1,0,0,0, 0,2,0,0, 0,0,3,0, 0,0,0,4]);
+ gl.uniformMatrix2fv(fm2, false, [2,1, 2,2]);
+ gl.uniformMatrix3fv(fm3, false, [2,2,2, 2,2,2, 2,1,2]);
+ assertGLError(gl, gl.INVALID_OPERATION, "3fv on mat4",
+ function(){gl.uniformMatrix3fv(fm4, false, [1,0,0, 0,2,0, 0,0,3]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "3fv on mat2",
+ function(){gl.uniformMatrix3fv(fm2, false, [0,2,1, 0,2,2, 0,0,0]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "2fv om mat3",
+ function(){gl.uniformMatrix2fv(fm3, false, [2,2, 2,2]);});
+ for (var ii = 2; ii <= 4; ++ii) {
+ var all = [];
+ var mats = [[],[]];
+ for (var jj = 0; jj < 2; ++jj) {
+ for (var kk = 0; kk < ii * ii; ++kk) {
+ mats[jj].push(jj + 1);
+ all.push(jj + 1);
+ }
+ }
+ var loc0Name = 'am' + ii + '[0]';
+ var loc1Name = 'am' + ii + '[1]';
+ var loc0 = f.uniform(loc0Name);
+ var loc1 = f.uniform(loc1Name);
+ var fname = "uniformMatrix" + ii + "fv";
+ assert(loc0Name, loc0 != null);
+ assert(loc1Name, loc1 != null);
+ assertOk("set array of 2 matrices " + ii + "fv",
+ function(){gl[fname].call(gl,loc0, false, all);});
+ var actual = unwrappedGL.getUniform(sh.shader.program, loc0);
+ assert("got value for loc0",
+ gl.NO_ERROR == checkError(gl, "getUniform loc0"));
+ assertArrayEquals(mats[0], actual);
+ var actual = unwrappedGL.getUniform(sh.shader.program, loc1);
+ assert("got value for loc1",
+ gl.NO_ERROR == checkError(gl, "getUniform loc1"));
+ assertArrayEquals(mats[1], actual);
+ assertOk("set array of second array of 2 matrixes",
+ function(){gl[fname].call(gl, loc1, false, mats[0]);});
+ var actual = unwrappedGL.getUniform(sh.shader.program, loc1);
+ assert("got value for loc1",
+ gl.NO_ERROR == checkError(gl, "getUniform loc1"));
+ assertArrayEquals(mats[0], actual);
+ var big = mats[1].concat([3]);
+ assertGLError(gl, gl.INVALID_VALUE, "set array of first array of 2 matrixes plus 1 value",
+ function(){gl[fname].call(gl, loc0, false, big);});
+ }
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertArrayEqualsWithEpsilon([1,2,3,8], d, [1,1,1,1]);
+ sh.destroy();
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform mat2 fm2;
+uniform mat3 fm3;
+uniform mat2 am2[2];
+uniform mat3 am3[2];
+uniform mat4 am4[2];
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, fm2[0][1]+fm3[2][1], 0.0);
+ float d = am2[0][1][1] + am3[0][2][2] + am4[0][3][3] +
+ am2[1][1][1] + am3[1][2][2] + am4[1][3][3];
+ gl_Position = vec4(Vertex, 1.0 + d * 0.0001);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform mat4 fm4;
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(fm4[0][0]/256.0, fm4[1][1]/256.0, fm4[2][2]/256.0, fm4[3][3]*texCoord0.z/256.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformf.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformf.html
new file mode 100644
index 0000000000..3c968c7a0c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformf.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testUniformf = function(gl) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var foo = f.uniform('foo');
+ var bar = f.uniform('bar');
+ gl.uniform4fv(foo, [1,2,3,4]);
+ gl.uniform1fv(bar, [2]);
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertEquals([1,2,3,8], [d[0], d[1], d[2], d[3]]);
+ sh.apply(function(f){
+ var foo = f.uniform('foo');
+ var bar = f.uniform('bar');
+ gl.uniform4f(foo, 2,2,3,4);
+ gl.uniform1f(bar, 3);
+ });
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertEquals([2,2,3,12], [d[0], d[1], d[2], d[3]]);
+ sh.destroy();
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform float bar;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, bar, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform vec4 foo;
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(foo.r/255.0, foo.g/255.0, foo.b/255.0, foo.a*texCoord0.z/255.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfArrayLen1.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfArrayLen1.html
new file mode 100644
index 0000000000..3b210f1f1e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfArrayLen1.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testUniformArray = function(gl) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var uniV4 = f.uniform('uniV4');
+ var uniFloat = f.uniform('uniFloat');
+ assertOk("1fv on 1fv",
+ function(){gl.uniform1fv(uniFloat, [2]);});
+ assertOk("5 values on 1fv",
+ function(){gl.uniform1fv(uniFloat, [2,3,4,5,6]);});
+ assertOk("4fv on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4]);});
+ assertOk("8 values on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4, 5, 6, 7, 8]);});
+
+ var uniformsFound = 0;
+ var numUniforms = gl.getProgramParameter(f.shader.program, gl.ACTIVE_UNIFORMS);
+ for (var i = 0; i < numUniforms; ++i) {
+ var uniformName = gl.getActiveUniform(f.shader.program, i).name;
+ if (uniformName.indexOf('uniV4') == 0 || uniformName.indexOf('uniFloat') == 0) {
+ assert("Uniform array of length 1 ends with [0]", uniformName.indexOf("[0]") != -1);
+ ++uniformsFound;
+ }
+ }
+ assert("Both uniforms found", uniformsFound == 2);
+
+ uniV4 = f.uniform('uniV4[0]');
+ uniFloat = f.uniform('uniFloat[0]');
+ assertOk("1fv on 1fv",
+ function(){gl.uniform1fv(uniFloat, [2]);});
+ assertOk("5 values on 1fv",
+ function(){gl.uniform1fv(uniFloat, [2,3,4,5,6]);});
+ assertOk("4fv on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4]);});
+ assertOk("8 values on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4, 5, 6, 7, 8]);});
+
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertArrayEquals([1,2,3,8], d);
+ sh.destroy();
+ throwError(gl);
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform float uniFloat[1];
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, uniFloat[0], 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform vec4 uniV4[1];
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(
+ uniV4[0].r/255.0,
+ uniV4[0].g/255.0,
+ uniV4[0].b/255.0,
+ uniV4[0].a*texCoord0.z/255.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfBadArgs.html
new file mode 100644
index 0000000000..32b2c4babc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfBadArgs.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testUniformf = function(gl) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var uniV4 = f.uniform('uniV4');
+ var uniFloat = f.uniform('uniFloat');
+ assertThrowNoGLError(gl, "number for location",
+ function(){gl.uniform4fv(58882929, [1,2,3,4]);});
+ assertThrowNoGLError(gl, "negative number for location",
+ function(){gl.uniform4fv(-58882929, [1,2,3,4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "1fv on 4fv",
+ function(){gl.uniform1fv(uniV4, [1,2,3,4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "more than enough values 1fv",
+ function(){gl.uniform1fv(uniFloat, [2,3,4,5,6]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "4fv on float",
+ function(){gl.uniform4fv(uniFloat, [2,3,4,5]);});
+ assertOk("4fv on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4]);});
+ assertGLError(gl, gl.INVALID_VALUE, "5 values on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4, 5]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "8 values on 4fv",
+ function(){gl.uniform4fv(uniV4, [1, 2, 3, 4, 5, 6, 7, 8]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "3fv on float",
+ function(){gl.uniform3fv(uniFloat, [2,3,4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "2fv on float",
+ function(){gl.uniform2fv(uniFloat, [2,3]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "3fv on 4fv",
+ function(){gl.uniform3fv(uniV4, [4,5,6]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "2fv on 4fv",
+ function(){gl.uniform2fv(uniV4, [5,6]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "1fv on 4fv",
+ function(){gl.uniform1fv(uniV4, [6]);});
+ assertOk("1fv on 1fv",
+ function(){gl.uniform1fv(uniFloat, [2]);});
+ assertGLError(gl, gl.INVALID_VALUE, "not enough values on 1fv",
+ function(){gl.uniform1fv(uniFloat, []);});
+ assertGLError(gl, gl.INVALID_VALUE, "not enough values on 4fv",
+ function(){gl.uniform4fv(uniV4, [3,3,4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "4iv on 4fv",
+ function(){gl.uniform4iv(uniV4, [1, 2, 3, 4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "1iv on 1fv",
+ function(){gl.uniform1iv(uniFloat, [2]);});
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertArrayEquals([1,2,3,8], d);
+ sh.destroy();
+ throwError(gl);
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform float uniFloat;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, uniFloat, 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform vec4 uniV4;
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(
+ uniV4.r/255.0,
+ uniV4.g/255.0,
+ uniV4.b/255.0,
+ uniV4.a*texCoord0.z/255.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformi.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformi.html
new file mode 100644
index 0000000000..252626a735
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformi.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testUniformi = function(gl) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var foo = f.uniform('foo');
+ var bar = f.uniform('bar');
+ gl.uniform4iv(foo, [1,2,3,4]);
+ gl.uniform1iv(bar, [2]);
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertEquals([1,2,3,8], [d[0], d[1], d[2], d[3]]);
+ sh.apply(function(f){
+ var foo = f.uniform('foo');
+ var bar = f.uniform('bar');
+ gl.uniform4i(foo, 2,2,3,4);
+ gl.uniform1i(bar, 3);
+ });
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertEquals([2,2,3,12], [d[0], d[1], d[2], d[3]]);
+ sh.destroy();
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform int bar;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, float(bar), 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform ivec4 foo;
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(float(foo.r)/256.0, float(foo.g)/256.0, float(foo.b)/256.0, float(foo.a)*texCoord0.z/256.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformiBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformiBadArgs.html
new file mode 100644
index 0000000000..4741ffebac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformiBadArgs.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.testUniformf = function(gl) {
+ var sh = new Filter(gl, 'foobar-vert', 'foobar-frag');
+ sh.apply(function(f){
+ var uniIV4 = f.uniform('uniIV4');
+ var uniInt = f.uniform('uniInt');
+ assertThrowNoGLError(gl, "number as location",
+ function(){gl.uniform4iv(58882929, [1,2,3,4]);});
+ assertThrowNoGLError(gl, "negative number as location",
+ function(){gl.uniform4iv(-58882929, [1,2,3,4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "more than 1 value to 1iv",
+ function(){gl.uniform1iv(uniInt, [2,3,4,5,6]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "4iv on int",
+ function(){gl.uniform4iv(uniInt, [2,3,4,5]);});
+ assertOk("4iv on 4iv",
+ function(){gl.uniform4iv(uniIV4, [1, 2, 3, 4]);});
+ assertGLError(gl, gl.INVALID_VALUE, "5 values on 4iv",
+ function(){gl.uniform4iv(uniIV4, [1, 2, 3, 4, 5]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "8 values on 4iv",
+ function(){gl.uniform4iv(uniIV4, [1, 2, 3, 4, 5, 6, 7, 8]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "3iv on int",
+ function(){gl.uniform3iv(uniInt, [2,3,4]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "2iv on int",
+ function(){gl.uniform2iv(uniInt, [2,3]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "3iv on 4iv",
+ function(){gl.uniform3iv(uniIV4, [4,5,6]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "2iv on 4iv",
+ function(){gl.uniform2iv(uniIV4, [5,6]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "1iv on 4iv",
+ function(){gl.uniform1iv(uniIV4, [6]);});
+ assertGLError(gl, gl.INVALID_VALUE, "not enough values",
+ function(){gl.uniform1iv(uniInt, []);});
+ assertGLError(gl, gl.INVALID_OPERATION, "1fv on int",
+ function(){gl.uniform1fv(uniInt, [2]);});
+ assertGLError(gl, gl.INVALID_OPERATION, "4fv on ivec4",
+ function(){gl.uniform4fv(uniIV4, [2,3,4,5]);});
+ gl.uniform1iv(uniInt, [2]);
+ gl.uniform4iv(uniIV4, [1, 2, 3, 4]);
+ });
+ var d = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, d);
+ assertArrayEquals([1,2,3,8], d);
+ sh.destroy();
+ throwError(gl);
+}
+
+Tests.endUnit = function(gl) {
+}
+
+</script>
+<script id="foobar-vert" type="x-shader/x-vertex">
+attribute vec3 Vertex;
+attribute vec2 Tex;
+
+uniform int uniInt;
+
+varying vec4 texCoord0;
+void main()
+{
+ texCoord0 = vec4(Tex.s, 1.0-Tex.t, float(uniInt), 0.0);
+ gl_Position = vec4(Vertex, 1.0);
+}
+</script>
+<script id="foobar-frag" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform ivec4 uniIV4;
+
+varying vec4 texCoord0;
+void main()
+{
+ gl_FragColor = vec4(
+ float(uniIV4.x)/256.0,
+ float(uniIV4.y)/256.0,
+ float(uniIV4.z)/256.0,
+ float(uniIV4.a)*texCoord0.z/256.0);
+}
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+<canvas id="gl" width="16" height="16"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttrib.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttrib.html
new file mode 100644
index 0000000000..866c95da1c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttrib.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+var verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0];
+var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0];
+var texcoords = [0.0,0.0, 1.0,0.0, 0.0,1.0];
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var prog = new Shader(gl, 'vert', 'frag');
+ prog.use();
+ var sh = prog.shader.program;
+// log(gl.getShaderInfoLog(prog.shaders[1]));
+ var v = gl.getAttribLocation(sh, 'Vertex');
+ var n = gl.getAttribLocation(sh, 'Normal');
+ var t = gl.getAttribLocation(sh, 'Tex');
+ return [gl,prog,v,n,t];
+}
+
+Tests.setup = function(gl, prog, v,n,t) {
+ assert(0 == gl.getError());
+ return [gl, prog, v,n,t];
+}
+Tests.teardown = function(gl, prog, v,n,t) {
+ gl.disableVertexAttribArray(v);
+ gl.disableVertexAttribArray(n);
+ gl.disableVertexAttribArray(t);
+}
+
+Tests.endUnit = function(gl, prog, v,n,t) {
+ prog.destroy();
+}
+
+Tests.testVertexAttrib = function(gl, prog, v,n,t) {
+ var vbo = gl.createBuffer();
+ var vertsArr = new Float32Array(verts);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, vertsArr, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(v);
+ gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
+ gl.vertexAttrib1fv(v, [1]);
+ gl.vertexAttrib2fv(v, [1,2]);
+ gl.vertexAttrib3fv(v, [1,2,3]);
+ gl.vertexAttrib4fv(v, [1,2,3,4]);
+ gl.vertexAttrib1f(v, 1);
+ gl.vertexAttrib2f(v, 1,2);
+ gl.vertexAttrib3f(v, 1,2,3);
+ gl.vertexAttrib4f(v, 1,2,3,4);
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
+ throwError(gl);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(vbo);
+ throwError(gl);
+}
+Tests.testVertexAttribVBO = function(gl, prog, v,n,t) {
+ var vbo = gl.createBuffer();
+ var vertsArr = new Float32Array(verts);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, vertsArr, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(v);
+ gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
+ gl.vertexAttrib1fv(v, [1]);
+ gl.vertexAttrib2fv(v, [1,2]);
+ gl.vertexAttrib3fv(v, [1,2,3]);
+ gl.vertexAttrib4fv(v, [1,2,3,4]);
+ gl.vertexAttrib1f(v, 1);
+ gl.vertexAttrib2f(v, 1,2);
+ gl.vertexAttrib3f(v, 1,2,3);
+ gl.vertexAttrib4f(v, 1,2,3,4);
+ assertOk(function(){gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);});
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
+ gl.vertexAttrib4fv(v, [1,2,3,4]);
+ assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
+ throwError(gl);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(vbo);
+ throwError(gl);
+}
+
+</script>
+<script id="vert" type="x-shader/x-vertex">
+ attribute vec3 Vertex;
+ attribute vec3 Normal;
+ attribute vec2 Tex;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ gl_Position = vec4(Vertex * Normal, 1.0);
+ texCoord0 = vec4(Tex,0.0,0.0) + gl_Position;
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+ precision mediump float;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ vec4 c = texCoord0;
+ gl_FragColor = c;
+ }
+</script>
+
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribBadArgs.html
new file mode 100644
index 0000000000..67e44a5b87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribBadArgs.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+var verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0];
+var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0];
+var texcoords = [0.0,0.0, 1.0,0.0, 0.0,1.0];
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var prog = new Shader(gl, 'vert', 'frag');
+ prog.use();
+ var sh = prog.shader.program;
+// log(gl.getShaderInfoLog(prog.shaders[1]));
+ var v = gl.getAttribLocation(sh, 'Vertex');
+ var n = gl.getAttribLocation(sh, 'Normal');
+ var t = gl.getAttribLocation(sh, 'Tex');
+ return [gl,prog,v,n,t];
+}
+
+Tests.setup = function(gl, prog, v,n,t) {
+ assert(0 == gl.getError());
+ return [gl, prog, v,n,t];
+}
+Tests.teardown = function(gl, prog, v,n,t) {
+ gl.disableVertexAttribArray(v);
+ gl.disableVertexAttribArray(n);
+ gl.disableVertexAttribArray(t);
+}
+
+Tests.endUnit = function(gl, prog, v,n,t) {
+ prog.destroy();
+}
+
+
+Tests.testVertexAttrib = function(gl, prog, v,n,t) {
+ var vbo = gl.createBuffer();
+ var vertsArr = new Float32Array(verts);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, vertsArr, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(v);
+ gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
+ assertFail("bad index",
+ function(){gl.vertexAttrib1f(-1, 1);});
+ assertFail("bad index (big negative)",
+ function(){gl.vertexAttrib1f(-69092342, 1);});
+ assertFail("bad index (big positive)",
+ function(){gl.vertexAttrib1f(58928938, 1);});
+ assertOk("array too large",
+ function(){gl.vertexAttrib1fv(v, [1,2,3,4,5]);});
+ assertFail("array too small",
+ function(){gl.vertexAttrib1fv(v, []);});
+ assertOk("draw",
+ function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
+ throwError(gl);
+}
+
+</script>
+<script id="vert" type="x-shader/x-vertex">
+ attribute vec3 Vertex;
+ attribute vec3 Normal;
+ attribute vec2 Tex;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ gl_Position = vec4(Vertex * Normal, 1.0);
+ texCoord0 = vec4(Tex,0.0,0.0) + gl_Position;
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+ precision mediump float;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ vec4 c = texCoord0;
+ gl_FragColor = c;
+ }
+</script>
+
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointer.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointer.html
new file mode 100644
index 0000000000..838f7d61e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointer.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+var verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0];
+var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0];
+var texcoords = [0.0,0.0, 1.0,0.0, 0.0,1.0];
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ var prog = new Shader(gl, 'vert', 'frag');
+ prog.use();
+ var sh = prog.shader.program;
+// log(gl.getShaderInfoLog(prog.shaders[1]));
+ var v = gl.getAttribLocation(sh, 'Vertex');
+ var n = gl.getAttribLocation(sh, 'Normal');
+ var t = gl.getAttribLocation(sh, 'Tex');
+ return [gl,prog,v,n,t];
+}
+
+Tests.setup = function(gl, prog, v,n,t) {
+ assert(0 == gl.getError());
+ return [gl, prog, v,n,t];
+}
+Tests.teardown = function(gl, prog, v,n,t) {
+ gl.disableVertexAttribArray(v);
+ gl.disableVertexAttribArray(n);
+ gl.disableVertexAttribArray(t);
+}
+
+Tests.endUnit = function(gl, prog, v,n,t) {
+ prog.destroy();
+}
+
+Tests.testVertexAttribPointerVBO = function(gl, prog, v,n,t) {
+ var vbo = gl.createBuffer();
+ var vertsArr = new Float32Array(verts);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, vertsArr, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 4);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(vbo);
+}
+
+</script>
+<script id="vert" type="x-shader/x-vertex">
+ attribute vec3 Vertex;
+ attribute vec3 Normal;
+ attribute vec2 Tex;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ gl_Position = vec4(Vertex * Normal, 1.0);
+ texCoord0 = vec4(Tex,0.0,0.0) + gl_Position;
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+ precision mediump float;
+
+ varying vec4 texCoord0;
+ void main()
+ {
+ vec4 c = texCoord0;
+ gl_FragColor = c;
+ }
+</script>
+
+
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="gl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointerBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointerBadArgs.html
new file mode 100644
index 0000000000..124d0258e3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointerBadArgs.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+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.
+-->
+<link rel="stylesheet" type="text/css" href="../unit.css" />
+<script type="application/javascript" src="../unit.js"></script>
+<script type="application/javascript" src="../util.js"></script>
+<script type="application/javascript">
+
+Tests.startUnit = function () {
+ var canvas = document.createElement('canvas');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+Tests.setup = function(gl) {
+ assert(0 == gl.getError());
+ return [gl];
+}
+
+Tests.teardown = function(gl) {
+}
+
+Tests.endUnit = function(gl) {
+}
+
+Tests.testVertexAttribPointerVBO = function(gl) {
+ var vbo = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(4), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ assertFail("negative offset",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, -4);});
+ assertOk("out of range offset (OK because we can change the buffer later)",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 1200);});
+ assertFail("Offset that is incompatible with type",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 3);});
+ assertFail("negative stride",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, -1, 0);});
+ assertFail("bad size",
+ function(){gl.vertexAttribPointer(0, 5, gl.FLOAT, false, 0, 0);});
+ assertFail("stride that doesn't match type",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 1, 0);});
+ assertFail("bad type",
+ function(){gl.vertexAttribPointer(0, 3, gl.TEXTURE_2D, false, 0, 0);});
+ assertFail("bad index",
+ function(){gl.vertexAttribPointer(-1, 3, gl.FLOAT, false, 0, 0);});
+ assertFail("bad index (big negative)",
+ function(){gl.vertexAttribPointer(-8693948, 3, gl.FLOAT, false, 0, 0);});
+ assertFail("bad index (big positive)",
+ function(){gl.vertexAttribPointer(8693948, 3, gl.FLOAT, false, 0, 0);});
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ assertOk("binding to null buffer with offset=0",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);});
+ assertFail("binding to null buffer with offset!=0",
+ function(){gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 16);});
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(vbo);
+ throwError(gl);
+}
+
+</script>
+</head><body>
+</body></html>