summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/more
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/webgl-conf/checkout/conformance/more
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/more')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/00_test_list.txt54
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/README.md53
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests.html378
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_linkonly.html378
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_sequential.html378
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-A.js69
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B1.js61
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B2.js154
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B3.js68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B4.js71
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-C.js119
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-D_G.js235
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-G_I.js124
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-L_S.js122
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-S_V.js212
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/badArgsArityLessThanArgc.html576
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/constants.html350
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/fuzzTheAPI.html116
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/getContext.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/methods.html180
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-A.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B1.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B2.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B3.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B4.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-C.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-D_G.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-G_I.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-L_S.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-S_V.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI.js414
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPIBadArgs.html82
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/webGLArrays.html165
-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
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/arrayOutOfBounds.html258
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/uniformOutOfBounds.html196
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/index.html75
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/unit.css66
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/unit.js970
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/more/util.js1287
76 files changed, 11179 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/more/00_test_list.txt
new file mode 100644
index 0000000000..f202776ac5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/00_test_list.txt
@@ -0,0 +1,54 @@
+conformance/constants.html
+conformance/getContext.html
+conformance/methods.html
+conformance/quickCheckAPI-A.html
+conformance/quickCheckAPI-B1.html
+conformance/quickCheckAPI-B2.html
+conformance/quickCheckAPI-B3.html
+conformance/quickCheckAPI-B4.html
+conformance/quickCheckAPI-C.html
+conformance/quickCheckAPI-D_G.html
+conformance/quickCheckAPI-G_I.html
+conformance/quickCheckAPI-L_S.html
+conformance/quickCheckAPI-S_V.html
+conformance/webGLArrays.html
+functions/bindBuffer.html
+functions/bindBufferBadArgs.html
+functions/bindFramebufferLeaveNonZero.html
+functions/bufferData.html
+functions/bufferDataBadArgs.html
+functions/bufferSubData.html
+functions/bufferSubDataBadArgs.html
+functions/copyTexImage2D.html
+functions/copyTexImage2DBadArgs.html
+functions/copyTexSubImage2D.html
+functions/copyTexSubImage2DBadArgs.html
+functions/deleteBufferBadArgs.html
+functions/drawArrays.html
+functions/drawElements.html
+functions/isTests.html
+--min-version 1.0.2 functions/isTestsBadArgs.html
+functions/readPixels.html
+functions/readPixelsBadArgs.html
+functions/texImage2D.html
+functions/texImage2DBadArgs.html
+functions/texImage2DHTML.html
+functions/texImage2DHTMLBadArgs.html
+functions/texSubImage2D.html
+functions/texSubImage2DBadArgs.html
+functions/texSubImage2DHTML.html
+functions/texSubImage2DHTMLBadArgs.html
+functions/uniformf.html
+functions/uniformfBadArgs.html
+functions/uniformfArrayLen1.html
+functions/uniformi.html
+functions/uniformiBadArgs.html
+functions/uniformMatrix.html
+functions/uniformMatrixBadArgs.html
+functions/vertexAttrib.html
+functions/vertexAttribBadArgs.html
+functions/vertexAttribPointer.html
+functions/vertexAttribPointerBadArgs.html
+glsl/arrayOutOfBounds.html
+glsl/uniformOutOfBounds.html
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/README.md b/dom/canvas/test/webgl-conf/checkout/conformance/more/README.md
new file mode 100644
index 0000000000..01937147f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/README.md
@@ -0,0 +1,53 @@
+Tests for the WebGL canvas context
+==================================
+
+These tests are intended to serve the following purposes:
+
+ * Assert spec conformance
+ * Check the safety of the GL binding (bounds checking, same origin policy)
+ * Provide performance numbers for developers
+
+
+Running the tests
+-----------------
+
+ 1. <a href="http://learningwebgl.com/blog/?p=11">Install a browser with WebGL support</a>
+ 2. Run <code>ruby gen_tests.rb</code> if you have modified the tests.
+ 3. Run <code>ruby test_server.rb</code> if you want to get test run output to test_server's stdout (especially useful for finding out which test crashed your browser.)
+ 4. Open all_tests.html in your browser.
+
+
+Want to contribute?
+-------------------
+
+ 1. Fork this repo
+ 2. Run <code>gen_tests.rb</code>
+ 3. Look into templates/ to see which functions lack tests (also see <a href="../raw/master/methods.txt">methods.txt</a> and <a href="http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/canvas/nsICanvasRenderingContextWebGL.idl">nsICanvasRenderingContextWebGL.idl</a>):
+ 1. copy methodName.html to functions/methodName.html and write tests that test the results of valid inputs.
+ 2. copy methodNameBadArgs.html to functions/methodNameBadArgs.html and write tests to assert that invalid inputs throw exceptions.
+ 3. If your test causes a segfault, add the following to the top of the script tag: <code>Tests.autorun = false; Tests.message = "Caution: this may crash your browser";</code>
+ 4. For each performance test:
+ 1. Write a performance/myTestName.html and set <code>Tests.autorun = false;</code>
+ 5. If you have a test that you would like to run over the whole API or want to generate tests programmatically, add them to gen_tests.rb or write your own script.
+ 6. Create a commit for each file. (E.g. <code>for f in $(git status | grep -e "^#\\s*functions/\\S*$" | sed "s/^#\s*//"); do git add $f; git commit -m $f; done</code>)
+ 7. Send me a pull request.
+ 8. Congratulations, you're now a contributor!
+
+
+For more information on WebGL:
+
+ * <a href="http://planet-webgl.org">Planet WebGL</a>
+ * <a href="http://learningwebgl.com">Learning WebGL</a>
+ * <a href="http://www.khronos.org/message_boards/viewforum.php?f=34">WebGL on Khronos Message Boards</a>
+
+Developer links:
+
+ * <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=webgl">WebGL on Mozilla Bugzilla</a>
+ * <a href="https://bugzilla.webkit.org/buglist.cgi?quicksearch=webgl">WebGL on WebKit Bugzilla</a>
+ * <a href="http://code.google.com/p/chromium/issues/list?q=label:3D-WebGL">WebGL on Chromium Bugzilla</a>
+
+What's the stuff in apigen?
+
+ There are some Python scripts in the apigen/ directory that generate C++ based on the API definition files (gl2.h, api_modifications.txt, valid_args.txt.) The generated code is Mozilla XPCOM functions that check their args against the valid GLES 2.0 constants (as they were written on the man pages.) There's also some wackier stuff for checking copyTexImage2D and copyTexSubImage2D image dimensions against viewport dimensions.
+
+ If you can use it to generate code for your WebGL implementation, it might save you 1500 lines of typing and testing. The last time I used it was summer 2009 to generate a patch for Canvas 3D, so it's likely somewhat out of date.
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests.html
new file mode 100644
index 0000000000..d089c716f4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests.html
@@ -0,0 +1,378 @@
+<!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 ES 2.0 &lt;canvas&gt; context tests</title>
+ <style type="text/css">
+ h2 { display: inline; font-size: 1em; margin-bottom: 0.2em; }
+ iframe { display: inline; border: 1px solid black; overflow: hidden;}
+ </style>
+ <script type="application/javascript">
+ function loadTest(id, url) {
+ document.getElementById(id).src = url;
+ }
+ function seqLoader() {
+ var iframes = document.getElementsByTagName('iframe');
+ for (var i=0; i<iframes.length; i++) {
+ iframes[i].addEventListener('load', (function(j) {
+ return function() {
+ var e = document.getElementById((j+1)+'_link');
+ if (e) loadTest(j+1, e.href);
+ }
+ })(i), false);
+ }
+ var e = document.getElementById('0_link');
+ if (e) loadTest(0, e.href);
+ }
+ </script>
+</head>
+<body onload="seqLoader()">
+
+ <div>
+ <iframe src="conformance/badArgsArityLessThanArgc.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/badArgsArityLessThanArgc.html">conformance/badArgsArityLessThanArgc.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/constants.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/constants.html">conformance/constants.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/fuzzTheAPI.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/fuzzTheAPI.html">conformance/fuzzTheAPI.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/getContext.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/getContext.html">conformance/getContext.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/methods.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/methods.html">conformance/methods.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/quickCheckAPI.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/quickCheckAPI.html">conformance/quickCheckAPI.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/quickCheckAPIBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/quickCheckAPIBadArgs.html">conformance/quickCheckAPIBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="conformance/webGLArrays.html" width="110" height="42"></iframe>
+ <h2><a href="conformance/webGLArrays.html">conformance/webGLArrays.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bindBuffer.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bindBuffer.html">functions/bindBuffer.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bindBufferBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bindBufferBadArgs.html">functions/bindBufferBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bindFramebufferLeaveNonZero.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bindFramebufferLeaveNonZero.html">functions/bindFramebufferLeaveNonZero.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bufferData.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bufferData.html">functions/bufferData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bufferDataBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bufferDataBadArgs.html">functions/bufferDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bufferSubData.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bufferSubData.html">functions/bufferSubData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/bufferSubDataBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/bufferSubDataBadArgs.html">functions/bufferSubDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/copyTexImage2D.html" width="110" height="42"></iframe>
+ <h2><a href="functions/copyTexImage2D.html">functions/copyTexImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/copyTexImage2DBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/copyTexImage2DBadArgs.html">functions/copyTexImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/copyTexSubImage2D.html" width="110" height="42"></iframe>
+ <h2><a href="functions/copyTexSubImage2D.html">functions/copyTexSubImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/copyTexSubImage2DBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/copyTexSubImage2DBadArgs.html">functions/copyTexSubImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/deleteBufferBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/deleteBufferBadArgs.html">functions/deleteBufferBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/drawArrays.html" width="110" height="42"></iframe>
+ <h2><a href="functions/drawArrays.html">functions/drawArrays.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/drawArraysOutOfBounds.html" width="110" height="42"></iframe>
+ <h2><a href="functions/drawArraysOutOfBounds.html">functions/drawArraysOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/drawElements.html" width="110" height="42"></iframe>
+ <h2><a href="functions/drawElements.html">functions/drawElements.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/drawElementsBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/drawElementsBadArgs.html">functions/drawElementsBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/getImageData.html" width="110" height="42"></iframe>
+ <h2><a href="functions/getImageData.html">functions/getImageData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/getImageDataBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/getImageDataBadArgs.html">functions/getImageDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/isTests.html" width="110" height="42"></iframe>
+ <h2><a href="functions/isTests.html">functions/isTests.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/linkProgramBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/linkProgramBadArgs.html">functions/linkProgramBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/readPixels.html" width="110" height="42"></iframe>
+ <h2><a href="functions/readPixels.html">functions/readPixels.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/readPixelsBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/readPixelsBadArgs.html">functions/readPixelsBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texImage2D.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texImage2D.html">functions/texImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texImage2DBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texImage2DBadArgs.html">functions/texImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texImage2DHTML.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texImage2DHTML.html">functions/texImage2DHTML.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texImage2DHTMLBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texImage2DHTMLBadArgs.html">functions/texImage2DHTMLBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texSubImage2D.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texSubImage2D.html">functions/texSubImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texSubImage2DBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texSubImage2DBadArgs.html">functions/texSubImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texSubImage2DHTML.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texSubImage2DHTML.html">functions/texSubImage2DHTML.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/texSubImage2DHTMLBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/texSubImage2DHTMLBadArgs.html">functions/texSubImage2DHTMLBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/uniformMatrix.html" width="110" height="42"></iframe>
+ <h2><a href="functions/uniformMatrix.html">functions/uniformMatrix.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/uniformMatrixBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/uniformMatrixBadArgs.html">functions/uniformMatrixBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/uniformf.html" width="110" height="42"></iframe>
+ <h2><a href="functions/uniformf.html">functions/uniformf.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/uniformfBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/uniformfBadArgs.html">functions/uniformfBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/uniformi.html" width="110" height="42"></iframe>
+ <h2><a href="functions/uniformi.html">functions/uniformi.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/uniformiBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/uniformiBadArgs.html">functions/uniformiBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/vertexAttrib.html" width="110" height="42"></iframe>
+ <h2><a href="functions/vertexAttrib.html">functions/vertexAttrib.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/vertexAttribBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/vertexAttribBadArgs.html">functions/vertexAttribBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/vertexAttribPointer.html" width="110" height="42"></iframe>
+ <h2><a href="functions/vertexAttribPointer.html">functions/vertexAttribPointer.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="functions/vertexAttribPointerBadArgs.html" width="110" height="42"></iframe>
+ <h2><a href="functions/vertexAttribPointerBadArgs.html">functions/vertexAttribPointerBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="performance/CPUvsGPU.html" width="110" height="42"></iframe>
+ <h2><a href="performance/CPUvsGPU.html">performance/CPUvsGPU.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="performance/bandwidth.html" width="110" height="42"></iframe>
+ <h2><a href="performance/bandwidth.html">performance/bandwidth.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="performance/jsGCPause.html" width="110" height="42"></iframe>
+ <h2><a href="performance/jsGCPause.html">performance/jsGCPause.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="performance/jsMatrixMult.html" width="110" height="42"></iframe>
+ <h2><a href="performance/jsMatrixMult.html">performance/jsMatrixMult.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="performance/jsToGLOverhead.html" width="110" height="42"></iframe>
+ <h2><a href="performance/jsToGLOverhead.html">performance/jsToGLOverhead.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="glsl/arrayOutOfBounds.html" width="110" height="42"></iframe>
+ <h2><a href="glsl/arrayOutOfBounds.html">glsl/arrayOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="glsl/longLoops.html" width="110" height="42"></iframe>
+ <h2><a href="glsl/longLoops.html">glsl/longLoops.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="glsl/uniformOutOfBounds.html" width="110" height="42"></iframe>
+ <h2><a href="glsl/uniformOutOfBounds.html">glsl/uniformOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe src="glsl/unusedAttribsUniforms.html" width="110" height="42"></iframe>
+ <h2><a href="glsl/unusedAttribsUniforms.html">glsl/unusedAttribsUniforms.html</a></h2>
+ </div>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_linkonly.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_linkonly.html
new file mode 100644
index 0000000000..0ec563b028
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_linkonly.html
@@ -0,0 +1,378 @@
+<!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 ES 2.0 &lt;canvas&gt; context tests</title>
+ <style type="text/css">
+ h2 { display: inline; font-size: 1em; margin-bottom: 0.2em; }
+ iframe { display: inline; border: 1px solid black; overflow: hidden;}
+ </style>
+ <script type="application/javascript">
+ function loadTest(id, url) {
+ document.getElementById(id).src = url;
+ }
+ function seqLoader() {
+ var iframes = document.getElementsByTagName('iframe');
+ for (var i=0; i<iframes.length; i++) {
+ iframes[i].addEventListener('load', (function(j) {
+ return function() {
+ var e = document.getElementById((j+1)+'_link');
+ if (e) loadTest(j+1, e.href);
+ }
+ })(i), false);
+ }
+ var e = document.getElementById('0_link');
+ if (e) loadTest(0, e.href);
+ }
+ </script>
+</head>
+<body onload="seqLoader()">
+
+ <div>
+ <iframe id="0" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(0, 'conformance/badArgsArityLessThanArgc.html');return false" href="conformance/badArgsArityLessThanArgc.html">conformance/badArgsArityLessThanArgc.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="1" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(1, 'conformance/constants.html');return false" href="conformance/constants.html">conformance/constants.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="2" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(2, 'conformance/fuzzTheAPI.html');return false" href="conformance/fuzzTheAPI.html">conformance/fuzzTheAPI.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="3" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(3, 'conformance/getContext.html');return false" href="conformance/getContext.html">conformance/getContext.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="4" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(4, 'conformance/methods.html');return false" href="conformance/methods.html">conformance/methods.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="5" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(5, 'conformance/quickCheckAPI.html');return false" href="conformance/quickCheckAPI.html">conformance/quickCheckAPI.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="6" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(6, 'conformance/quickCheckAPIBadArgs.html');return false" href="conformance/quickCheckAPIBadArgs.html">conformance/quickCheckAPIBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="7" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(7, 'conformance/webGLArrays.html');return false" href="conformance/webGLArrays.html">conformance/webGLArrays.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="8" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(8, 'functions/bindBuffer.html');return false" href="functions/bindBuffer.html">functions/bindBuffer.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="9" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(9, 'functions/bindBufferBadArgs.html');return false" href="functions/bindBufferBadArgs.html">functions/bindBufferBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="10" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(10, 'functions/bindFramebufferLeaveNonZero.html');return false" href="functions/bindFramebufferLeaveNonZero.html">functions/bindFramebufferLeaveNonZero.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="11" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(11, 'functions/bufferData.html');return false" href="functions/bufferData.html">functions/bufferData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="12" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(12, 'functions/bufferDataBadArgs.html');return false" href="functions/bufferDataBadArgs.html">functions/bufferDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="13" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(13, 'functions/bufferSubData.html');return false" href="functions/bufferSubData.html">functions/bufferSubData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="14" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(14, 'functions/bufferSubDataBadArgs.html');return false" href="functions/bufferSubDataBadArgs.html">functions/bufferSubDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="15" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(15, 'functions/copyTexImage2D.html');return false" href="functions/copyTexImage2D.html">functions/copyTexImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="16" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(16, 'functions/copyTexImage2DBadArgs.html');return false" href="functions/copyTexImage2DBadArgs.html">functions/copyTexImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="17" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(17, 'functions/copyTexSubImage2D.html');return false" href="functions/copyTexSubImage2D.html">functions/copyTexSubImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="18" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(18, 'functions/copyTexSubImage2DBadArgs.html');return false" href="functions/copyTexSubImage2DBadArgs.html">functions/copyTexSubImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="19" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(19, 'functions/deleteBufferBadArgs.html');return false" href="functions/deleteBufferBadArgs.html">functions/deleteBufferBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="20" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(20, 'functions/drawArrays.html');return false" href="functions/drawArrays.html">functions/drawArrays.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="21" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(21, 'functions/drawArraysOutOfBounds.html');return false" href="functions/drawArraysOutOfBounds.html">functions/drawArraysOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="22" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(22, 'functions/drawElements.html');return false" href="functions/drawElements.html">functions/drawElements.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="23" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(23, 'functions/drawElementsBadArgs.html');return false" href="functions/drawElementsBadArgs.html">functions/drawElementsBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="24" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(24, 'functions/getImageData.html');return false" href="functions/getImageData.html">functions/getImageData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="25" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(25, 'functions/getImageDataBadArgs.html');return false" href="functions/getImageDataBadArgs.html">functions/getImageDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="26" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(26, 'functions/isTests.html');return false" href="functions/isTests.html">functions/isTests.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="27" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(27, 'functions/linkProgramBadArgs.html');return false" href="functions/linkProgramBadArgs.html">functions/linkProgramBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="28" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(28, 'functions/readPixels.html');return false" href="functions/readPixels.html">functions/readPixels.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="29" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(29, 'functions/readPixelsBadArgs.html');return false" href="functions/readPixelsBadArgs.html">functions/readPixelsBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="30" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(30, 'functions/texImage2D.html');return false" href="functions/texImage2D.html">functions/texImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="31" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(31, 'functions/texImage2DBadArgs.html');return false" href="functions/texImage2DBadArgs.html">functions/texImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="32" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(32, 'functions/texImage2DHTML.html');return false" href="functions/texImage2DHTML.html">functions/texImage2DHTML.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="33" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(33, 'functions/texImage2DHTMLBadArgs.html');return false" href="functions/texImage2DHTMLBadArgs.html">functions/texImage2DHTMLBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="34" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(34, 'functions/texSubImage2D.html');return false" href="functions/texSubImage2D.html">functions/texSubImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="35" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(35, 'functions/texSubImage2DBadArgs.html');return false" href="functions/texSubImage2DBadArgs.html">functions/texSubImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="36" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(36, 'functions/texSubImage2DHTML.html');return false" href="functions/texSubImage2DHTML.html">functions/texSubImage2DHTML.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="37" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(37, 'functions/texSubImage2DHTMLBadArgs.html');return false" href="functions/texSubImage2DHTMLBadArgs.html">functions/texSubImage2DHTMLBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="38" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(38, 'functions/uniformMatrix.html');return false" href="functions/uniformMatrix.html">functions/uniformMatrix.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="39" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(39, 'functions/uniformMatrixBadArgs.html');return false" href="functions/uniformMatrixBadArgs.html">functions/uniformMatrixBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="40" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(40, 'functions/uniformf.html');return false" href="functions/uniformf.html">functions/uniformf.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="41" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(41, 'functions/uniformfBadArgs.html');return false" href="functions/uniformfBadArgs.html">functions/uniformfBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="42" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(42, 'functions/uniformi.html');return false" href="functions/uniformi.html">functions/uniformi.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="43" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(43, 'functions/uniformiBadArgs.html');return false" href="functions/uniformiBadArgs.html">functions/uniformiBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="44" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(44, 'functions/vertexAttrib.html');return false" href="functions/vertexAttrib.html">functions/vertexAttrib.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="45" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(45, 'functions/vertexAttribBadArgs.html');return false" href="functions/vertexAttribBadArgs.html">functions/vertexAttribBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="46" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(46, 'functions/vertexAttribPointer.html');return false" href="functions/vertexAttribPointer.html">functions/vertexAttribPointer.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="47" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(47, 'functions/vertexAttribPointerBadArgs.html');return false" href="functions/vertexAttribPointerBadArgs.html">functions/vertexAttribPointerBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="48" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(48, 'performance/CPUvsGPU.html');return false" href="performance/CPUvsGPU.html">performance/CPUvsGPU.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="49" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(49, 'performance/bandwidth.html');return false" href="performance/bandwidth.html">performance/bandwidth.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="50" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(50, 'performance/jsGCPause.html');return false" href="performance/jsGCPause.html">performance/jsGCPause.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="51" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(51, 'performance/jsMatrixMult.html');return false" href="performance/jsMatrixMult.html">performance/jsMatrixMult.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="52" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(52, 'performance/jsToGLOverhead.html');return false" href="performance/jsToGLOverhead.html">performance/jsToGLOverhead.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="53" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(53, 'glsl/arrayOutOfBounds.html');return false" href="glsl/arrayOutOfBounds.html">glsl/arrayOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="54" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(54, 'glsl/longLoops.html');return false" href="glsl/longLoops.html">glsl/longLoops.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="55" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(55, 'glsl/uniformOutOfBounds.html');return false" href="glsl/uniformOutOfBounds.html">glsl/uniformOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="56" width="110" height="42"></iframe>
+ <h2><a onclick="loadTest(56, 'glsl/unusedAttribsUniforms.html');return false" href="glsl/unusedAttribsUniforms.html">glsl/unusedAttribsUniforms.html</a></h2>
+ </div>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_sequential.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_sequential.html
new file mode 100644
index 0000000000..5ebf8382ba
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_sequential.html
@@ -0,0 +1,378 @@
+<!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 ES 2.0 &lt;canvas&gt; context tests</title>
+ <style type="text/css">
+ h2 { display: inline; font-size: 1em; margin-bottom: 0.2em; }
+ iframe { display: inline; border: 1px solid black; overflow: hidden;}
+ </style>
+ <script type="application/javascript">
+ function loadTest(id, url) {
+ document.getElementById(id).src = url;
+ }
+ function seqLoader() {
+ var iframes = document.getElementsByTagName('iframe');
+ for (var i=0; i<iframes.length; i++) {
+ iframes[i].addEventListener('load', (function(j) {
+ return function() {
+ var e = document.getElementById((j+1)+'_link');
+ if (e) loadTest(j+1, e.href);
+ }
+ })(i), false);
+ }
+ var e = document.getElementById('0_link');
+ if (e) loadTest(0, e.href);
+ }
+ </script>
+</head>
+<body onload="seqLoader()">
+
+ <div>
+ <iframe id="0" width="110" height="42"></iframe>
+ <h2><a id="0_link" href="conformance/badArgsArityLessThanArgc.html">conformance/badArgsArityLessThanArgc.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="1" width="110" height="42"></iframe>
+ <h2><a id="1_link" href="conformance/constants.html">conformance/constants.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="2" width="110" height="42"></iframe>
+ <h2><a id="2_link" href="conformance/fuzzTheAPI.html">conformance/fuzzTheAPI.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="3" width="110" height="42"></iframe>
+ <h2><a id="3_link" href="conformance/getContext.html">conformance/getContext.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="4" width="110" height="42"></iframe>
+ <h2><a id="4_link" href="conformance/methods.html">conformance/methods.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="5" width="110" height="42"></iframe>
+ <h2><a id="5_link" href="conformance/quickCheckAPI.html">conformance/quickCheckAPI.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="6" width="110" height="42"></iframe>
+ <h2><a id="6_link" href="conformance/quickCheckAPIBadArgs.html">conformance/quickCheckAPIBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="7" width="110" height="42"></iframe>
+ <h2><a id="7_link" href="conformance/webGLArrays.html">conformance/webGLArrays.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="8" width="110" height="42"></iframe>
+ <h2><a id="8_link" href="functions/bindBuffer.html">functions/bindBuffer.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="9" width="110" height="42"></iframe>
+ <h2><a id="9_link" href="functions/bindBufferBadArgs.html">functions/bindBufferBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="10" width="110" height="42"></iframe>
+ <h2><a id="10_link" href="functions/bindFramebufferLeaveNonZero.html">functions/bindFramebufferLeaveNonZero.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="11" width="110" height="42"></iframe>
+ <h2><a id="11_link" href="functions/bufferData.html">functions/bufferData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="12" width="110" height="42"></iframe>
+ <h2><a id="12_link" href="functions/bufferDataBadArgs.html">functions/bufferDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="13" width="110" height="42"></iframe>
+ <h2><a id="13_link" href="functions/bufferSubData.html">functions/bufferSubData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="14" width="110" height="42"></iframe>
+ <h2><a id="14_link" href="functions/bufferSubDataBadArgs.html">functions/bufferSubDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="15" width="110" height="42"></iframe>
+ <h2><a id="15_link" href="functions/copyTexImage2D.html">functions/copyTexImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="16" width="110" height="42"></iframe>
+ <h2><a id="16_link" href="functions/copyTexImage2DBadArgs.html">functions/copyTexImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="17" width="110" height="42"></iframe>
+ <h2><a id="17_link" href="functions/copyTexSubImage2D.html">functions/copyTexSubImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="18" width="110" height="42"></iframe>
+ <h2><a id="18_link" href="functions/copyTexSubImage2DBadArgs.html">functions/copyTexSubImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="19" width="110" height="42"></iframe>
+ <h2><a id="19_link" href="functions/deleteBufferBadArgs.html">functions/deleteBufferBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="20" width="110" height="42"></iframe>
+ <h2><a id="20_link" href="functions/drawArrays.html">functions/drawArrays.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="21" width="110" height="42"></iframe>
+ <h2><a id="21_link" href="functions/drawArraysOutOfBounds.html">functions/drawArraysOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="22" width="110" height="42"></iframe>
+ <h2><a id="22_link" href="functions/drawElements.html">functions/drawElements.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="23" width="110" height="42"></iframe>
+ <h2><a id="23_link" href="functions/drawElementsBadArgs.html">functions/drawElementsBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="24" width="110" height="42"></iframe>
+ <h2><a id="24_link" href="functions/getImageData.html">functions/getImageData.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="25" width="110" height="42"></iframe>
+ <h2><a id="25_link" href="functions/getImageDataBadArgs.html">functions/getImageDataBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="26" width="110" height="42"></iframe>
+ <h2><a id="26_link" href="functions/isTests.html">functions/isTests.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="27" width="110" height="42"></iframe>
+ <h2><a id="27_link" href="functions/linkProgramBadArgs.html">functions/linkProgramBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="28" width="110" height="42"></iframe>
+ <h2><a id="28_link" href="functions/readPixels.html">functions/readPixels.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="29" width="110" height="42"></iframe>
+ <h2><a id="29_link" href="functions/readPixelsBadArgs.html">functions/readPixelsBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="30" width="110" height="42"></iframe>
+ <h2><a id="30_link" href="functions/texImage2D.html">functions/texImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="31" width="110" height="42"></iframe>
+ <h2><a id="31_link" href="functions/texImage2DBadArgs.html">functions/texImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="32" width="110" height="42"></iframe>
+ <h2><a id="32_link" href="functions/texImage2DHTML.html">functions/texImage2DHTML.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="33" width="110" height="42"></iframe>
+ <h2><a id="33_link" href="functions/texImage2DHTMLBadArgs.html">functions/texImage2DHTMLBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="34" width="110" height="42"></iframe>
+ <h2><a id="34_link" href="functions/texSubImage2D.html">functions/texSubImage2D.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="35" width="110" height="42"></iframe>
+ <h2><a id="35_link" href="functions/texSubImage2DBadArgs.html">functions/texSubImage2DBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="36" width="110" height="42"></iframe>
+ <h2><a id="36_link" href="functions/texSubImage2DHTML.html">functions/texSubImage2DHTML.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="37" width="110" height="42"></iframe>
+ <h2><a id="37_link" href="functions/texSubImage2DHTMLBadArgs.html">functions/texSubImage2DHTMLBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="38" width="110" height="42"></iframe>
+ <h2><a id="38_link" href="functions/uniformMatrix.html">functions/uniformMatrix.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="39" width="110" height="42"></iframe>
+ <h2><a id="39_link" href="functions/uniformMatrixBadArgs.html">functions/uniformMatrixBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="40" width="110" height="42"></iframe>
+ <h2><a id="40_link" href="functions/uniformf.html">functions/uniformf.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="41" width="110" height="42"></iframe>
+ <h2><a id="41_link" href="functions/uniformfBadArgs.html">functions/uniformfBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="42" width="110" height="42"></iframe>
+ <h2><a id="42_link" href="functions/uniformi.html">functions/uniformi.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="43" width="110" height="42"></iframe>
+ <h2><a id="43_link" href="functions/uniformiBadArgs.html">functions/uniformiBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="44" width="110" height="42"></iframe>
+ <h2><a id="44_link" href="functions/vertexAttrib.html">functions/vertexAttrib.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="45" width="110" height="42"></iframe>
+ <h2><a id="45_link" href="functions/vertexAttribBadArgs.html">functions/vertexAttribBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="46" width="110" height="42"></iframe>
+ <h2><a id="46_link" href="functions/vertexAttribPointer.html">functions/vertexAttribPointer.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="47" width="110" height="42"></iframe>
+ <h2><a id="47_link" href="functions/vertexAttribPointerBadArgs.html">functions/vertexAttribPointerBadArgs.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="48" width="110" height="42"></iframe>
+ <h2><a id="48_link" href="performance/CPUvsGPU.html">performance/CPUvsGPU.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="49" width="110" height="42"></iframe>
+ <h2><a id="49_link" href="performance/bandwidth.html">performance/bandwidth.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="50" width="110" height="42"></iframe>
+ <h2><a id="50_link" href="performance/jsGCPause.html">performance/jsGCPause.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="51" width="110" height="42"></iframe>
+ <h2><a id="51_link" href="performance/jsMatrixMult.html">performance/jsMatrixMult.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="52" width="110" height="42"></iframe>
+ <h2><a id="52_link" href="performance/jsToGLOverhead.html">performance/jsToGLOverhead.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="53" width="110" height="42"></iframe>
+ <h2><a id="53_link" href="glsl/arrayOutOfBounds.html">glsl/arrayOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="54" width="110" height="42"></iframe>
+ <h2><a id="54_link" href="glsl/longLoops.html">glsl/longLoops.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="55" width="110" height="42"></iframe>
+ <h2><a id="55_link" href="glsl/uniformOutOfBounds.html">glsl/uniformOutOfBounds.html</a></h2>
+ </div>
+
+
+ <div>
+ <iframe id="56" width="110" height="42"></iframe>
+ <h2><a id="56_link" href="glsl/unusedAttribsUniforms.html">glsl/unusedAttribsUniforms.html</a></h2>
+ </div>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-A.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-A.js
new file mode 100644
index 0000000000..c3e301ce14
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-A.js
@@ -0,0 +1,69 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// A
+
+ activeTexture : {
+ generate : function() { return [textureUnit.random()]; },
+ checkArgValidity : function(t) { return textureUnit.has(t); },
+ teardown : function() { GL.activeTexture(GL.TEXTURE0); }
+ },
+ attachShader : {
+ generate : function() {
+ var p = GL.createProgram();
+ var sh = GL.createShader(shaderType.random());
+ return [p, sh];
+ },
+ checkArgValidity : function(p, sh) {
+ return GL.isProgram(p) && GL.isShader(sh) && !GL.getAttachedShaders(p).has(sh);
+ },
+ cleanup : function(p, sh) {
+ try {GL.detachShader(p,sh);} catch(e) {}
+ try {GL.deleteProgram(p);} catch(e) {}
+ try {GL.deleteShader(sh);} catch(e) {}
+ }
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B1.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B1.js
new file mode 100644
index 0000000000..04f394be02
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B1.js
@@ -0,0 +1,61 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// B-1
+
+ bindAttribLocation : {
+ generate : function() {
+ var program = GL.createProgram();
+ return [program, randomVertexAttribute(), randomName()];
+ },
+ checkArgValidity : function(program, index, name) {
+ return GL.isProgram(program) && isVertexAttribute(index) && isValidName(name);
+ },
+ cleanup : function(program, index, name) {
+ try { GL.deleteProgram(program); } catch(e) {}
+ }
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B2.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B2.js
new file mode 100644
index 0000000000..f366c3d8f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B2.js
@@ -0,0 +1,154 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// B-2
+
+ bindBuffer : {
+ generate : function(buf) {
+ return [bufferTarget.random(), GL.createBuffer()];
+ },
+ checkArgValidity : function(target, buf) {
+ if (!bufferTarget.has(target))
+ return false;
+ GL.bindBuffer(target, buf);
+ return GL.isBuffer(buf);
+ },
+ cleanup : function(t, buf, m) {
+ GL.deleteBuffer(buf);
+ }
+ },
+ bindFramebuffer : {
+ generate : function() {
+ return [GL.FRAMEBUFFER, Math.random() > 0.5 ? null : GL.createFramebuffer()];
+ },
+ checkArgValidity : function(target, fbo) {
+ if (target != GL.FRAMEBUFFER)
+ return false;
+ if (fbo != null)
+ GL.bindFramebuffer(target, fbo);
+ return (fbo == null || GL.isFramebuffer(fbo));
+ },
+ cleanup : function(target, fbo) {
+ GL.bindFramebuffer(target, null);
+ if (fbo)
+ GL.deleteFramebuffer(fbo);
+ }
+ },
+ bindRenderbuffer : {
+ generate : function() {
+ return [GL.RENDERBUFFER, Math.random() > 0.5 ? null : GL.createRenderbuffer()];
+ },
+ checkArgValidity : function(target, rbo) {
+ if (target != GL.RENDERBUFFER)
+ return false;
+ if (rbo != null)
+ GL.bindRenderbuffer(target, rbo);
+ return (rbo == null || GL.isRenderbuffer(rbo));
+ },
+ cleanup : function(target, rbo) {
+ GL.bindRenderbuffer(target, null);
+ if (rbo)
+ GL.deleteRenderbuffer(rbo);
+ }
+ },
+ bindTexture : {
+ generate : function() {
+ return [bindTextureTarget.random(), Math.random() > 0.5 ? null : GL.createTexture()];
+ },
+ checkArgValidity : function(target, o) {
+ if (!bindTextureTarget.has(target))
+ return false;
+ if (o != null)
+ GL.bindTexture(target, o);
+ return (o == null || GL.isTexture(o));
+ },
+ cleanup : function(target, o) {
+ GL.bindTexture(target, null);
+ if (o)
+ GL.deleteTexture(o);
+ }
+ },
+ blendColor : {
+ generate : function() { return randomColor(); },
+ teardown : function() { GL.blendColor(0,0,0,0); }
+ },
+ blendEquation : {
+ generate : function() { return [blendEquationMode.random()]; },
+ checkArgValidity : function(o) { return blendEquationMode.has(o); },
+ teardown : function() { GL.blendEquation(GL.FUNC_ADD); }
+ },
+ blendEquationSeparate : {
+ generate : function() {
+ return [blendEquationMode.random(), blendEquationMode.random()];
+ },
+ checkArgValidity : function(o,p) {
+ return blendEquationMode.has(o) && blendEquationMode.has(p);
+ },
+ teardown : function() { GL.blendEquationSeparate(GL.FUNC_ADD, GL.FUNC_ADD); }
+ },
+ blendFunc : {
+ generate : function() {
+ return [blendFuncSfactor.random(), blendFuncDfactor.random()];
+ },
+ checkArgValidity : function(s,d) {
+ return blendFuncSfactor.has(s) && blendFuncDfactor.has(d);
+ },
+ teardown : function() { GL.blendFunc(GL.ONE, GL.ZERO); }
+ },
+ blendFuncSeparate : {
+ generate : function() {
+ return [blendFuncSfactor.random(), blendFuncDfactor.random(),
+ blendFuncSfactor.random(), blendFuncDfactor.random()];
+ },
+ checkArgValidity : function(s,d,as,ad) {
+ return blendFuncSfactor.has(s) && blendFuncDfactor.has(d) &&
+ blendFuncSfactor.has(as) && blendFuncDfactor.has(ad) ;
+ },
+ teardown : function() {
+ GL.blendFuncSeparate(GL.ONE, GL.ZERO, GL.ONE, GL.ZERO);
+ }
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B3.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B3.js
new file mode 100644
index 0000000000..2a4796d914
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B3.js
@@ -0,0 +1,68 @@
+/*
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// B-3
+
+ bufferData : {
+ setup : function() {
+ var buf = GL.createBuffer();
+ var ebuf = GL.createBuffer();
+ GL.bindBuffer(GL.ARRAY_BUFFER, buf);
+ GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ebuf);
+ return [buf, ebuf];
+ },
+ generate : function(buf, ebuf) {
+ return [bufferTarget.random(), randomBufferData(), bufferMode.random()];
+ },
+ checkArgValidity : function(target, bufData, mode) {
+ return bufferTarget.has(target) && isBufferData(bufData) && bufferMode.has(mode);
+ },
+ teardown : function(buf, ebuf) {
+ GL.deleteBuffer(buf);
+ GL.deleteBuffer(ebuf);
+ },
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B4.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B4.js
new file mode 100644
index 0000000000..4c1ca7d8b9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B4.js
@@ -0,0 +1,71 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// B-4
+
+ bufferSubData : {
+ setup : function() {
+ var buf = GL.createBuffer();
+ var ebuf = GL.createBuffer();
+ GL.bindBuffer(GL.ARRAY_BUFFER, buf);
+ GL.bufferData(GL.ARRAY_BUFFER, 256, GL.STATIC_DRAW);
+ GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ebuf);
+ GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, 256, GL.STATIC_DRAW);
+ return [buf, ebuf];
+ },
+ generate : function(buf, ebuf) {
+ var d = randomBufferSubData(256);
+ return [bufferTarget.random(), d.offset, d.data];
+ },
+ checkArgValidity : function(target, offset, data) {
+ return bufferTarget.has(target) && offset >= 0 && data.byteLength >= 0 && offset + data.byteLength <= 256;
+ },
+ teardown : function(buf, ebuf) {
+ GL.deleteBuffer(buf);
+ GL.deleteBuffer(ebuf);
+ },
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-C.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-C.js
new file mode 100644
index 0000000000..fbe1c2a5c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-C.js
@@ -0,0 +1,119 @@
+/*
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// C
+
+ checkFramebufferStatus : {
+ generate : function() {
+ return [Math.random() > 0.5 ? null : GL.createFramebuffer()];
+ },
+ checkArgValidity : function(fbo) {
+ if (fbo != null)
+ GL.bindFramebuffer(GL.FRAMEBUFFER, fbo);
+ return fbo == null || GL.isFramebuffer(fbo);
+ },
+ cleanup : function(fbo){
+ GL.bindFramebuffer(GL.FRAMEBUFFER, null);
+ if (fbo != null)
+ try{ GL.deleteFramebuffer(fbo); } catch(e) {}
+ }
+ },
+ clear : {
+ generate : function() { return [clearMask.random()]; },
+ checkArgValidity : function(mask) { return clearMask.has(mask); }
+ },
+ clearColor : {
+ generate : function() { return randomColor(); },
+ teardown : function() { GL.clearColor(0,0,0,0); }
+ },
+ clearDepth : {
+ generate : function() { return [Math.random()]; },
+ teardown : function() { GL.clearDepth(1); }
+ },
+ clearStencil : {
+ generate : function() { return [randomStencil()]; },
+ teardown : function() { GL.clearStencil(0); }
+ },
+ colorMask : {
+ generate : function() {
+ return [randomBool(), randomBool(), randomBool(), randomBool()];
+ },
+ teardown : function() { GL.colorMask(true, true, true, true); }
+ },
+ compileShader : {}, // FIXME
+ copyTexImage2D : {}, // FIXME
+ copyTexSubImage2D : {}, // FIXME
+ createBuffer : {
+ generate : function() { return []; },
+ returnValueCleanup : function(o) { GL.deleteBuffer(o); }
+ },
+ createFramebuffer : {
+ generate : function() { return []; },
+ returnValueCleanup : function(o) { GL.deleteFramebuffer(o); }
+ },
+ createProgram : {
+ generate : function() { return []; },
+ returnValueCleanup : function(o) { GL.deleteProgram(o); }
+ },
+ createRenderbuffer : {
+ generate : function() { return []; },
+ returnValueCleanup : function(o) { GL.deleteRenderbuffer(o); }
+ },
+ createShader : {
+ generate : function() { return [shaderType.random()]; },
+ checkArgValidity : function(t) { return shaderType.has(t); },
+ returnValueCleanup : function(o) { GL.deleteShader(o); }
+ },
+ createTexture : {
+ generate : function() { return []; },
+ returnValueCleanup : function(o) { GL.deleteTexture(o); }
+ },
+ cullFace : {
+ generate : function() { return [cullFace.random()]; },
+ checkArgValidity : function(f) { return cullFace.has(f); },
+ teardown : function() { GL.cullFace(GL.BACK); }
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-D_G.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-D_G.js
new file mode 100644
index 0000000000..00e602002f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-D_G.js
@@ -0,0 +1,235 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// D
+
+ deleteBuffer : {
+ generate : function() { return [GL.createBuffer()]; },
+ checkArgValidity : function(o) {
+ GL.bindBuffer(GL.ARRAY_BUFFER, o);
+ return GL.isBuffer(o);
+ },
+ cleanup : function(o) {
+ GL.bindBuffer(GL.ARRAY_BUFFER, null);
+ try { GL.deleteBuffer(o); } catch(e) {}
+ }
+ },
+ deleteFramebuffer : {
+ generate : function() { return [GL.createFramebuffer()]; },
+ checkArgValidity : function(o) {
+ GL.bindFramebuffer(GL.FRAMEBUFFER, o);
+ return GL.isFramebuffer(o);
+ },
+ cleanup : function(o) {
+ GL.bindFramebuffer(GL.FRAMEBUFFER, null);
+ try { GL.deleteFramebuffer(o); } catch(e) {}
+ }
+ },
+ deleteProgram : {
+ generate : function() { return [GL.createProgram()]; },
+ checkArgValidity : function(o) { return GL.isProgram(o); },
+ cleanup : function(o) { try { GL.deleteProgram(o); } catch(e) {} }
+ },
+ deleteRenderbuffer : {
+ generate : function() { return [GL.createRenderbuffer()]; },
+ checkArgValidity : function(o) {
+ GL.bindRenderbuffer(GL.RENDERBUFFER, o);
+ return GL.isRenderbuffer(o);
+ },
+ cleanup : function(o) {
+ GL.bindRenderbuffer(GL.RENDERBUFFER, null);
+ try { GL.deleteRenderbuffer(o); } catch(e) {}
+ }
+ },
+ deleteShader : {
+ generate : function() { return [GL.createShader(shaderType.random())]; },
+ checkArgValidity : function(o) { return GL.isShader(o); },
+ cleanup : function(o) { try { GL.deleteShader(o); } catch(e) {} }
+ },
+ deleteTexture : {
+ generate : function() { return [GL.createTexture()]; },
+ checkArgValidity : function(o) {
+ GL.bindTexture(GL.TEXTURE_2D, o);
+ return GL.isTexture(o);
+ },
+ cleanup : function(o) {
+ GL.bindTexture(GL.TEXTURE_2D, null);
+ try { GL.deleteTexture(o); } catch(e) {}
+ }
+ },
+ depthFunc : {
+ generate : function() { return [depthFuncFunc.random()]; },
+ checkArgValidity : function(f) { return depthFuncFunc.has(f); },
+ teardown : function() { GL.depthFunc(GL.LESS); }
+ },
+ depthMask : {
+ generate : function() { return [randomBool()]; },
+ teardown : function() { GL.depthFunc(GL.TRUE); }
+ },
+ depthRange : {
+ generate : function() { return [Math.random(), Math.random()]; },
+ teardown : function() { GL.depthRange(0, 1); }
+ },
+ detachShader : {
+ generate : function() {
+ var p = GL.createProgram();
+ var sh = GL.createShader(shaderType.random());
+ GL.attachShader(p, sh);
+ return [p, sh];
+ },
+ checkArgValidity : function(p, sh) {
+ return GL.isProgram(p) && GL.isShader(sh) && GL.getAttachedShaders(p).has(sh);
+ },
+ cleanup : function(p, sh) {
+ try {GL.deleteProgram(p);} catch(e) {}
+ try {GL.deleteShader(sh);} catch(e) {}
+ }
+ },
+ disable : {
+ generate : function() { return [enableCap.random()]; },
+ checkArgValidity : function(c) { return enableCap.has(c); },
+ cleanup : function(c) { if (c == GL.DITHER) GL.enable(c); }
+ },
+ disableVertexAttribArray : {
+ generate : function() { return [randomVertexAttribute()]; },
+ checkArgValidity : function(v) { return isVertexAttribute(v); }
+ },
+ drawArrays : {}, // FIXME
+ drawElements : {}, // FIXME
+
+// E
+
+ enable : {
+ generate : function() { return [enableCap.random()]; },
+ checkArgValidity : function(c) { return enableCap.has(c); },
+ cleanup : function(c) { if (c != GL.DITHER) GL.disable(c); }
+ },
+ enableVertexAttribArray : {
+ generate : function() { return [randomVertexAttribute()]; },
+ checkArgValidity : function(v) { return isVertexAttribute(castToInt(v)); },
+ cleanup : function(v) { GL.disableVertexAttribArray(v); }
+ },
+
+// F
+
+ finish : {
+ generate : function() { return []; }
+ },
+ flush : {
+ generate : function() { return []; }
+ },
+ framebufferRenderbuffer : {}, // FIXME
+ framebufferTexture2D : {}, // FIXME
+ frontFace : {
+ generate : function() { return [frontFaceMode.random()]; },
+ checkArgValidity : function(c) { return frontFaceMode.has(c); },
+ cleanup : function(c) { GL.frontFace(GL.CCW); }
+ },
+
+// G-1
+
+ generateMipmap : {
+ setup : function() {
+ var tex = GL.createTexture();
+ var tex2 = GL.createTexture();
+ GL.bindTexture(GL.TEXTURE_2D, tex);
+ GL.bindTexture(GL.TEXTURE_CUBE_MAP, tex2);
+ var pix = new Uint8Array(16*16*4);
+ GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ GL.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ GL.texImage2D(GL.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ GL.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ GL.texImage2D(GL.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ GL.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ GL.texImage2D(GL.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL.RGBA, 16, 16, 0, GL.RGBA, GL.UNSIGNED_BYTE, pix);
+ },
+ generate : function() { return [bindTextureTarget.random()]; },
+ checkArgValidity : function(t) { return bindTextureTarget.has(t); },
+ teardown : function(tex, tex2) {
+ GL.bindTexture(GL.TEXTURE_2D, null);
+ GL.bindTexture(GL.TEXTURE_CUBE_MAP, null);
+ GL.deleteTexture(tex);
+ GL.deleteTexture(tex2);
+ }
+ },
+ getActiveAttrib : {
+ /* FIXME the queried attrib needs to be an active one
+ generate : function() {
+ var program = GL.createProgram();
+ return [program, randomVertexAttribute()];
+ },
+ checkArgValidity : function(program, index) {
+ return GL.isProgram(program) && isVertexAttribute(index);
+ },
+ cleanup : function(program, index) {
+ GL.deleteProgram(program);
+ }
+ */
+ },
+ getActiveUniform : {}, // FIXME
+ getAttachedShaders : {
+ setup : function() {
+ var program = GL.createProgram();
+ var s1 = GL.createShader(GL.VERTEX_SHADER);
+ var s2 = GL.createShader(GL.FRAGMENT_SHADER);
+ GL.attachShader(program, s1);
+ GL.attachShader(program, s2);
+ return [program, s1, s2];
+ },
+ generate : function(program, s1, s2) {
+ return [program]
+ },
+ checkArgValidity : function(program) {
+ return GL.isProgram(program);
+ },
+ teardown : function(program, s1, s2) {
+ GL.deleteProgram(program);
+ GL.deleteShader(s1);
+ GL.deleteShader(s2);
+ }
+ }
+
+};
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-G_I.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-G_I.js
new file mode 100644
index 0000000000..6aa2474241
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-G_I.js
@@ -0,0 +1,124 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// G-2
+
+ getAttribLocation : {
+ generate : function() {
+ var program = GL.createProgram();
+ var name = randomName();
+ GL.bindAttribLocation(program, randomVertexAttribute(), name);
+ return [program, name];
+ },
+ checkArgValidity : function(program, name) {
+ return GL.isProgram(program) && isValidName(name);
+ },
+ cleanup : function(program, name) {
+ try { GL.deleteProgram(program); } catch(e) {}
+ }
+ },/*
+ getParameter : {
+ generate : function() { return [getParameterPname.random()]; },
+ checkArgValidity : function(p) { return getParameterPname.has(p); }
+ },
+ getBufferParameter : {}, // FIXME
+ getError : {
+ generate : function() { return []; }
+ },
+ getFramebufferAttachmentParameter : {}, // FIXME
+ getProgramParameter : {}, // FIXME
+ getProgramInfoLog : {}, // FIXME
+ getRenderbufferParameter : {}, // FIXME
+ getShaderParameter : {}, // FIXME
+ getShaderInfoLog : {}, // FIXME
+ getShaderSource : {}, // FIXME
+ getTexParameter : {}, // FIXME
+ getUniform : {}, // FIXME
+ getUniformLocation : {}, // FIXME
+ getVertexAttrib : {}, // FIXME
+ getVertexAttribOffset : {}, // FIXME
+
+// H
+
+ hint : {
+ generate : function() { return [GL.GENERATE_MIPMAP_HINT, mipmapHint.random()]; },
+ checkValidArgs : function(h, m) {
+ return h == GL.GENERATE_MIPMAP_HINT && mipmapHint.has(m);
+ },
+ teardown : function(){ GL.hint(GL.GENERATE_MIPMAP_HINT, GL.DONT_CARE); }
+ },
+
+// I
+
+ isBuffer : {
+ generate : function() { return [GL.createBuffer()]; },
+ cleanup : function(o) { try { GL.deleteBuffer(o); } catch(e) {} }
+ },
+ isEnabled : {
+ generate : function() { return [enableCap.random()]; },
+ checkArgValidity : function(c) { return enableCap.has(c); }
+ },
+ isFramebuffer : {
+ generate : function() { return [GL.createFramebuffer()]; },
+ cleanup : function(o) { try { GL.deleteFramebuffer(o); } catch(e) {} }
+ },
+ isProgram : {
+ generate : function() { return [GL.createProgram()]; },
+ cleanup : function(o) { try { GL.deleteProgram(o); } catch(e) {} }
+ },
+ isRenderbuffer : {
+ generate : function() { return [GL.createRenderbuffer()]; },
+ cleanup : function(o) { try { GL.deleteRenderbuffer(o); } catch(e) {} }
+ },
+ isShader : {
+ generate : function() { return [GL.createShader(shaderType.random())]; },
+ cleanup : function(o) { try { GL.deleteShader(o); } catch(e) {} }
+ },
+ isTexture : {
+ generate : function() { return [GL.createTexture()]; },
+ cleanup : function(o) { try { GL.deleteTexture(o); } catch(e) {} }
+ }*/
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-L_S.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-L_S.js
new file mode 100644
index 0000000000..d3cdb3e67a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-L_S.js
@@ -0,0 +1,122 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// L
+
+ lineWidth : {
+ generate : function() { return [randomLineWidth()]; },
+ teardown : function() { GL.lineWidth(1); }
+ },
+ linkProgram : {}, // FIXME
+
+// P
+ pixelStorei : {
+ generate : function() {
+ return [pixelStoreiPname.random(), pixelStoreiParam.random()];
+ },
+ checkArgValidity : function(pname, param) {
+ return pixelStoreiPname.has(pname) && pixelStoreiParam.has(param);
+ },
+ teardown : function() {
+ GL.pixelStorei(GL.PACK_ALIGNMENT, 4);
+ GL.pixelStorei(GL.UNPACK_ALIGNMENT, 4);
+ }
+ },
+ polygonOffset : {
+ generate : function() { return [randomFloat(), randomFloat()]; },
+ teardown : function() { GL.polygonOffset(0,0); }
+ },
+
+// R
+
+ readPixels : {}, // FIXME
+ renderbufferStorage : {}, // FIXME
+
+// S-1
+
+ sampleCoverage : {
+ generate : function() { return [randomFloatFromRange(0,1), randomBool()] },
+ teardown : function() { GL.sampleCoverage(1, false); }
+ },
+ scissor : {
+ generate : function() {
+ return [randomInt(3000)-1500, randomInt(3000)-1500, randomIntFromRange(0,3000), randomIntFromRange(0,3000)];
+ },
+ checkArgValidity : function(x,y,w,h) {
+ return castToInt(w) >= 0 && castToInt(h) >= 0;
+ },
+ teardown : function() {
+ GL.scissor(0,0,GL.canvas.width, GL.canvas.height);
+ }
+ },
+ shaderSource : {}, // FIXME
+ stencilFunc : {
+ generate : function(){
+ return [stencilFuncFunc.random(), randomInt(MaxStencilValue), randomInt(0xffffffff)];
+ },
+ checkArgValidity : function(func, ref, mask) {
+ return stencilFuncFunc.has(func) && castToInt(ref) >= 0 && castToInt(ref) < MaxStencilValue;
+ },
+ teardown : function() {
+ GL.stencilFunc(GL.ALWAYS, 0, 0xffffffff);
+ }
+ },
+ stencilFuncSeparate : {
+ generate : function(){
+ return [cullFace.random(), stencilFuncFunc.random(), randomInt(MaxStencilValue), randomInt(0xffffffff)];
+ },
+ checkArgValidity : function(face, func, ref, mask) {
+ return cullFace.has(face) && stencilFuncFunc.has(func) && castToInt(ref) >= 0 && castToInt(ref) < MaxStencilValue;
+ },
+ teardown : function() {
+ GL.stencilFunc(GL.ALWAYS, 0, 0xffffffff);
+ }
+ },
+ stencilMask : {
+ generate : function() { return [randomInt(0xffffffff)]; },
+ teardown : function() { GL.stencilMask(0xffffffff); }
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-S_V.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-S_V.js
new file mode 100644
index 0000000000..d08310001c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-S_V.js
@@ -0,0 +1,212 @@
+/*
+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.
+*/
+
+// ArgGenerators contains argument generators for WebGL functions.
+// The argument generators are used for running random tests against the WebGL
+// functions.
+//
+// ArgGenerators is an object consisting of functionName : argGen -properties.
+//
+// functionName is a WebGL context function name and the argGen is an argument
+// generator object that encapsulates the requirements to run
+// randomly generated tests on the WebGL function.
+//
+// An argGen object has the following methods:
+// - setup -- set up state for testing the GL function, returns values
+// that need cleanup in teardown. Run once before entering a
+// test loop.
+// - teardown -- do cleanup on setup's return values after testing is complete
+// - generate -- generate a valid set of random arguments for the GL function
+// - returnValueCleanup -- do cleanup on value returned by the tested GL function
+// - cleanup -- do cleanup on generated arguments from generate
+// - checkArgValidity -- check if passed args are valid. Has a call signature
+// that matches generate's return value. Returns true
+// if args are valid, false if not.
+//
+// Example test loop that demonstrates how the function args and return
+// values flow together:
+//
+// var setupArgs = argGen.setup();
+// for (var i=0; i<numberOfTests; i++) {
+// var generatedArgs = argGen.generate.apply(argGen, setupArgs);
+// var validArgs = argGen.checkArgValidity.apply(argGen, generatedArgs);
+// var rv = call the GL function with generatedArgs;
+// argGen.returnValueCleanup(rv);
+// argGen.cleanup.apply(argGen, generatedArgs);
+// }
+// argGen.teardown.apply(argGen, setupArgs);
+//
+ArgGenerators = {
+
+// GL functions in alphabetical order
+
+// S-2
+
+ stencilMaskSeparate : {
+ generate : function() { return [cullFace.random(), randomInt(0xffffffff)]; },
+ checkArgValidity : function(face, mask) {
+ return cullFace.has(face);
+ },
+ teardown : function() { GL.stencilMask(0xffffffff); }
+ },
+ stencilOp : {
+ generate : function() {
+ return [stencilOp.random(), stencilOp.random(), stencilOp.random()];
+ },
+ checkArgValidity : function(sfail, dpfail, dppass) {
+ return stencilOp.has(sfail) && stencilOp.has(dpfail) && stencilOp.has(dppass);
+ },
+ teardown : function() { GL.stencilOp(GL.KEEP, GL.KEEP, GL.KEEP); }
+ },
+ stencilOpSeparate : {
+ generate : function() {
+ return [cullFace.random(), stencilOp.random(), stencilOp.random(), stencilOp.random()];
+ },
+ checkArgValidity : function(face, sfail, dpfail, dppass) {
+ return cullFace.has(face) && stencilOp.has(sfail) &&
+ stencilOp.has(dpfail) && stencilOp.has(dppass);
+ },
+ teardown : function() { GL.stencilOp(GL.KEEP, GL.KEEP, GL.KEEP); }
+ },
+
+// T
+ texImage2D : {
+ noAlreadyTriedCheck : true, // Object.toSource is very slow here
+ setup : function() {
+ var tex = GL.createTexture();
+ var tex2 = GL.createTexture();
+ GL.bindTexture(GL.TEXTURE_2D, tex);
+ GL.bindTexture(GL.TEXTURE_CUBE_MAP, tex2);
+ return [tex, tex2];
+ },
+ generate : function() {
+ var format = texImageFormat.random();
+ if (Math.random() < 0.5) {
+ var img = randomImage(16,16);
+ var a = [ texImageTarget.random(), 0, format, format, GL.UNSIGNED_BYTE, img ];
+ return a;
+ } else {
+ var pix = null;
+ if (Math.random > 0.5) {
+ pix = new Uint8Array(16*16*4);
+ }
+ return [
+ texImageTarget.random(), 0,
+ format, 16, 16, 0,
+ format, GL.UNSIGNED_BYTE, pix
+ ];
+ }
+ },
+ checkArgValidity : function(target, level, internalformat, width, height, border, format, type, data) {
+ // or : function(target, level, internalformat, format, type, image)
+ if (!texImageTarget.has(target) || castToInt(level) < 0)
+ return false;
+ if (arguments.length <= 6) {
+ var xformat = width;
+ var xtype = height;
+ var ximage = border;
+ if ((ximage instanceof HTMLImageElement ||
+ ximage instanceof HTMLVideoElement ||
+ ximage instanceof HTMLCanvasElement ||
+ ximage instanceof ImageData) &&
+ texImageInternalFormat.has(internalformat) &&
+ texImageFormat.has(xformat) &&
+ texImageType.has(xtype) &&
+ internalformat == xformat)
+ return true;
+ return false;
+ }
+ var w = castToInt(width), h = castToInt(height), b = castToInt(border);
+ return texImageInternalFormat.has(internalformat) && w >= 0 && h >= 0 &&
+ b == 0 && (data == null || data.byteLength == w*h*4) &&
+ texImageFormat.has(format) && texImageType.has(type)
+ && internalformat == format;
+ },
+ teardown : function(tex, tex2) {
+ GL.bindTexture(GL.TEXTURE_2D, null);
+ GL.bindTexture(GL.TEXTURE_CUBE_MAP, null);
+ GL.deleteTexture(tex);
+ GL.deleteTexture(tex2);
+ }
+ },
+ texParameterf : {
+ generate : function() {
+ var pname = texParameterPname.random();
+ var param = texParameterParam[pname].random();
+ return [bindTextureTarget.random(), pname, param];
+ },
+ checkArgValidity : function(target, pname, param) {
+ if (!bindTextureTarget.has(target))
+ return false;
+ if (!texParameterPname.has(pname))
+ return false;
+ return texParameterParam[pname].has(param);
+ }
+ },
+ texParameteri : {
+ generate : function() {
+ var pname = texParameterPname.random();
+ var param = texParameterParam[pname].random();
+ return [bindTextureTarget.random(), pname, param];
+ },
+ checkArgValidity : function(target, pname, param) {
+ if (!bindTextureTarget.has(target))
+ return false;
+ if (!texParameterPname.has(pname))
+ return false;
+ return texParameterParam[pname].has(param);
+ }
+ },
+ texSubImage2D : {}, // FIXME
+
+// U
+
+ uniform1f : {}, // FIXME
+ uniform1fv : {}, // FIXME
+ uniform1i : {}, // FIXME
+ uniform1iv : {}, // FIXME
+ uniform2f : {}, // FIXME
+ uniform2fv : {}, // FIXME
+ uniform2i : {}, // FIXME
+ uniform2iv : {}, // FIXME
+ uniform3f : {}, // FIXME
+ uniform3fv : {}, // FIXME
+ uniform3i : {}, // FIXME
+ uniform3iv : {}, // FIXME
+ uniform4f : {}, // FIXME
+ uniform4fv : {}, // FIXME
+ uniform4i : {}, // FIXME
+ uniform4iv : {}, // FIXME
+ uniformMatrix2fv : {}, // FIXME
+ uniformMatrix3fv : {}, // FIXME
+ uniformMatrix4fv : {}, // FIXME
+ useProgram : {}, // FIXME
+
+// V
+
+ validateProgram : {}, // FIXME
+ vertexAttrib1f : {}, // FIXME
+ vertexAttrib1fv : {}, // FIXME
+ vertexAttrib2f : {}, // FIXME
+ vertexAttrib2fv : {}, // FIXME
+ vertexAttrib3f : {}, // FIXME
+ vertexAttrib3fv : {}, // FIXME
+ vertexAttrib4f : {}, // FIXME
+ vertexAttrib4fv : {}, // FIXME
+ vertexAttribPointer : {}, // FIXME
+ viewport : {
+ generate : function() {
+ return [randomInt(3000)-1500, randomInt(3000)-1500, randomIntFromRange(0,3000), randomIntFromRange(0,3000)];
+ },
+ checkArgValidity : function(x,y,w,h) {
+ return castToInt(w) >= 0 && castToInt(h) >= 0;
+ },
+ teardown : function() {
+ GL.viewport(0,0,GL.canvas.width, GL.canvas.height);
+ }
+ }
+
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/badArgsArityLessThanArgc.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/badArgsArityLessThanArgc.html
new file mode 100644
index 0000000000..5ee9727a6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/badArgsArityLessThanArgc.html
@@ -0,0 +1,576 @@
+<!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">
+
+/*
+ The following tests are generated from
+ http://www.khronos.org/registry/gles/api/2.0/gl2.h
+ and api_modifications.txt
+*/
+Tests.test_activeTexture = function(gl) {
+ assertFail(function(){ gl.activeTexture(); });
+}
+Tests.test_attachShader = function(gl) {
+ assertFail(function(){ gl.attachShader(); });
+ assertFail(function(){ gl.attachShader(0); });
+}
+Tests.test_bindAttribLocation = function(gl) {
+ assertFail(function(){ gl.bindAttribLocation(); });
+ assertFail(function(){ gl.bindAttribLocation(0); });
+ assertFail(function(){ gl.bindAttribLocation(0,0); });
+}
+Tests.test_bindBuffer = function(gl) {
+ assertFail(function(){ gl.bindBuffer(); });
+ assertFail(function(){ gl.bindBuffer(0); });
+}
+Tests.test_bindFramebuffer = function(gl) {
+ assertFail(function(){ gl.bindFramebuffer(); });
+ assertFail(function(){ gl.bindFramebuffer(0); });
+}
+Tests.test_bindRenderbuffer = function(gl) {
+ assertFail(function(){ gl.bindRenderbuffer(); });
+ assertFail(function(){ gl.bindRenderbuffer(0); });
+}
+Tests.test_bindTexture = function(gl) {
+ assertFail(function(){ gl.bindTexture(); });
+ assertFail(function(){ gl.bindTexture(0); });
+}
+Tests.test_blendColor = function(gl) {
+ assertFail(function(){ gl.blendColor(); });
+ assertFail(function(){ gl.blendColor(0); });
+ assertFail(function(){ gl.blendColor(0,0); });
+ assertFail(function(){ gl.blendColor(0,0,0); });
+}
+Tests.test_blendEquation = function(gl) {
+ assertFail(function(){ gl.blendEquation(); });
+}
+Tests.test_blendEquationSeparate = function(gl) {
+ assertFail(function(){ gl.blendEquationSeparate(); });
+ assertFail(function(){ gl.blendEquationSeparate(0); });
+}
+Tests.test_blendFunc = function(gl) {
+ assertFail(function(){ gl.blendFunc(); });
+ assertFail(function(){ gl.blendFunc(0); });
+}
+Tests.test_blendFuncSeparate = function(gl) {
+ assertFail(function(){ gl.blendFuncSeparate(); });
+ assertFail(function(){ gl.blendFuncSeparate(0); });
+ assertFail(function(){ gl.blendFuncSeparate(0,0); });
+ assertFail(function(){ gl.blendFuncSeparate(0,0,0); });
+}
+Tests.test_bufferData = function(gl) {
+ assertFail(function(){ gl.bufferData(); });
+ assertFail(function(){ gl.bufferData(0); });
+ assertFail(function(){ gl.bufferData(0,0); });
+}
+Tests.test_bufferSubData = function(gl) {
+ assertFail(function(){ gl.bufferSubData(); });
+ assertFail(function(){ gl.bufferSubData(0); });
+ assertFail(function(){ gl.bufferSubData(0,0); });
+}
+Tests.test_checkFramebufferStatus = function(gl) {
+ assertFail(function(){ gl.checkFramebufferStatus(); });
+}
+Tests.test_clear = function(gl) {
+ assertFail(function(){ gl.clear(); });
+}
+Tests.test_clearColor = function(gl) {
+ assertFail(function(){ gl.clearColor(); });
+ assertFail(function(){ gl.clearColor(0); });
+ assertFail(function(){ gl.clearColor(0,0); });
+ assertFail(function(){ gl.clearColor(0,0,0); });
+}
+Tests.test_clearDepth = function(gl) {
+ assertFail(function(){ gl.clearDepth(); });
+}
+Tests.test_clearStencil = function(gl) {
+ assertFail(function(){ gl.clearStencil(); });
+}
+Tests.test_colorMask = function(gl) {
+ assertFail(function(){ gl.colorMask(); });
+ assertFail(function(){ gl.colorMask(0); });
+ assertFail(function(){ gl.colorMask(0,0); });
+ assertFail(function(){ gl.colorMask(0,0,0); });
+}
+Tests.test_compileShader = function(gl) {
+ assertFail(function(){ gl.compileShader(); });
+}
+Tests.test_copyTexImage2D = function(gl) {
+ assertFail(function(){ gl.copyTexImage2D(); });
+ assertFail(function(){ gl.copyTexImage2D(0); });
+ assertFail(function(){ gl.copyTexImage2D(0,0); });
+ assertFail(function(){ gl.copyTexImage2D(0,0,0); });
+ assertFail(function(){ gl.copyTexImage2D(0,0,0,0); });
+ assertFail(function(){ gl.copyTexImage2D(0,0,0,0,0); });
+ assertFail(function(){ gl.copyTexImage2D(0,0,0,0,0,0); });
+ assertFail(function(){ gl.copyTexImage2D(0,0,0,0,0,0,0); });
+}
+Tests.test_copyTexSubImage2D = function(gl) {
+ assertFail(function(){ gl.copyTexSubImage2D(); });
+ assertFail(function(){ gl.copyTexSubImage2D(0); });
+ assertFail(function(){ gl.copyTexSubImage2D(0,0); });
+ assertFail(function(){ gl.copyTexSubImage2D(0,0,0); });
+ assertFail(function(){ gl.copyTexSubImage2D(0,0,0,0); });
+ assertFail(function(){ gl.copyTexSubImage2D(0,0,0,0,0); });
+ assertFail(function(){ gl.copyTexSubImage2D(0,0,0,0,0,0); });
+ assertFail(function(){ gl.copyTexSubImage2D(0,0,0,0,0,0,0); });
+}
+Tests.test_createProgram = function(gl) {
+}
+Tests.test_createShader = function(gl) {
+ assertFail(function(){ gl.createShader(); });
+}
+Tests.test_cullFace = function(gl) {
+ assertFail(function(){ gl.cullFace(); });
+}
+Tests.test_deleteBuffer = function(gl) {
+ assertFail(function(){ gl.deleteBuffer(); });
+}
+Tests.test_deleteFramebuffer = function(gl) {
+ assertFail(function(){ gl.deleteFramebuffer(); });
+}
+Tests.test_deleteProgram = function(gl) {
+ assertFail(function(){ gl.deleteProgram(); });
+}
+Tests.test_deleteRenderbuffer = function(gl) {
+ assertFail(function(){ gl.deleteRenderbuffer(); });
+}
+Tests.test_deleteShader = function(gl) {
+ assertFail(function(){ gl.deleteShader(); });
+}
+Tests.test_deleteTexture = function(gl) {
+ assertFail(function(){ gl.deleteTexture(); });
+}
+Tests.test_depthFunc = function(gl) {
+ assertFail(function(){ gl.depthFunc(); });
+}
+Tests.test_depthMask = function(gl) {
+ assertFail(function(){ gl.depthMask(); });
+}
+Tests.test_depthRange = function(gl) {
+ assertFail(function(){ gl.depthRange(); });
+ assertFail(function(){ gl.depthRange(0); });
+}
+Tests.test_detachShader = function(gl) {
+ assertFail(function(){ gl.detachShader(); });
+ assertFail(function(){ gl.detachShader(0); });
+}
+Tests.test_disable = function(gl) {
+ assertFail(function(){ gl.disable(); });
+}
+Tests.test_disableVertexAttribArray = function(gl) {
+ assertFail(function(){ gl.disableVertexAttribArray(); });
+}
+Tests.test_drawArrays = function(gl) {
+ assertFail(function(){ gl.drawArrays(); });
+ assertFail(function(){ gl.drawArrays(0); });
+ assertFail(function(){ gl.drawArrays(0,0); });
+}
+Tests.test_drawElements = function(gl) {
+ assertFail(function(){ gl.drawElements(); });
+ assertFail(function(){ gl.drawElements(0); });
+ assertFail(function(){ gl.drawElements(0,0); });
+ assertFail(function(){ gl.drawElements(0,0,0); });
+}
+Tests.test_enable = function(gl) {
+ assertFail(function(){ gl.enable(); });
+}
+Tests.test_enableVertexAttribArray = function(gl) {
+ assertFail(function(){ gl.enableVertexAttribArray(); });
+}
+Tests.test_finish = function(gl) {
+}
+Tests.test_flush = function(gl) {
+}
+Tests.test_framebufferRenderbuffer = function(gl) {
+ assertFail(function(){ gl.framebufferRenderbuffer(); });
+ assertFail(function(){ gl.framebufferRenderbuffer(0); });
+ assertFail(function(){ gl.framebufferRenderbuffer(0,0); });
+ assertFail(function(){ gl.framebufferRenderbuffer(0,0,0); });
+}
+Tests.test_framebufferTexture2D = function(gl) {
+ assertFail(function(){ gl.framebufferTexture2D(); });
+ assertFail(function(){ gl.framebufferTexture2D(0); });
+ assertFail(function(){ gl.framebufferTexture2D(0,0); });
+ assertFail(function(){ gl.framebufferTexture2D(0,0,0); });
+ assertFail(function(){ gl.framebufferTexture2D(0,0,0,0); });
+}
+Tests.test_frontFace = function(gl) {
+ assertFail(function(){ gl.frontFace(); });
+}
+Tests.test_createBuffer = function(gl) {
+}
+Tests.test_generateMipmap = function(gl) {
+ assertFail(function(){ gl.generateMipmap(); });
+}
+Tests.test_createFramebuffer = function(gl) {
+}
+Tests.test_createRenderbuffer = function(gl) {
+}
+Tests.test_createTexture = function(gl) {
+}
+Tests.test_getActiveAttrib = function(gl) {
+ assertFail(function(){ gl.getActiveAttrib(); });
+ assertFail(function(){ gl.getActiveAttrib(0); });
+}
+Tests.test_getActiveUniform = function(gl) {
+ assertFail(function(){ gl.getActiveUniform(); });
+ assertFail(function(){ gl.getActiveUniform(0); });
+}
+Tests.test_getAttachedShaders = function(gl) {
+ assertFail(function(){ gl.getAttachedShaders(); });
+}
+Tests.test_getAttribLocation = function(gl) {
+ assertFail(function(){ gl.getAttribLocation(); });
+ assertFail(function(){ gl.getAttribLocation(0); });
+}
+Tests.test_getBufferParameteri = function(gl) {
+ assertFail(function(){ gl.getBufferParameteri(); });
+ assertFail(function(){ gl.getBufferParameteri(0); });
+}
+Tests.test_getError = function(gl) {
+}
+Tests.test_getFramebufferAttachmentParameteri = function(gl) {
+ assertFail(function(){ gl.getFramebufferAttachmentParameteri(); });
+ assertFail(function(){ gl.getFramebufferAttachmentParameteri(0); });
+ assertFail(function(){ gl.getFramebufferAttachmentParameteri(0,0); });
+}
+Tests.test_getProgramInfoLog = function(gl) {
+ assertFail(function(){ gl.getProgramInfoLog(); });
+}
+Tests.test_getRenderbufferParameteri = function(gl) {
+ assertFail(function(){ gl.getRenderbufferParameteri(); });
+ assertFail(function(){ gl.getRenderbufferParameteri(0); });
+}
+Tests.test_getShaderInfoLog = function(gl) {
+ assertFail(function(){ gl.getShaderInfoLog(); });
+}
+Tests.test_getShaderSource = function(gl) {
+ assertFail(function(){ gl.getShaderSource(); });
+}
+Tests.test_getUniformLocation = function(gl) {
+ assertFail(function(){ gl.getUniformLocation(); });
+ assertFail(function(){ gl.getUniformLocation(0); });
+}
+Tests.test_hint = function(gl) {
+ assertFail(function(){ gl.hint(); });
+ assertFail(function(){ gl.hint(0); });
+}
+Tests.test_isBuffer = function(gl) {
+ assertFail(function(){ gl.isBuffer(); });
+}
+Tests.test_isEnabled = function(gl) {
+ assertFail(function(){ gl.isEnabled(); });
+}
+Tests.test_isFramebuffer = function(gl) {
+ assertFail(function(){ gl.isFramebuffer(); });
+}
+Tests.test_isProgram = function(gl) {
+ assertFail(function(){ gl.isProgram(); });
+}
+Tests.test_isRenderbuffer = function(gl) {
+ assertFail(function(){ gl.isRenderbuffer(); });
+}
+Tests.test_isShader = function(gl) {
+ assertFail(function(){ gl.isShader(); });
+}
+Tests.test_isTexture = function(gl) {
+ assertFail(function(){ gl.isTexture(); });
+}
+Tests.test_lineWidth = function(gl) {
+ assertFail(function(){ gl.lineWidth(); });
+}
+Tests.test_linkProgram = function(gl) {
+ assertFail(function(){ gl.linkProgram(); });
+}
+Tests.test_polygonOffset = function(gl) {
+ assertFail(function(){ gl.polygonOffset(); });
+ assertFail(function(){ gl.polygonOffset(0); });
+}
+Tests.test_readPixels = function(gl) {
+ assertFail(function(){ gl.readPixels(); });
+ assertFail(function(){ gl.readPixels(0); });
+ assertFail(function(){ gl.readPixels(0,0); });
+ assertFail(function(){ gl.readPixels(0,0,0); });
+ assertFail(function(){ gl.readPixels(0,0,0,0); });
+ assertFail(function(){ gl.readPixels(0,0,0,0,0); });
+}
+Tests.test_renderbufferStorage = function(gl) {
+ assertFail(function(){ gl.renderbufferStorage(); });
+ assertFail(function(){ gl.renderbufferStorage(0); });
+ assertFail(function(){ gl.renderbufferStorage(0,0); });
+ assertFail(function(){ gl.renderbufferStorage(0,0,0); });
+}
+Tests.test_sampleCoverage = function(gl) {
+ assertFail(function(){ gl.sampleCoverage(); });
+ assertFail(function(){ gl.sampleCoverage(0); });
+}
+Tests.test_scissor = function(gl) {
+ assertFail(function(){ gl.scissor(); });
+ assertFail(function(){ gl.scissor(0); });
+ assertFail(function(){ gl.scissor(0,0); });
+ assertFail(function(){ gl.scissor(0,0,0); });
+}
+Tests.test_shaderSource = function(gl) {
+ assertFail(function(){ gl.shaderSource(); });
+ assertFail(function(){ gl.shaderSource(0); });
+}
+Tests.test_stencilFunc = function(gl) {
+ assertFail(function(){ gl.stencilFunc(); });
+ assertFail(function(){ gl.stencilFunc(0); });
+ assertFail(function(){ gl.stencilFunc(0,0); });
+}
+Tests.test_stencilFuncSeparate = function(gl) {
+ assertFail(function(){ gl.stencilFuncSeparate(); });
+ assertFail(function(){ gl.stencilFuncSeparate(0); });
+ assertFail(function(){ gl.stencilFuncSeparate(0,0); });
+ assertFail(function(){ gl.stencilFuncSeparate(0,0,0); });
+}
+Tests.test_stencilMask = function(gl) {
+ assertFail(function(){ gl.stencilMask(); });
+}
+Tests.test_stencilMaskSeparate = function(gl) {
+ assertFail(function(){ gl.stencilMaskSeparate(); });
+ assertFail(function(){ gl.stencilMaskSeparate(0); });
+}
+Tests.test_stencilOp = function(gl) {
+ assertFail(function(){ gl.stencilOp(); });
+ assertFail(function(){ gl.stencilOp(0); });
+ assertFail(function(){ gl.stencilOp(0,0); });
+}
+Tests.test_stencilOpSeparate = function(gl) {
+ assertFail(function(){ gl.stencilOpSeparate(); });
+ assertFail(function(){ gl.stencilOpSeparate(0); });
+ assertFail(function(){ gl.stencilOpSeparate(0,0); });
+ assertFail(function(){ gl.stencilOpSeparate(0,0,0); });
+}
+Tests.test_texImage2D = function(gl) {
+ assertFail(function(){ gl.texImage2D(); });
+ assertFail(function(){ gl.texImage2D(0); });
+ assertFail(function(){ gl.texImage2D(0,0); });
+}
+Tests.test_texParameteri = function(gl) {
+ assertFail(function(){ gl.texParameteri(); });
+ assertFail(function(){ gl.texParameteri(0); });
+ assertFail(function(){ gl.texParameteri(0,0); });
+}
+Tests.test_texSubImage2D = function(gl) {
+ assertFail(function(){ gl.texSubImage2D(); });
+ assertFail(function(){ gl.texSubImage2D(0); });
+ assertFail(function(){ gl.texSubImage2D(0,0); });
+ assertFail(function(){ gl.texSubImage2D(0,0,0); });
+ assertFail(function(){ gl.texSubImage2D(0,0,0,0); });
+ assertFail(function(){ gl.texSubImage2D(0,0,0,0,0); });
+ assertFail(function(){ gl.texSubImage2D(0,0,0,0,0,0); });
+ assertFail(function(){ gl.texSubImage2D(0,0,0,0,0,0,0); });
+ assertFail(function(){ gl.texSubImage2D(0,0,0,0,0,0,0,0); });
+}
+Tests.test_uniform1f = function(gl) {
+ assertFail(function(){ gl.uniform1f(); });
+ assertFail(function(){ gl.uniform1f(0); });
+}
+Tests.test_uniform1fv = function(gl) {
+ assertFail(function(){ gl.uniform1fv(); });
+ assertFail(function(){ gl.uniform1fv(0); });
+}
+Tests.test_uniform1i = function(gl) {
+ assertFail(function(){ gl.uniform1i(); });
+ assertFail(function(){ gl.uniform1i(0); });
+}
+Tests.test_uniform1iv = function(gl) {
+ assertFail(function(){ gl.uniform1iv(); });
+ assertFail(function(){ gl.uniform1iv(0); });
+}
+Tests.test_uniform2f = function(gl) {
+ assertFail(function(){ gl.uniform2f(); });
+ assertFail(function(){ gl.uniform2f(0); });
+ assertFail(function(){ gl.uniform2f(0,0); });
+}
+Tests.test_uniform2fv = function(gl) {
+ assertFail(function(){ gl.uniform2fv(); });
+ assertFail(function(){ gl.uniform2fv(0); });
+}
+Tests.test_uniform2i = function(gl) {
+ assertFail(function(){ gl.uniform2i(); });
+ assertFail(function(){ gl.uniform2i(0); });
+ assertFail(function(){ gl.uniform2i(0,0); });
+}
+Tests.test_uniform2iv = function(gl) {
+ assertFail(function(){ gl.uniform2iv(); });
+ assertFail(function(){ gl.uniform2iv(0); });
+}
+Tests.test_uniform3f = function(gl) {
+ assertFail(function(){ gl.uniform3f(); });
+ assertFail(function(){ gl.uniform3f(0); });
+ assertFail(function(){ gl.uniform3f(0,0); });
+ assertFail(function(){ gl.uniform3f(0,0,0); });
+}
+Tests.test_uniform3fv = function(gl) {
+ assertFail(function(){ gl.uniform3fv(); });
+ assertFail(function(){ gl.uniform3fv(0); });
+}
+Tests.test_uniform3i = function(gl) {
+ assertFail(function(){ gl.uniform3i(); });
+ assertFail(function(){ gl.uniform3i(0); });
+ assertFail(function(){ gl.uniform3i(0,0); });
+ assertFail(function(){ gl.uniform3i(0,0,0); });
+}
+Tests.test_uniform3iv = function(gl) {
+ assertFail(function(){ gl.uniform3iv(); });
+ assertFail(function(){ gl.uniform3iv(0); });
+}
+Tests.test_uniform4f = function(gl) {
+ assertFail(function(){ gl.uniform4f(); });
+ assertFail(function(){ gl.uniform4f(0); });
+ assertFail(function(){ gl.uniform4f(0,0); });
+ assertFail(function(){ gl.uniform4f(0,0,0); });
+ assertFail(function(){ gl.uniform4f(0,0,0,0); });
+}
+Tests.test_uniform4fv = function(gl) {
+ assertFail(function(){ gl.uniform4fv(); });
+ assertFail(function(){ gl.uniform4fv(0); });
+}
+Tests.test_uniform4i = function(gl) {
+ assertFail(function(){ gl.uniform4i(); });
+ assertFail(function(){ gl.uniform4i(0); });
+ assertFail(function(){ gl.uniform4i(0,0); });
+ assertFail(function(){ gl.uniform4i(0,0,0); });
+ assertFail(function(){ gl.uniform4i(0,0,0,0); });
+}
+Tests.test_uniform4iv = function(gl) {
+ assertFail(function(){ gl.uniform4iv(); });
+ assertFail(function(){ gl.uniform4iv(0); });
+}
+Tests.test_uniformMatrix2fv = function(gl) {
+ assertFail(function(){ gl.uniformMatrix2fv(); });
+ assertFail(function(){ gl.uniformMatrix2fv(0); });
+ assertFail(function(){ gl.uniformMatrix2fv(0,0); });
+}
+Tests.test_uniformMatrix3fv = function(gl) {
+ assertFail(function(){ gl.uniformMatrix3fv(); });
+ assertFail(function(){ gl.uniformMatrix3fv(0); });
+ assertFail(function(){ gl.uniformMatrix3fv(0,0); });
+}
+Tests.test_uniformMatrix4fv = function(gl) {
+ assertFail(function(){ gl.uniformMatrix4fv(); });
+ assertFail(function(){ gl.uniformMatrix4fv(0); });
+ assertFail(function(){ gl.uniformMatrix4fv(0,0); });
+}
+Tests.test_useProgram = function(gl) {
+ assertFail(function(){ gl.useProgram(); });
+}
+Tests.test_validateProgram = function(gl) {
+ assertFail(function(){ gl.validateProgram(); });
+}
+Tests.test_vertexAttrib1f = function(gl) {
+ assertFail(function(){ gl.vertexAttrib1f(); });
+ assertFail(function(){ gl.vertexAttrib1f(0); });
+}
+Tests.test_vertexAttrib1fv = function(gl) {
+ assertFail(function(){ gl.vertexAttrib1fv(); });
+ assertFail(function(){ gl.vertexAttrib1fv(0); });
+}
+Tests.test_vertexAttrib2f = function(gl) {
+ assertFail(function(){ gl.vertexAttrib2f(); });
+ assertFail(function(){ gl.vertexAttrib2f(0); });
+ assertFail(function(){ gl.vertexAttrib2f(0,0); });
+}
+Tests.test_vertexAttrib2fv = function(gl) {
+ assertFail(function(){ gl.vertexAttrib2fv(); });
+ assertFail(function(){ gl.vertexAttrib2fv(0); });
+}
+Tests.test_vertexAttrib3f = function(gl) {
+ assertFail(function(){ gl.vertexAttrib3f(); });
+ assertFail(function(){ gl.vertexAttrib3f(0); });
+ assertFail(function(){ gl.vertexAttrib3f(0,0); });
+ assertFail(function(){ gl.vertexAttrib3f(0,0,0); });
+}
+Tests.test_vertexAttrib3fv = function(gl) {
+ assertFail(function(){ gl.vertexAttrib3fv(); });
+ assertFail(function(){ gl.vertexAttrib3fv(0); });
+}
+Tests.test_vertexAttrib4f = function(gl) {
+ assertFail(function(){ gl.vertexAttrib4f(); });
+ assertFail(function(){ gl.vertexAttrib4f(0); });
+ assertFail(function(){ gl.vertexAttrib4f(0,0); });
+ assertFail(function(){ gl.vertexAttrib4f(0,0,0); });
+ assertFail(function(){ gl.vertexAttrib4f(0,0,0,0); });
+}
+Tests.test_vertexAttrib4fv = function(gl) {
+ assertFail(function(){ gl.vertexAttrib4fv(); });
+ assertFail(function(){ gl.vertexAttrib4fv(0); });
+}
+Tests.test_vertexAttribPointer = function(gl) {
+ assertFail(function(){ gl.vertexAttribPointer(); });
+ assertFail(function(){ gl.vertexAttribPointer(0); });
+ assertFail(function(){ gl.vertexAttribPointer(0,0); });
+ assertFail(function(){ gl.vertexAttribPointer(0,0,0); });
+ assertFail(function(){ gl.vertexAttribPointer(0,0,0,0); });
+ assertFail(function(){ gl.vertexAttribPointer(0,0,0,0,0); });
+}
+Tests.test_viewport = function(gl) {
+ assertFail(function(){ gl.viewport(); });
+ assertFail(function(){ gl.viewport(0); });
+ assertFail(function(){ gl.viewport(0,0); });
+ assertFail(function(){ gl.viewport(0,0,0); });
+}
+Tests.test_currentArrayBufferBinding = function(gl) {
+}
+Tests.test_currentElementArrayBufferBinding = function(gl) {
+}
+Tests.test_currentFramebufferBinding = function(gl) {
+}
+Tests.test_currentRenderbufferBinding = function(gl) {
+}
+Tests.test_currentTextureBinding2D = function(gl) {
+}
+Tests.test_currentTextureBindingCubeMap = function(gl) {
+}
+Tests.test_currentProgram = function(gl) {
+}
+Tests.test_getParameter = function(gl) {
+ assertFail(function(){ gl.getParameter(); });
+}
+Tests.test_getProgramParameter = function(gl) {
+ assertFail(function(){ gl.getProgramParameter(); });
+ assertFail(function(){ gl.getProgramParameter(0); });
+}
+Tests.test_getShaderParameter = function(gl) {
+ assertFail(function(){ gl.getShaderParameter(); });
+ assertFail(function(){ gl.getShaderParameter(0); });
+}
+Tests.test_getTexParameteri = function(gl) {
+ assertFail(function(){ gl.getTexParameteri(); });
+ assertFail(function(){ gl.getTexParameteri(0); });
+}
+Tests.test_getUniformi = function(gl) {
+ assertFail(function(){ gl.getUniformi(); });
+ assertFail(function(){ gl.getUniformi(0); });
+}
+Tests.test_getVertexAttribi = function(gl) {
+ assertFail(function(){ gl.getVertexAttribi(); });
+ assertFail(function(){ gl.getVertexAttribi(0); });
+}
+Tests.test_present = function(gl) {
+}
+Tests.startUnit = function() {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+</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/conformance/constants.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/constants.html
new file mode 100644
index 0000000000..61997afae6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/constants.html
@@ -0,0 +1,350 @@
+<!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">
+
+/*
+ The following tests are generated from
+ http://www.khronos.org/registry/gles/api/2.0/gl2.h
+ and api_modifications.txt
+*/
+var constants = {
+DEPTH_BUFFER_BIT : 0x00000100,
+STENCIL_BUFFER_BIT : 0x00000400,
+COLOR_BUFFER_BIT : 0x00004000,
+POINTS : 0x0000,
+LINES : 0x0001,
+LINE_LOOP : 0x0002,
+LINE_STRIP : 0x0003,
+TRIANGLES : 0x0004,
+TRIANGLE_STRIP : 0x0005,
+TRIANGLE_FAN : 0x0006,
+ZERO : 0,
+ONE : 1,
+SRC_COLOR : 0x0300,
+ONE_MINUS_SRC_COLOR : 0x0301,
+SRC_ALPHA : 0x0302,
+ONE_MINUS_SRC_ALPHA : 0x0303,
+DST_ALPHA : 0x0304,
+ONE_MINUS_DST_ALPHA : 0x0305,
+DST_COLOR : 0x0306,
+ONE_MINUS_DST_COLOR : 0x0307,
+SRC_ALPHA_SATURATE : 0x0308,
+FUNC_ADD : 0x8006,
+BLEND_EQUATION : 0x8009,
+BLEND_EQUATION_RGB : 0x8009,
+BLEND_EQUATION_ALPHA : 0x883D,
+FUNC_SUBTRACT : 0x800A,
+FUNC_REVERSE_SUBTRACT : 0x800B,
+BLEND_DST_RGB : 0x80C8,
+BLEND_SRC_RGB : 0x80C9,
+BLEND_DST_ALPHA : 0x80CA,
+BLEND_SRC_ALPHA : 0x80CB,
+CONSTANT_COLOR : 0x8001,
+ONE_MINUS_CONSTANT_COLOR : 0x8002,
+CONSTANT_ALPHA : 0x8003,
+ONE_MINUS_CONSTANT_ALPHA : 0x8004,
+BLEND_COLOR : 0x8005,
+ARRAY_BUFFER : 0x8892,
+ELEMENT_ARRAY_BUFFER : 0x8893,
+ARRAY_BUFFER_BINDING : 0x8894,
+ELEMENT_ARRAY_BUFFER_BINDING : 0x8895,
+STREAM_DRAW : 0x88E0,
+STATIC_DRAW : 0x88E4,
+DYNAMIC_DRAW : 0x88E8,
+BUFFER_SIZE : 0x8764,
+BUFFER_USAGE : 0x8765,
+CURRENT_VERTEX_ATTRIB : 0x8626,
+FRONT : 0x0404,
+BACK : 0x0405,
+FRONT_AND_BACK : 0x0408,
+TEXTURE_2D : 0x0DE1,
+CULL_FACE : 0x0B44,
+BLEND : 0x0BE2,
+DITHER : 0x0BD0,
+STENCIL_TEST : 0x0B90,
+DEPTH_TEST : 0x0B71,
+SCISSOR_TEST : 0x0C11,
+POLYGON_OFFSET_FILL : 0x8037,
+SAMPLE_ALPHA_TO_COVERAGE : 0x809E,
+SAMPLE_COVERAGE : 0x80A0,
+NO_ERROR : 0,
+INVALID_ENUM : 0x0500,
+INVALID_VALUE : 0x0501,
+INVALID_OPERATION : 0x0502,
+OUT_OF_MEMORY : 0x0505,
+CW : 0x0900,
+CCW : 0x0901,
+LINE_WIDTH : 0x0B21,
+ALIASED_POINT_SIZE_RANGE : 0x846D,
+ALIASED_LINE_WIDTH_RANGE : 0x846E,
+CULL_FACE_MODE : 0x0B45,
+FRONT_FACE : 0x0B46,
+DEPTH_RANGE : 0x0B70,
+DEPTH_WRITEMASK : 0x0B72,
+DEPTH_CLEAR_VALUE : 0x0B73,
+DEPTH_FUNC : 0x0B74,
+STENCIL_CLEAR_VALUE : 0x0B91,
+STENCIL_FUNC : 0x0B92,
+STENCIL_FAIL : 0x0B94,
+STENCIL_PASS_DEPTH_FAIL : 0x0B95,
+STENCIL_PASS_DEPTH_PASS : 0x0B96,
+STENCIL_REF : 0x0B97,
+STENCIL_VALUE_MASK : 0x0B93,
+STENCIL_WRITEMASK : 0x0B98,
+STENCIL_BACK_FUNC : 0x8800,
+STENCIL_BACK_FAIL : 0x8801,
+STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802,
+STENCIL_BACK_PASS_DEPTH_PASS : 0x8803,
+STENCIL_BACK_REF : 0x8CA3,
+STENCIL_BACK_VALUE_MASK : 0x8CA4,
+STENCIL_BACK_WRITEMASK : 0x8CA5,
+VIEWPORT : 0x0BA2,
+SCISSOR_BOX : 0x0C10,
+COLOR_CLEAR_VALUE : 0x0C22,
+COLOR_WRITEMASK : 0x0C23,
+UNPACK_ALIGNMENT : 0x0CF5,
+PACK_ALIGNMENT : 0x0D05,
+MAX_TEXTURE_SIZE : 0x0D33,
+MAX_VIEWPORT_DIMS : 0x0D3A,
+SUBPIXEL_BITS : 0x0D50,
+RED_BITS : 0x0D52,
+GREEN_BITS : 0x0D53,
+BLUE_BITS : 0x0D54,
+ALPHA_BITS : 0x0D55,
+DEPTH_BITS : 0x0D56,
+STENCIL_BITS : 0x0D57,
+POLYGON_OFFSET_UNITS : 0x2A00,
+POLYGON_OFFSET_FACTOR : 0x8038,
+TEXTURE_BINDING_2D : 0x8069,
+SAMPLE_BUFFERS : 0x80A8,
+SAMPLES : 0x80A9,
+SAMPLE_COVERAGE_VALUE : 0x80AA,
+SAMPLE_COVERAGE_INVERT : 0x80AB,
+COMPRESSED_TEXTURE_FORMATS : 0x86A3,
+DONT_CARE : 0x1100,
+FASTEST : 0x1101,
+NICEST : 0x1102,
+GENERATE_MIPMAP_HINT : 0x8192,
+BYTE : 0x1400,
+UNSIGNED_BYTE : 0x1401,
+SHORT : 0x1402,
+UNSIGNED_SHORT : 0x1403,
+INT : 0x1404,
+UNSIGNED_INT : 0x1405,
+FLOAT : 0x1406,
+//FIXED : 0x140C,
+DEPTH_COMPONENT : 0x1902,
+ALPHA : 0x1906,
+RGB : 0x1907,
+RGBA : 0x1908,
+LUMINANCE : 0x1909,
+LUMINANCE_ALPHA : 0x190A,
+UNSIGNED_SHORT_4_4_4_4 : 0x8033,
+UNSIGNED_SHORT_5_5_5_1 : 0x8034,
+UNSIGNED_SHORT_5_6_5 : 0x8363,
+FRAGMENT_SHADER : 0x8B30,
+VERTEX_SHADER : 0x8B31,
+MAX_VERTEX_ATTRIBS : 0x8869,
+MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB,
+MAX_VARYING_VECTORS : 0x8DFC,
+MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
+MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C,
+MAX_TEXTURE_IMAGE_UNITS : 0x8872,
+MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD,
+SHADER_TYPE : 0x8B4F,
+DELETE_STATUS : 0x8B80,
+LINK_STATUS : 0x8B82,
+VALIDATE_STATUS : 0x8B83,
+ATTACHED_SHADERS : 0x8B85,
+ACTIVE_UNIFORMS : 0x8B86,
+ACTIVE_ATTRIBUTES : 0x8B89,
+SHADING_LANGUAGE_VERSION : 0x8B8C,
+CURRENT_PROGRAM : 0x8B8D,
+NEVER : 0x0200,
+LESS : 0x0201,
+EQUAL : 0x0202,
+LEQUAL : 0x0203,
+GREATER : 0x0204,
+NOTEQUAL : 0x0205,
+GEQUAL : 0x0206,
+ALWAYS : 0x0207,
+KEEP : 0x1E00,
+REPLACE : 0x1E01,
+INCR : 0x1E02,
+DECR : 0x1E03,
+INVERT : 0x150A,
+INCR_WRAP : 0x8507,
+DECR_WRAP : 0x8508,
+VENDOR : 0x1F00,
+RENDERER : 0x1F01,
+VERSION : 0x1F02,
+//EXTENSIONS : 0x1F03,
+NEAREST : 0x2600,
+LINEAR : 0x2601,
+NEAREST_MIPMAP_NEAREST : 0x2700,
+LINEAR_MIPMAP_NEAREST : 0x2701,
+NEAREST_MIPMAP_LINEAR : 0x2702,
+LINEAR_MIPMAP_LINEAR : 0x2703,
+TEXTURE_MAG_FILTER : 0x2800,
+TEXTURE_MIN_FILTER : 0x2801,
+TEXTURE_WRAP_S : 0x2802,
+TEXTURE_WRAP_T : 0x2803,
+TEXTURE : 0x1702,
+TEXTURE_CUBE_MAP : 0x8513,
+TEXTURE_BINDING_CUBE_MAP : 0x8514,
+TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515,
+TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516,
+TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517,
+TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518,
+TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519,
+TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A,
+MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C,
+TEXTURE0 : 0x84C0,
+TEXTURE1 : 0x84C1,
+TEXTURE2 : 0x84C2,
+TEXTURE3 : 0x84C3,
+TEXTURE4 : 0x84C4,
+TEXTURE5 : 0x84C5,
+TEXTURE6 : 0x84C6,
+TEXTURE7 : 0x84C7,
+TEXTURE8 : 0x84C8,
+TEXTURE9 : 0x84C9,
+TEXTURE10 : 0x84CA,
+TEXTURE11 : 0x84CB,
+TEXTURE12 : 0x84CC,
+TEXTURE13 : 0x84CD,
+TEXTURE14 : 0x84CE,
+TEXTURE15 : 0x84CF,
+TEXTURE16 : 0x84D0,
+TEXTURE17 : 0x84D1,
+TEXTURE18 : 0x84D2,
+TEXTURE19 : 0x84D3,
+TEXTURE20 : 0x84D4,
+TEXTURE21 : 0x84D5,
+TEXTURE22 : 0x84D6,
+TEXTURE23 : 0x84D7,
+TEXTURE24 : 0x84D8,
+TEXTURE25 : 0x84D9,
+TEXTURE26 : 0x84DA,
+TEXTURE27 : 0x84DB,
+TEXTURE28 : 0x84DC,
+TEXTURE29 : 0x84DD,
+TEXTURE30 : 0x84DE,
+TEXTURE31 : 0x84DF,
+ACTIVE_TEXTURE : 0x84E0,
+REPEAT : 0x2901,
+CLAMP_TO_EDGE : 0x812F,
+MIRRORED_REPEAT : 0x8370,
+FLOAT_VEC2 : 0x8B50,
+FLOAT_VEC3 : 0x8B51,
+FLOAT_VEC4 : 0x8B52,
+INT_VEC2 : 0x8B53,
+INT_VEC3 : 0x8B54,
+INT_VEC4 : 0x8B55,
+BOOL : 0x8B56,
+BOOL_VEC2 : 0x8B57,
+BOOL_VEC3 : 0x8B58,
+BOOL_VEC4 : 0x8B59,
+FLOAT_MAT2 : 0x8B5A,
+FLOAT_MAT3 : 0x8B5B,
+FLOAT_MAT4 : 0x8B5C,
+SAMPLER_2D : 0x8B5E,
+SAMPLER_CUBE : 0x8B60,
+VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622,
+VERTEX_ATTRIB_ARRAY_SIZE : 0x8623,
+VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624,
+VERTEX_ATTRIB_ARRAY_TYPE : 0x8625,
+VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
+VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
+VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
+//IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A,
+//IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B,
+COMPILE_STATUS : 0x8B81,
+//SHADER_COMPILER : 0x8DFA,
+LOW_FLOAT : 0x8DF0,
+MEDIUM_FLOAT : 0x8DF1,
+HIGH_FLOAT : 0x8DF2,
+LOW_INT : 0x8DF3,
+MEDIUM_INT : 0x8DF4,
+HIGH_INT : 0x8DF5,
+FRAMEBUFFER : 0x8D40,
+RENDERBUFFER : 0x8D41,
+RGBA4 : 0x8056,
+RGB5_A1 : 0x8057,
+RGB565 : 0x8D62,
+DEPTH_COMPONENT16 : 0x81A5,
+STENCIL_INDEX8 : 0x8D48,
+DEPTH_STENCIL : 0x84F9,
+RENDERBUFFER_WIDTH : 0x8D42,
+RENDERBUFFER_HEIGHT : 0x8D43,
+RENDERBUFFER_INTERNAL_FORMAT : 0x8D44,
+RENDERBUFFER_RED_SIZE : 0x8D50,
+RENDERBUFFER_GREEN_SIZE : 0x8D51,
+RENDERBUFFER_BLUE_SIZE : 0x8D52,
+RENDERBUFFER_ALPHA_SIZE : 0x8D53,
+RENDERBUFFER_DEPTH_SIZE : 0x8D54,
+RENDERBUFFER_STENCIL_SIZE : 0x8D55,
+FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0,
+FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1,
+FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2,
+FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
+COLOR_ATTACHMENT0 : 0x8CE0,
+DEPTH_ATTACHMENT : 0x8D00,
+STENCIL_ATTACHMENT : 0x8D20,
+DEPTH_STENCIL_ATTACHMENT : 0x821A,
+NONE : 0,
+FRAMEBUFFER_COMPLETE : 0x8CD5,
+FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6,
+FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
+FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9,
+FRAMEBUFFER_UNSUPPORTED : 0x8CDD,
+FRAMEBUFFER_BINDING : 0x8CA6,
+RENDERBUFFER_BINDING : 0x8CA7,
+MAX_RENDERBUFFER_SIZE : 0x84E8,
+INVALID_FRAMEBUFFER_OPERATION : 0x0506,
+//FALSE : 0,
+//TRUE : 1,
+UNPACK_FLIP_Y_WEBGL : 0x9240,
+UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241
+}
+
+Tests.testOES20Constants = function(gl) {
+ for (var i in constants) {
+ assertProperty(gl, i) &&
+ assertEquals(i, gl[i], constants[i]);
+ }
+ var extended = false;
+ for (var i in gl) {
+ if (i.match(/^[A-Z_]+$/) && constants[i] == null) {
+ if (!extended) {
+ extended = true;
+ var h = document.createElement('h3');
+ h.textContent = "Also found the following extra constants";
+ __testLog__.appendChild(h);
+ }
+ log(i);
+ }
+ }
+}
+
+Tests.startUnit = function() {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+</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/conformance/fuzzTheAPI.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/fuzzTheAPI.html
new file mode 100644
index 0000000000..c1090aeb4b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/fuzzTheAPI.html
@@ -0,0 +1,116 @@
+<!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.autorun = false;
+Tests.message = "This will fuzz the API with random inputs for a [long] while."
+
+
+function randomCall(testProgress, gl, m, arities) {
+ doTestNotify(m);
+ var argcs = {};
+ var foundArity = false;
+ if (arities == null) {
+ testProgress.textContent += " 500 random arity calls on " + m + "\n";
+ for (var i=0; i<50; i++) {
+ for (var j=0; j<10; j++) {
+ var args = generateRandomArgs(j);
+// doTestNotify(m + ": " + args.toSource());
+ try {
+ gl[m].apply(gl, args);
+ argcs[j] = true;
+ foundArity = true;
+ } catch (e) {
+ }
+ }
+ }
+ for (var j in argcs) {
+ testProgress.textContent += "200 arity " + j + " calls on " + m + "\n";
+ for (var i=0; i<200; i++) {
+ var args = generateRandomArgs(j);
+// doTestNotify(m + ": " + args.toSource());
+ try {
+ gl[m].apply(gl, args);
+ argcs[j] = true;
+ } catch (e) {
+ }
+ }
+ }
+ } else {
+ for (var k=0; k<arities.length; k++) {
+ var j = arities[k];
+ testProgress.textContent += "500 arity " + j + " calls on " + m + "\n";
+ for (var i=0; i<500; i++) {
+ var args = generateRandomArgs(j);
+// doTestNotify(m + ": " + args.toSource());
+ try {
+ gl[m].apply(gl, args);
+ } catch (e) {
+ }
+ }
+ }
+ }
+// doTestNotify(m+"--OK");
+}
+
+Tests.testGetGLWeb20 = function() {
+ var testProgress = document.getElementById('testProgress');
+ var funcnames = document.getElementById('funcnames').value.split(",");
+ var canvas = document.getElementById('glweb20');
+ var gl;
+ assertOk(function(){gl = getGLContext(canvas);});
+ var funcs = [];
+ for (var i=0; i<funcnames.length; i++) {
+ var fn = funcnames[i];
+ fn = fn.replace(/^\s+|\s+$/g, '');
+ if (fn.length > 0)
+ funcs.push(fn);
+ }
+ if (funcs.length == 0) {
+ for (var m in gl)
+ try{if (typeof gl[m] == 'function')
+ funcs.push(m);}catch(e){}
+ }
+ var idx = 0;
+ var count = 0;
+ var limit = 1000;
+ var iv1;
+ var iv2;
+ iv1 = setInterval(function(){
+ if (idx >= funcs.length) {
+ iv2 = setInterval(function(){
+ if (count >= limit) {
+ clearInterval(iv2);
+ return false;
+ }
+ count++;
+ var f = Math.floor(Math.random() * funcs.length);
+ randomCall(testProgress, gl, funcs[f]);
+ }, 50);
+ clearInterval(iv1);
+ return false;
+ }
+ randomCall(testProgress, gl, funcs[idx]);
+ idx++;
+ }, 50);
+}
+
+</script>
+<style>canvas{ position:absolute; }</style>
+</head><body>
+ <canvas id="glweb20" width="16" height="16"></canvas>
+ <p>Optional: Enter a comma-separated list of functions to fuzz (leave blank for full API)</p>
+ <input type="text" size="40" id="funcnames" value="">
+ <pre id="testProgress"></pre>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/getContext.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/getContext.html
new file mode 100644
index 0000000000..14c0559123
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/getContext.html
@@ -0,0 +1,38 @@
+<!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.testGetWebGL = function() {
+ var canvas = document.getElementById('webgl');
+ var gl;
+ assertOk(function(){gl = getGLContext(canvas)});
+ assertEquals("ctx.canvas === canvas", gl.canvas, canvas);
+ assertOk(function(){g2d = canvas.getContext('2d')});
+ assert("Should get a null 2d context after getting webgl context", g2d === null);
+}
+
+Tests.testGet2D = function() {
+ var canvas = document.getElementById('2d');
+ var g2d;
+ var gl;
+ assertOk(function(){g2d = canvas.getContext('2d')});
+ assertOk(function(){gl = getGLContext(canvas)});
+ assert("Should get a null WebGL context after getting 2D context", gl === null);
+}
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+ <canvas id="2d" width="1" height="1"></canvas>
+ <canvas id="webgl" width="1" height="1"></canvas>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/methods.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/methods.html
new file mode 100644
index 0000000000..d6d14bd827
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/methods.html
@@ -0,0 +1,180 @@
+<!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">
+
+/*
+ The following tests are generated from
+ http://www.khronos.org/registry/gles/api/2.0/gl2.h
+ and api_modifications.txt
+*/
+var methods = ['canvas',
+"activeTexture",
+"attachShader",
+"bindAttribLocation",
+"bindBuffer",
+"bindFramebuffer",
+"bindRenderbuffer",
+"bindTexture",
+"blendColor",
+"blendEquation",
+"blendEquationSeparate",
+"blendFunc",
+"blendFuncSeparate",
+"bufferData",
+"bufferSubData",
+"checkFramebufferStatus",
+"clear",
+"clearColor",
+"clearDepth",
+"clearStencil",
+"colorMask",
+"compileShader",
+"copyTexImage2D",
+"copyTexSubImage2D",
+"createProgram",
+"createShader",
+"cullFace",
+"deleteBuffer",
+"deleteFramebuffer",
+"deleteProgram",
+"deleteRenderbuffer",
+"deleteShader",
+"deleteTexture",
+"depthFunc",
+"depthMask",
+"depthRange",
+"detachShader",
+"disable",
+"disableVertexAttribArray",
+"drawArrays",
+"drawElements",
+"enable",
+"enableVertexAttribArray",
+"finish",
+"flush",
+"framebufferRenderbuffer",
+"framebufferTexture2D",
+"frontFace",
+"createBuffer",
+"generateMipmap",
+"createFramebuffer",
+"createRenderbuffer",
+"createTexture",
+"getActiveAttrib",
+"getActiveUniform",
+"getAttachedShaders",
+"getAttribLocation",
+"getBufferParameter",
+"getError",
+"getExtension",
+"getSupportedExtensions",
+"getFramebufferAttachmentParameter",
+"getProgramInfoLog",
+"getRenderbufferParameter",
+"getShaderInfoLog",
+"getShaderSource",
+"getUniformLocation",
+"hint",
+"isBuffer",
+"isContextLost",
+"isEnabled",
+"isFramebuffer",
+"isProgram",
+"isRenderbuffer",
+"isShader",
+"isTexture",
+"lineWidth",
+"linkProgram",
+"polygonOffset",
+"readPixels",
+"renderbufferStorage",
+"sampleCoverage",
+"scissor",
+"shaderSource",
+"stencilFunc",
+"stencilFuncSeparate",
+"stencilMask",
+"stencilMaskSeparate",
+"stencilOp",
+"stencilOpSeparate",
+"texImage2D",
+"texParameteri",
+"texSubImage2D",
+"uniform1f",
+"uniform1fv",
+"uniform1i",
+"uniform1iv",
+"uniform2f",
+"uniform2fv",
+"uniform2i",
+"uniform2iv",
+"uniform3f",
+"uniform3fv",
+"uniform3i",
+"uniform3iv",
+"uniform4f",
+"uniform4fv",
+"uniform4i",
+"uniform4iv",
+"uniformMatrix2fv",
+"uniformMatrix3fv",
+"uniformMatrix4fv",
+"useProgram",
+"validateProgram",
+"vertexAttrib1f",
+"vertexAttrib1fv",
+"vertexAttrib2f",
+"vertexAttrib2fv",
+"vertexAttrib3f",
+"vertexAttrib3fv",
+"vertexAttrib4f",
+"vertexAttrib4fv",
+"vertexAttribPointer",
+"viewport",
+"getParameter",
+"getProgramParameter",
+"getShaderParameter",
+"getTexParameter",
+"getUniform",
+"getVertexAttrib"
+]
+
+Tests.testOES20Methods = function(gl) {
+ for (var i=0; i<methods.length; i++) {
+ assertProperty(gl, methods[i]);
+ }
+ var extended = false;
+ for (var i in gl) {
+ if (i.match(/^[a-z_]+$/) && methods.indexOf(i) == -1) {
+ if (!extended) {
+ extended = true;
+ var h = document.createElement('h3');
+ h.textContent = "Also found the following extra properties";
+ __testLog__.appendChild(h);
+ }
+ log(i);
+ }
+ }
+}
+
+Tests.startUnit = function() {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ return [gl];
+}
+
+</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/conformance/quickCheckAPI-A.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-A.html
new file mode 100644
index 0000000000..fe453457c3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-A.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-A.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B1.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B1.html
new file mode 100644
index 0000000000..6d34f27795
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B1.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-B1.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B2.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B2.html
new file mode 100644
index 0000000000..2a1ddd9bd9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B2.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-B2.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B3.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B3.html
new file mode 100644
index 0000000000..08e85dbc04
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B3.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-B3.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B4.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B4.html
new file mode 100644
index 0000000000..9ee5228e78
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B4.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-B4.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-C.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-C.html
new file mode 100644
index 0000000000..3717e41e77
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-C.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-C.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-D_G.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-D_G.html
new file mode 100644
index 0000000000..c692db331b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-D_G.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-D_G.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-G_I.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-G_I.html
new file mode 100644
index 0000000000..1f474892fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-G_I.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-G_I.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-L_S.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-L_S.html
new file mode 100644
index 0000000000..698e1c93d9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-L_S.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-L_S.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-S_V.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-S_V.html
new file mode 100644
index 0000000000..84e60151e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-S_V.html
@@ -0,0 +1,63 @@
+<!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="quickCheckAPI.js"></script>
+<script type="application/javascript" src="argGenerators-S_V.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators work
+// when called with randomly generated valid arguments
+Tests.testValidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ if (!gen.noAlreadyTriedCheck) {
+ var src = Object.toSource(args);
+ if (alreadyTriedArgs[src])
+ return true;
+
+ alreadyTriedArgs[src] = true;
+ }
+ var ok = false;
+ // if we have an validity checker, assert that the generated args are valid
+ if (gen.checkArgValidity)
+ assert("Valid args: "+name+"("+argsToString(args)+")",
+ gen.checkArgValidity.apply(gen, args));
+ var rv;
+ // assert that GL function works when called with valid args
+ assertOk("This should work: "+name+"("+argsToString(args)+")",
+ function(){rv = GL[name].apply(GL, args); ok = true;});
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup)
+ assertOk("Cleaning up return value after "+name+"("+argsToString(args)+")",
+ function() { gen.returnValueCleanup(rv); });
+ return ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI.js
new file mode 100644
index 0000000000..50e74963e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI.js
@@ -0,0 +1,414 @@
+/*
+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.
+*/
+
+/*
+ QuickCheck tests for WebGL:
+
+ 1. Write a valid arg generator for each function
+ 1.1. Write valid arg predicates to use with random generator:
+ if value passes generator, accept it as valid.
+ 1.2. Often needs initializing and cleanup:
+ setup - generate - cleanup
+ gl.createBuffer - test(bindBufferGenerator) - gl.deleteBuffer
+
+ 2. Write an invalid arg generator
+ 2.1. Take valid args, modify an arg until the args no longer pass
+ checkArgValidity.
+ 2.2. Repeat for all args.
+
+ 3. Test functions using the generators
+ 3.1. Args generated with the valid arg generator should pass
+ assertOk(f(args))
+ 3.2. Args generated with the invalid arg generator should pass
+ assertFail(f(args))
+*/
+var GLcanvas = document.createElement('canvas');
+var canvas2D = document.createElement('canvas');
+GLcanvas.width = GLcanvas.height = 256;
+GL = getGLContext(GLcanvas);
+Array.from = function(o) {
+ var a = [];
+ for (var i=0; i<o.length; i++)
+ a.push(o[i]);
+ return a;
+}
+Array.prototype.has = function(v) { return this.indexOf(v) != -1; }
+Array.prototype.random = function() { return this[randomInt(this.length)]; }
+
+castToInt = function(o) {
+ if (typeof o == 'number')
+ return isNaN(o) ? 0 : Math.floor(o);
+ if (o == true) return 1;
+ return 0;
+};
+
+// Creates a constant checker / generator from its arguments.
+//
+// E.g. if you want a constant checker for the constants 1, 2, and 3, you
+// would do the following:
+//
+// var cc = constCheck(1,2,3);
+// var randomConst = cc.random();
+// if (cc.has(randomConst))
+// console.log("randomConst is included in cc's constants");
+//
+constCheck = function() {
+ var a = Array.from(arguments);
+ a.has = function(v) { return this.indexOf(castToInt(v)) != -1; };
+ return a;
+}
+
+bindTextureTarget = constCheck(GL.TEXTURE_2D, GL.TEXTURE_CUBE_MAP);
+blendEquationMode = constCheck(GL.FUNC_ADD, GL.FUNC_SUBTRACT, GL.FUNC_REVERSE_SUBTRACT);
+blendFuncSfactor = constCheck(
+ GL.ZERO, GL.ONE, GL.SRC_COLOR, GL.ONE_MINUS_SRC_COLOR, GL.DST_COLOR,
+ GL.ONE_MINUS_DST_COLOR, GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.DST_ALPHA,
+ GL.ONE_MINUS_DST_ALPHA, GL.CONSTANT_COLOR, GL.ONE_MINUS_CONSTANT_COLOR,
+ GL.CONSTANT_ALPHA, GL.ONE_MINUS_CONSTANT_ALPHA, GL.SRC_ALPHA_SATURATE
+);
+blendFuncDfactor = constCheck(
+ GL.ZERO, GL.ONE, GL.SRC_COLOR, GL.ONE_MINUS_SRC_COLOR, GL.DST_COLOR,
+ GL.ONE_MINUS_DST_COLOR, GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.DST_ALPHA,
+ GL.ONE_MINUS_DST_ALPHA, GL.CONSTANT_COLOR, GL.ONE_MINUS_CONSTANT_COLOR,
+ GL.CONSTANT_ALPHA, GL.ONE_MINUS_CONSTANT_ALPHA
+);
+bufferTarget = constCheck(GL.ARRAY_BUFFER, GL.ELEMENT_ARRAY_BUFFER);
+bufferMode = constCheck(GL.STREAM_DRAW, GL.STATIC_DRAW, GL.DYNAMIC_DRAW);
+clearMask = constCheck(
+ GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT | GL.STENCIL_BUFFER_BIT,
+ GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT,
+ GL.COLOR_BUFFER_BIT | GL.STENCIL_BUFFER_BIT,
+ GL.DEPTH_BUFFER_BIT | GL.STENCIL_BUFFER_BIT,
+ GL.COLOR_BUFFER_BIT, GL.DEPTH_BUFFER_BIT, GL.STENCIL_BUFFER_BIT, 0
+);
+cullFace = constCheck(GL.FRONT, GL.BACK, GL.FRONT_AND_BACK);
+depthFuncFunc = constCheck(
+ GL.NEVER, GL.LESS, GL.EQUAL, GL.LEQUAL, GL.GREATER, GL.NOTEQUAL,
+ GL.GEQUAL, GL.ALWAYS
+);
+stencilFuncFunc = depthFuncFunc;
+enableCap = constCheck(
+ GL.BLEND, GL.CULL_FACE, GL.DEPTH_TEST, GL.DITHER, GL.POLYGON_OFFSET_FILL,
+ GL.SAMPLE_ALPHA_TO_COVERAGE, GL.SAMPLE_COVERAGE, GL.SCISSOR_TEST,
+ GL.STENCIL_TEST
+);
+frontFaceMode = constCheck(GL.CCW, GL.CW);
+getParameterPname = constCheck(
+ GL.ACTIVE_TEXTURE || "GL.ACTIVE_TEXTURE",
+ GL.ALIASED_LINE_WIDTH_RANGE || "GL.ALIASED_LINE_WIDTH_RANGE",
+ GL.ALIASED_POINT_SIZE_RANGE || "GL.ALIASED_POINT_SIZE_RANGE",
+ GL.ALPHA_BITS || "GL.ALPHA_BITS",
+ GL.ARRAY_BUFFER_BINDING || "GL.ARRAY_BUFFER_BINDING",
+ GL.BLEND || "GL.BLEND",
+ GL.BLEND_COLOR || "GL.BLEND_COLOR",
+ GL.BLEND_DST_ALPHA || "GL.BLEND_DST_ALPHA",
+ GL.BLEND_DST_RGB || "GL.BLEND_DST_RGB",
+ GL.BLEND_EQUATION_ALPHA || "GL.BLEND_EQUATION_ALPHA",
+ GL.BLEND_EQUATION_RGB || "GL.BLEND_EQUATION_RGB",
+ GL.BLEND_SRC_ALPHA || "GL.BLEND_SRC_ALPHA",
+ GL.BLEND_SRC_RGB || "GL.BLEND_SRC_RGB",
+ GL.BLUE_BITS || "GL.BLUE_BITS",
+ GL.COLOR_CLEAR_VALUE || "GL.COLOR_CLEAR_VALUE",
+ GL.COLOR_WRITEMASK || "GL.COLOR_WRITEMASK",
+ GL.COMPRESSED_TEXTURE_FORMATS || "GL.COMPRESSED_TEXTURE_FORMATS",
+ GL.CULL_FACE || "GL.CULL_FACE",
+ GL.CULL_FACE_MODE || "GL.CULL_FACE_MODE",
+ GL.CURRENT_PROGRAM || "GL.CURRENT_PROGRAM",
+ GL.DEPTH_BITS || "GL.DEPTH_BITS",
+ GL.DEPTH_CLEAR_VALUE || "GL.DEPTH_CLEAR_VALUE",
+ GL.DEPTH_FUNC || "GL.DEPTH_FUNC",
+ GL.DEPTH_RANGE || "GL.DEPTH_RANGE",
+ GL.DEPTH_TEST || "GL.DEPTH_TEST",
+ GL.DEPTH_WRITEMASK || "GL.DEPTH_WRITEMASK",
+ GL.DITHER || "GL.DITHER",
+ GL.ELEMENT_ARRAY_BUFFER_BINDING || "GL.ELEMENT_ARRAY_BUFFER_BINDING",
+ GL.FRAMEBUFFER_BINDING || "GL.FRAMEBUFFER_BINDING",
+ GL.FRONT_FACE || "GL.FRONT_FACE",
+ GL.GENERATE_MIPMAP_HINT || "GL.GENERATE_MIPMAP_HINT",
+ GL.GREEN_BITS || "GL.GREEN_BITS",
+ GL.LINE_WIDTH || "GL.LINE_WIDTH",
+ GL.MAX_COMBINED_TEXTURE_IMAGE_UNITS || "GL.MAX_COMBINED_TEXTURE_IMAGE_UNITS",
+ GL.MAX_CUBE_MAP_TEXTURE_SIZE || "GL.MAX_CUBE_MAP_TEXTURE_SIZE",
+ GL.MAX_FRAGMENT_UNIFORM_VECTORS || "GL.MAX_FRAGMENT_UNIFORM_VECTORS",
+ GL.MAX_RENDERBUFFER_SIZE || "GL.MAX_RENDERBUFFER_SIZE",
+ GL.MAX_TEXTURE_IMAGE_UNITS || "GL.MAX_TEXTURE_IMAGE_UNITS",
+ GL.MAX_TEXTURE_SIZE || "GL.MAX_TEXTURE_SIZE",
+ GL.MAX_VARYING_VECTORS || "GL.MAX_VARYING_VECTORS",
+ GL.MAX_VERTEX_ATTRIBS || "GL.MAX_VERTEX_ATTRIBS",
+ GL.MAX_VERTEX_TEXTURE_IMAGE_UNITS || "GL.MAX_VERTEX_TEXTURE_IMAGE_UNITS",
+ GL.MAX_VERTEX_UNIFORM_VECTORS || "GL.MAX_VERTEX_UNIFORM_VECTORS",
+ GL.MAX_VIEWPORT_DIMS || "GL.MAX_VIEWPORT_DIMS",
+ GL.PACK_ALIGNMENT || "GL.PACK_ALIGNMENT",
+ GL.POLYGON_OFFSET_FACTOR || "GL.POLYGON_OFFSET_FACTOR",
+ GL.POLYGON_OFFSET_FILL || "GL.POLYGON_OFFSET_FILL",
+ GL.POLYGON_OFFSET_UNITS || "GL.POLYGON_OFFSET_UNITS",
+ GL.RED_BITS || "GL.RED_BITS",
+ GL.RENDERBUFFER_BINDING || "GL.RENDERBUFFER_BINDING",
+ GL.SAMPLE_BUFFERS || "GL.SAMPLE_BUFFERS",
+ GL.SAMPLE_COVERAGE_INVERT || "GL.SAMPLE_COVERAGE_INVERT",
+ GL.SAMPLE_COVERAGE_VALUE || "GL.SAMPLE_COVERAGE_VALUE",
+ GL.SAMPLES || "GL.SAMPLES",
+ GL.SCISSOR_BOX || "GL.SCISSOR_BOX",
+ GL.SCISSOR_TEST || "GL.SCISSOR_TEST",
+ GL.STENCIL_BACK_FAIL || "GL.STENCIL_BACK_FAIL",
+ GL.STENCIL_BACK_FUNC || "GL.STENCIL_BACK_FUNC",
+ GL.STENCIL_BACK_PASS_DEPTH_FAIL || "GL.STENCIL_BACK_PASS_DEPTH_FAIL",
+ GL.STENCIL_BACK_PASS_DEPTH_PASS || "GL.STENCIL_BACK_PASS_DEPTH_PASS",
+ GL.STENCIL_BACK_REF || "GL.STENCIL_BACK_REF",
+ GL.STENCIL_BACK_VALUE_MASK || "GL.STENCIL_BACK_VALUE_MASK",
+ GL.STENCIL_BACK_WRITEMASK || "GL.STENCIL_BACK_WRITEMASK",
+ GL.STENCIL_BITS || "GL.STENCIL_BITS",
+ GL.STENCIL_CLEAR_VALUE || "GL.STENCIL_CLEAR_VALUE",
+ GL.STENCIL_FAIL || "GL.STENCIL_FAIL",
+ GL.STENCIL_FUNC || "GL.STENCIL_FUNC",
+ GL.STENCIL_PASS_DEPTH_FAIL || "GL.STENCIL_PASS_DEPTH_FAIL",
+ GL.STENCIL_PASS_DEPTH_PASS || "GL.STENCIL_PASS_DEPTH_PASS",
+ GL.STENCIL_REF || "GL.STENCIL_REF",
+ GL.STENCIL_TEST || "GL.STENCIL_TEST",
+ GL.STENCIL_VALUE_MASK || "GL.STENCIL_VALUE_MASK",
+ GL.STENCIL_WRITEMASK || "GL.STENCIL_WRITEMASK",
+ GL.SUBPIXEL_BITS || "GL.SUBPIXEL_BITS",
+ GL.TEXTURE_BINDING_2D || "GL.TEXTURE_BINDING_2D",
+ GL.TEXTURE_BINDING_CUBE_MAP || "GL.TEXTURE_BINDING_CUBE_MAP",
+ GL.UNPACK_ALIGNMENT || "GL.UNPACK_ALIGNMENT",
+ GL.VIEWPORT || "GL.VIEWPORT"
+);
+mipmapHint = constCheck(GL.FASTEST, GL.NICEST, GL.DONT_CARE);
+pixelStoreiPname = constCheck(GL.PACK_ALIGNMENT, GL.UNPACK_ALIGNMENT);
+pixelStoreiParam = constCheck(1,2,4,8);
+shaderType = constCheck(GL.VERTEX_SHADER, GL.FRAGMENT_SHADER);
+stencilOp = constCheck(GL.KEEP, GL.ZERO, GL.REPLACE, GL.INCR, GL.INCR_WRAP,
+ GL.DECR, GL.DECR_WRAP, GL.INVERT);
+texImageTarget = constCheck(
+ 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
+);
+texImageInternalFormat = constCheck(
+ GL.ALPHA,
+ GL.LUMINANCE,
+ GL.LUMINANCE_ALPHA,
+ GL.RGB,
+ GL.RGBA
+);
+texImageFormat = constCheck(
+ GL.ALPHA,
+ GL.LUMINANCE,
+ GL.LUMINANCE_ALPHA,
+ GL.RGB,
+ GL.RGBA
+);
+texImageType = constCheck(GL.UNSIGNED_BYTE);
+texParameterPname = constCheck(
+ GL.TEXTURE_MIN_FILTER, GL.TEXTURE_MAG_FILTER,
+ GL.TEXTURE_WRAP_S, GL.TEXTURE_WRAP_T);
+texParameterParam = {};
+texParameterParam[GL.TEXTURE_MIN_FILTER] = constCheck(
+ GL.NEAREST, GL.LINEAR, GL.NEAREST_MIPMAP_NEAREST, GL.LINEAR_MIPMAP_NEAREST,
+ GL.NEAREST_MIPMAP_LINEAR, GL.LINEAR_MIPMAP_LINEAR);
+texParameterParam[GL.TEXTURE_MAG_FILTER] = constCheck(GL.NEAREST, GL.LINEAR);
+texParameterParam[GL.TEXTURE_WRAP_S] = constCheck(
+ GL.CLAMP_TO_EDGE, GL.MIRRORED_REPEAT, GL.REPEAT);
+texParameterParam[GL.TEXTURE_WRAP_T] = texParameterParam[GL.TEXTURE_WRAP_S];
+textureUnit = constCheck.apply(this, (function(){
+ var textureUnits = [];
+ var texUnits = GL.getParameter(GL.MAX_TEXTURE_IMAGE_UNITS);
+ for (var i=0; i<texUnits; i++) textureUnits.push(GL['TEXTURE'+i]);
+ return textureUnits;
+})());
+
+var StencilBits = GL.getParameter(GL.STENCIL_BITS);
+var MaxStencilValue = 1 << StencilBits;
+
+var MaxVertexAttribs = GL.getParameter(GL.MAX_VERTEX_ATTRIBS);
+var LineWidthRange = GL.getParameter(GL.ALIASED_LINE_WIDTH_RANGE);
+
+// Returns true if bufData can be passed to GL.bufferData
+isBufferData = function(bufData) {
+ if (typeof bufData == 'number')
+ return bufData >= 0;
+ if (bufData instanceof ArrayBuffer)
+ return true;
+ return WebGLArrayTypes.some(function(t) {
+ return bufData instanceof t;
+ });
+};
+
+isVertexAttribute = function(idx) {
+ if (typeof idx != 'number') return false;
+ return idx >= 0 && idx < MaxVertexAttribs;
+};
+
+isValidName = function(name) {
+ if (typeof name != 'string') return false;
+ for (var i=0; i<name.length; i++) {
+ var c = name.charCodeAt(i);
+ if (c & 0x00FF == 0 || c & 0xFF00 == 0) {
+ return false;
+ }
+ }
+ return true;
+};
+
+WebGLArrayTypes = [
+ Float32Array,
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array
+];
+webGLArrayContentGenerators = [randomLength, randomSmallIntArray];
+randomWebGLArray = function() {
+ var t = WebGLArrayTypes.random();
+ return new t(webGLArrayContentGenerators.random()());
+};
+
+randomArrayBuffer = function(buflen) {
+ if (buflen == null) buflen = 256;
+ var len = randomInt(buflen)+1;
+ var rv;
+ try {
+ rv = new ArrayBuffer(len);
+ } catch(e) {
+ log("Error creating ArrayBuffer with length " + len);
+ throw(e);
+ }
+ return rv;
+};
+
+bufferDataGenerators = [randomLength, randomWebGLArray, randomArrayBuffer];
+randomBufferData = function() {
+ return bufferDataGenerators.random()();
+};
+
+randomSmallWebGLArray = function(buflen) {
+ var t = WebGLArrayTypes.random();
+ return new t(randomInt(buflen/4)+1);
+};
+
+bufferSubDataGenerators = [randomSmallWebGLArray, randomArrayBuffer];
+randomBufferSubData = function(buflen) {
+ var data = bufferSubDataGenerators.random()(buflen);
+ var offset = randomInt(buflen - data.byteLength);
+ return {data:data, offset:offset};
+};
+
+randomColor = function() {
+ return [Math.random(), Math.random(), Math.random(), Math.random()];
+};
+
+randomName = function() {
+ var arr = [];
+ var len = randomLength()+1;
+ for (var i=0; i<len; i++) {
+ var l = randomInt(255)+1;
+ var h = randomInt(255)+1;
+ var c = (h << 8) | l;
+ arr.push(String.fromCharCode(c));
+ }
+ return arr.join('');
+};
+randomVertexAttribute = function() {
+ return randomInt(MaxVertexAttribs);
+};
+
+randomBool = function() { return Math.random() > 0.5; };
+
+randomStencil = function() {
+ return randomInt(MaxStencilValue);
+};
+
+randomLineWidth = function() {
+ var lo = LineWidthRange[0],
+ hi = LineWidthRange[1];
+ return randomFloatFromRange(lo, hi);
+};
+
+randomImage = function(w,h) {
+ var img;
+ var r = Math.random();
+ if (r < 0.25) {
+ img = document.createElement('canvas');
+ img.width = w; img.height = h;
+ img.getContext('2d').fillRect(0,0,w,h);
+ } else if (r < 0.5) {
+ img = document.createElement('video');
+ img.muted = true;
+ img.width = w; img.height = h;
+ } else if (r < 0.75) {
+ img = document.createElement('img');
+ img.width = w; img.height = h;
+ } else {
+ img = canvas2D.getContext('2d').createImageData(w,h);
+ }
+ return img
+};
+
+mutateArgs = function(args) {
+ var mutateCount = randomIntFromRange(1, args.length);
+ var newArgs = Array.from(args);
+ for (var i=0; i<mutateCount; i++) {
+ var idx = randomInt(args.length);
+ newArgs[idx] = generateRandomArg(idx, args.length);
+ }
+ return newArgs;
+};
+
+// Calls testFunction numberOfTests times with arguments generated by
+// argGen.generate() (or empty arguments if no generate present).
+//
+// The arguments testFunction is called with are the generated args,
+// the argGen, and what argGen.setup() returned or [] if argGen has not setup
+// method. I.e. testFunction(generatedArgs, argGen, setupVars).
+//
+argGeneratorTestRunner = function(argGen, testFunction, numberOfTests) {
+ // do argument generator setup if needed
+ var setupVars = argGen.setup ? argGen.setup() : [];
+ var error;
+ for (var i=0; i<numberOfTests; i++) {
+ var failed = false;
+ // generate arguments if argGen has a generate method
+ var generatedArgs = argGen.generate ? argGen.generate.apply(argGen, setupVars) : [];
+ try {
+ // call testFunction with the generated args
+ testFunction.call(this, generatedArgs, argGen, setupVars);
+ } catch (e) {
+ failed = true;
+ error = e;
+ }
+ // if argGen needs cleanup for generated args, do it here
+ if (argGen.cleanup)
+ argGen.cleanup.apply(argGen, generatedArgs);
+ if (failed) break;
+ }
+ // if argGen needs to do a final cleanup for setupVars, do it here
+ if (argGen.teardown)
+ argGen.teardown.apply(argGen, setupVars);
+ if (error) throw(error);
+};
+
+// TODO: Remove this
+// WebKit or at least Chrome is really slow at laying out strings with
+// unprintable characters. Without this tests can take 30-90 seconds.
+// With this they're instant.
+sanitize = function(str) {
+ var newStr = [];
+ for (var ii = 0; ii < str.length; ++ii) {
+ var c = str.charCodeAt(ii);
+ newStr.push((c > 31 && c < 128) ? str[ii] : "?");
+ }
+ return newStr.join('');
+};
+
+argsToString = function(args) {
+ return sanitize(args.map(function(a){return Object.toSource(a)}).join(","));
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPIBadArgs.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPIBadArgs.html
new file mode 100644
index 0000000000..fb65bf2ad1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPIBadArgs.html
@@ -0,0 +1,82 @@
+<!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="quickCheckAPI.js"></script>
+
+<script type="application/javascript">
+
+// Test that all GL functions specified in ArgGenerators fail
+// when called with randomly generated invalid arguments
+// Works only on tests with checkArgValidity defined
+Tests.testInvalidArgs = function() {
+ var randomTestCount = 100;
+ for (var name in ArgGenerators) {
+ try {
+ if (!GL[name])
+ throw (new Error(name + " is missing from the WebGL context"));
+ var argGen = ArgGenerators[name];
+ var alreadyTriedArgs = {};
+ if (!argGen.generate || !argGen.checkArgValidity) continue;
+ // test each GL function with randomTestCount randomly generated valid args
+ argGeneratorTestRunner(argGen, function(args, gen, setupVars) {
+ var mutatedArgs;
+ var foundArgs = false;
+ for (var j=0; j<100; j++) {
+ mutatedArgs = mutateArgs(args);
+ var validArgs = false;
+ try {
+ validArgs = gen.checkArgValidity.apply(gen, mutatedArgs);
+ } catch(e) {}
+ if (!validArgs) {
+ if (gen.noAlreadyTriedCheck) {
+ foundArgs = true;
+ break; // found new invalid args
+ }
+ var src = Object.toSource(mutatedArgs);
+ if (!alreadyTriedArgs[src]) {
+ alreadyTriedArgs[src] = true;
+ foundArgs = true;
+ break; // found new invalid args
+ }
+ }
+ }
+ if (!foundArgs)
+ return true;
+ var ok = false;
+ var rv;
+ // assert that GL function fails when called with invalid args
+ assertFail("This should fail: "+name+"("+argsToString(mutatedArgs)+")",
+ function(){
+ GL.getError(); // clear off existing error
+ rv = GL[name].apply(GL, mutatedArgs);
+ throwError(GL, name);
+ ok = true;
+ });
+ // if we need to cleanup the return value, do it here
+ // e.g. calling gl.deleteBuffer(rv) after testing gl.createBuffer() above
+ if (gen.returnValueCleanup && rv != null) {
+ assertOk("Cleaning up return value after "+name+"("+argsToString(mutatedArgs)+")",
+ function() { gen.returnValueCleanup(rv); });
+ }
+ GL.getError();
+ return !ok;
+ }, argGen.testCount || randomTestCount);
+ } catch(e) {
+ testFailed(name, e.name, formatError(e));
+ }
+ }
+}
+
+</script>
+<style>canvas{position:absolute;}</style>
+</head><body>
+</body></html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/webGLArrays.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/webGLArrays.html
new file mode 100644
index 0000000000..bd3eba036d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/webGLArrays.html
@@ -0,0 +1,165 @@
+<!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">
+
+function assertIdxs(name, arr, length) {
+// assertOk(name+": Read with negative idx should work", function(){ return arr[-1] });
+// assertOk(name+": Read with too large idx should work", function(){ return arr[length] });
+// assertOk(name+": Write with negative idx should work", function(){ arr[-1] = 0 });
+// assertOk(name+": Write with too large idx should work", function(){ arr[length] = 0 });
+// arr[0] = 2;
+// assertEquals(name+": Test that write worked", 2, arr[0]);
+// assertOk(name+": Write with bad value should work", function(){ arr[0] = {x:"foo"} });
+// assertEquals(name+": Test that bad write didn't work", 2, arr[0]);
+ assertOk(name+": Read and writes with OK idxs should work", function(){
+ for (var i=0; i<length; i++) arr[i] = i + 1;
+ for (var i=0; i<length; i++) arr[i] = arr[i] + 1;
+ for (var i=0; i<length; i++) assertEquals(name+": Test that reads and writes work", i+2, arr[i]);
+ });
+}
+
+Tests.startUnit = function () {
+ var canvas = document.getElementById('gl');
+ var gl = wrapGLContext(getGLContext(canvas));
+ prog = new Shader(gl, 'vert', 'frag');
+ prog.use();
+ prog.uniform4f('c', 255, 0, 0, 255);
+ va = prog.attrib('Vertex');
+ buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ return [gl];
+}
+
+Tests.endUnit = function() {
+ prog.destroy();
+}
+
+Tests.testCreateFromArray = function() {
+ var a = new Float32Array([1,2,3,4,5,6]);
+ assertIdxs('Float', a, 6);
+ var a = new Int32Array([1,2,3,4,5,6]);
+ assertIdxs('Int', a, 6);
+ var a = new Int16Array([1,2,3,4,5,6]);
+ assertIdxs('Short', a, 6);
+ var a = new Int8Array([1,2,3,4,5,6]);
+ assertIdxs('Byte', a, 6);
+ var a = new Uint32Array([1,2,3,4,5,6]);
+ assertIdxs('UInt', a, 6);
+ var a = new Uint16Array([1,2,3,4,5,6]);
+ assertIdxs('UShort', a, 6);
+ var a = new Uint8Array([1,2,3,4,5,6]);
+ assertIdxs('UByte', a, 6);
+}
+Tests.testCreateFromCount = function() {
+ var a = new Float32Array(6);
+ assertIdxs('Float', a, 6);
+ var a = new Int32Array(6);
+ assertIdxs('Int', a, 6);
+ var a = new Int16Array(6);
+ assertIdxs('Short', a, 6);
+ var a = new Int8Array(6);
+ assertIdxs('Byte', a, 6);
+ var a = new Uint32Array(6);
+ assertIdxs('UInt', a, 6);
+ var a = new Uint16Array(6);
+ assertIdxs('UShort', a, 6);
+ var a = new Uint8Array(6);
+ assertIdxs('UByte', a, 6);
+}
+Tests.testCreateFromBuffer = function() {
+ var sz = 24;
+ var b = new ArrayBuffer(sz);
+ var a = new Float32Array(b);
+ assertIdxs('Float', a, sz/4);
+ var a = new Int32Array(b);
+ assertIdxs('Int', a, sz/4);
+ var a = new Int16Array(b);
+ assertIdxs('Short', a, sz/2);
+ var a = new Int8Array(b);
+ assertIdxs('Byte', a, sz/1);
+ var a = new Uint32Array(b);
+ assertIdxs('UInt', a, sz/4);
+ var a = new Uint16Array(b);
+ assertIdxs('UShort', a, sz/2);
+ var a = new Uint8Array(b);
+ assertIdxs('UByte', a, sz/1);
+}
+
+Tests.testThatWritesChangeDrawing = function(gl) {
+ var verts = [
+ 0,0,
+ 1,0,
+ 1,1,
+
+ 0,0,
+ 1,1,
+ 0,1
+ ];
+ var a = new Float32Array(verts);
+ var arr = [];
+ for (var i=0; i<12; i++)
+ arr[i] = a[i];
+ assertEquals("Test that reads work from an array-initialized Float32Array", arr, verts);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(va, 2, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(va);
+
+ var id = new Uint8Array(4);
+ gl.readPixels(8,8,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertEquals([0, 0, 0, 0], [id[0], id[1], id[2], id[3]]);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ gl.readPixels(8,8,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertEquals([255, 0, 0, 255], [id[0], id[1], id[2], id[3]]);
+ gl.readPixels(0,8,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertEquals([0, 0, 0, 0], [id[0], id[1], id[2], id[3]]);
+
+ a[0] = a[6] = a[10] = -1;
+ gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(va, 2, gl.FLOAT, false, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ gl.readPixels(8,8,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertEquals([255, 0, 0, 255], [id[0], id[1], id[2], id[3]]);
+ gl.readPixels(0,8,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertEquals("Test that Float32Array#[]= worked and drawArrays drew a full-width rectangle",
+ [255, 0, 0, 255], [id[0], id[1], id[2], id[3]]);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, id);
+ assertEquals([0, 0, 0, 0], [id[0], id[1], id[2], id[3]]);
+}
+
+</script>
+<script id="vert" type="x-shader/x-vertex">
+ attribute vec2 Vertex;
+ void main()
+ {
+ gl_Position = vec4(Vertex, 0.0, 1.0);
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+ precision mediump float;
+
+ uniform vec4 c;
+ void main()
+ {
+ gl_FragColor = c;
+ }
+</script>
+<style>canvas{border: 1px solid black}</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/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,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAATVElEQVR4nO3d+VPUd57Hcf2b9k9Y+z44+qK7OZoGFVA5VfBGzah9cxpNzGEOoRua5lBEue/DK4fZ7MapmSm3Mlshu8xOdCpDJt3v/aEBAUHAOMG4z0fV53fqU/V6fd7fT/e32bEDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwOvBkar7l+3+GwBsk8xUrT0rTb8vx2Q45janlu7YsWPnsgXgTeYwak85U3Xv5ZiM3+XbUh/l2dICBc6080WZ1ur92baSHRQB8GayGdUWu1HzoSNFO+ZM1f2cbTLM51lT5woc5rkDObbZ/Vm2SEm23VvsyjhV5nJQBsCbxGZQVtmN6p4Mo/YPdqNGHKlayUrXJ9zWlESh0xIvzsmYL3HZ54pzMm6VuRyRMpfTW+pyUAbAm8BmVNVnGNTTdqP6vzOMGrGnaMSZqpNsk17ybKlS6DTL/ixbotRlj5flOubL3I65MpfjVrnbEalYKINSl335vQGA3wKbUW2xGdWRDKP66wyjWhYLwJGiFWeaTrJNBnFbU2SP3ST7s6xSmmuXcrczUe52xstzHfPlbsdcudt5qyzX3lKWlxkszXGeK8mxnyzJySjeQRkArzebQVllM6p7bUb149UF4EjVSmaaTrLS9eKypMgee7ocyLZJmdshFXmZUpHnXFEGB/OzJsrdjqEyt/NmWa49XJbt9Ja6Mk4Vu7hEBF5LNr2q3mZQz9gM6u9XFEBqsgCcaTrJXJgEci0pstdhkv3ZNinNTZbAofwsOZSfJQfzMqU8z5kodzsSZbmOeIXb+XW52zFa5nLcKnPZI2ULl4jFfKIAvB7MOrXFZlBHbAb11zaj+kmGUbNuAWSm65dKYHdGmhRlWqQ8zyFHCnLk+L5cOV6UK0cKXVK5J1sO5mdKhdspZavKoDTX0VPiciTLIHtFGVAIwK/NYlBW2fTqXptB/dhmSJ7+LyqArHS95JiTJVDgNEllQZZ4KgulrrpU6qtLJXBsv5wt3yMn9rvlaIFLDi8vg1xH4mB+5p+Wl0Fpjr2lJMcRLM6ynyvOzjhxIIt7A+BXY9Gr6q0L4/9SAaRoxL7w/L9WAWSbDJJrTZFid4Z4jxZJU/1xufHhOem+ek6il0/LB74qaTxTJoGj++Vs2R45vj9XjhTkyOHdC48JC2VwaHfmnyrczn+vcDsmynLtQyU5GTeLczLCpTk2T3GW7VhxVsae7d4f4I1l1qktVoM6YjOovrYa1D8sFoB9WQE415kA8u1pcvRAjnwUOiLDLQG5190o9242ylRHnQyG/XLz6nmJXqqWD3yV0nC6VPxH98nZst1yfF+uHC10SdXebDmUnyyDqoLs7w7lZ35b7nb8scxt/7dSl32kJCejqyQn40pJTkbZDiYC4NWzaJVVVr2q12ZQPbYa1H9fuwB0SwWQla6XLFOyAAoyTfLW4T3SfuWM3L3RIA/7L8vD/svyZe8l+ezW23Kvu1EmO2ploNkn3VfPSevb1fK+t1Iaz5RJ7cli8R0pktOl+XKsKFkGBxfKoHJv1l8P5mf+uSLP8fvyXMdMmdsRKXc5qotdGQXbvV/AG8WiV9Vb9aoZq141azOoxWbcXAHkWlOkJC9Dak8Xy61PL8iDnotLBbBUBH2X5Yvbl+RBz0W5e6NBJtprpL/ZJzc/Oi/XP3hLWi6ekvc8h6WuukS8Vc/KYPEC8WhhzpOqguzvKvdmfXV4d2b3wfzM9w/lZTENAK+CWaewWHWqiE2v+tqqV/2w2QLINhkkP2Nh/K89ImNtIfmi99Kz8Pcl15dL65J80XtJPr/1tty/2Sh3uxvkzvV6GY+FpO+aV65/8DuJXDwpVzyHpO7UQhmU5MvRIpdU7c2RQ7uz5MR+9x+OFbnuHi3MiVQVuKoP784u2u79A37TLFpllVWn6rXqVY+tetWPGxbAsgvAvU6TvHVot8SunJY7N+rly761g/9lb3J9sWx9fvuSfH77bXnQc1HudTfITFedjLWFpPeaR7o+eEvCjSflyoVDUlddKsHjB+TC4UI5VZwnVQU5ibcq9nx1ujS/58QB99XqYnf5DqYB4OVYdM/Gf6te9Y/k8//GBeCyGKXEnSE11Qek55Pzcv9m48rQrxP8L25fki9uvy2fr1qf3bqYnAxuNMh0Z52MRINy+1OPXP/wd9J+5Yw015+Qd84flJqTxXLhcIGcLM77+UhBzt8uVBa2nqvce/ZsxZ6y7d5L4Ddlcfy36FVfW/SqH6wGlawugMWvATvTlhWAySB5GalydH+OfFRzREajQfn81tvrh/6FwV9cF+WzWxflwa2Lcr/notzrbpSZ6/Uy1VUnkx21MtwSkJ5PLkjHe2elqf64XD53UEInDiQuHC6Yry7Omz1W5HrY+FbF4R1MA8DmWLTKKsuy8d9qUL+wAJZ/C3CPM13OHtwtbe+elunr9fLFusF/PvSf31o7+A96nq37PRflfk+j3L+Z/Fjx7o0Gme6qk4n2Ghlq8UvPx+el/coZuVZ3XC6fq/i57lTx32pOHngUOlUc/jR4lEtCYCMWnareolfNWPSqWatB9dOaBbDGl4BcFqMUu20SOnVAbn58Tu52N27qtP98g9A/WAz9QvAX173FEuhukLvdDcnJoLNWxmM1Mhjxy82Pzknn+2cSsXdPz4cbT8x+GKh8+FHwSO0OSgBYm1mnsJh1qohFr1wY/5XxZwWw/teAs9KTvwtwZH+2XA1VyXBrUB70XFz/tF9nzN9K8O91N8i9hfAvrjs3GuTOjXqZXnhEGG+vkdFoUAbD/p97Pj7/t56r57/pu+b5pOXd6qPbvdfAa8ei3VVl0al6LXrlY4tO+aNFr0pstgD2ONLlzMHdEn2nWqY66+SzlxzzHywb858L/TrBv3vjWfgX18z15JruqpOpzlqZaA8lxmKhv49Gg3/oD/s+3u69Bl47Fp2i3qJVzVh0ylmrTvmTVZ+8AFz5HsDzBZBjNkpxrk2Cpw5I90fn5M6Nhhee9lsOfvfmg3/n+rPwz1yvk5muOpleWJMdtfHJjprvJjtqKABgueT4r4iYdcqvzbpdP1j0yvjqArCv9SJQul7ctlSp2pctHwYrZaglIPdvNq5/2r/gYm9Twb+x9eBPd9XJVHISmJ/qrP1murOGRwBgOZN2V5VFp+y1aBfGf50ysVQAa3wHYLEAstL1stuRLqcr8qX18imZ7KiVBz0XXxj6jZ/vNxn86xsHP/kIUCdTnXXx6c7av0x11PRs914Drx2TTlFv0ipmzDrlrEWn/MmiV8lmCiDbbJADuTYJntwvN67+Tmau1ydDvmbot36x9yz49S8Z/NrFNT/dVfv7qc66k9u918BrxaxePf4r4hsVgHPh9wBzrSlSVZQtHwQqZTDil7vdjVs77bcY/JmtB1+mOmsTkx21T6a6ake2e6+B145Ju6vKpFP2mrTKx2bts/F/8VuALyqA3fY0OV2eLy2XTspEe43cf8Gz/TYEXyY7amWyoyY+1VHz/VRnXfN27zXw2lka/7XKWYtW+ZNFp5TNFEC2ySD7XVYJnNgnXR++JdNddZs+7X+d4NfKZEeNTHbUzE921Dya5PIPWClNrbCYtcnx36Td9YNZp4hbdKqNC2Bh/K8szJL3/YdlIOyTOzcatvwx3sY3+r8o+DLZEUpMtNc8mehg/AeeY1LvqjJplb0mjeKxWav40axVJlYXwFpvAmam6STfnibVZXkSefukjMVCcrd7EyP+eqf9loJfu2HwJzpqZKK9RsbbQ/HJ9tD3k501jP/AaiaNot6kSY7/Zq3iJ7NOKYsXgC8qgCyTQfblWMV/fJ90fnBWJjtrV4z3Wzntn7vRv/586Lca/GcrND/RHno02c74D6yQplZYTFpFxKRVLI3/Kwvg+ReB7CnJ3wFwWVLkcGGWvOc/LP3NXpm5Xv/LT/tNBn9yE8EfT4Y/MR4LPRlvDzH+A6uZNYpKk3ZXb/rC+G/SKhKbLYC8jDQ5VZYn4YsnZLQtKHdubC70mx3zf0nwx9tDMh4LyVgsFB+PBb8fb2f8B56TrlHUp2sV0yaNYmn830wBZKXrZV+2RXzH90nH+2dloqMmWQCv4LR/+eCHloK/EH4ZjwXnx2PBR2PtQcZ/YDmTRpmarlY0mTS7vkrTKP5q0ip+NuuUYtmgABypWnFZjHKoIFOueA9JX5NHprvqNh36zZ72vyT4C+FPjLYFn4zHgoz/wGomza7d6ZpdMZNG8Y1Jo3hi1i48/2+iAPIyUuVkqVuaGk/ISDQoM9df3Wm/Mvg1Ww7+WCwkY21BGW0Lxkfbgt+PxUKM/8BqaZpdu9PUiiaTRvGVSav4y9InABsUQGa6XoqyLeI9ViTt752R8fbQqsC/4tN+i8EfawvKaDQoI9HA/Ghb8JuxKOM/8ByT5l9T09SKQLpGMWTSKv7TrFU8NeuUieUFYFv1YyCOVK3kmJPj/7veg9J7zSNTnbWv6LR/BcFfWCPRQHwkGvjLSDTAm3/AetLVyjyTRvmOSauYNOsU35p1yn9sVABuW6qcLM2Vaw3HZbg1INNdr+a0X/sz/K0FfzQalNFoIHn6RwO/H2kL8uYf8CImza5Ck27Xe2atcsqiU8bXLYAUjWSm66QwyyzeY4USu3JaxmKhtUP/i0/7mhWhXxH8tvWCH5SRaEBGo4HESKv/yWhrgMs/YDPSdcois1bxvkWnfGrRK+NrFYA9RSvZZoMc3OuUdzwH5fa1CzLRUfNPPe3H1zjt1wv+4hpuDcRHooHvR6IBLv+AzTLrlEVmnfKhRad8al3z58C04ralyImSXLnWcEyGWv0y2VkrU13Ph/6lTvsNgj+6QfBHWgMy3BqQ4Vb//HBr4NFI1M/lH7AVFr0qYNGrHlr1qqc2gyq+/E1AZ5pOCrNM4jlaIG1XTstoW/Cfd9q/VPADMtzqTwy3+J8MM/4DL2XnihIwquI2o1rsKRrJNhmkYq9DLl+okFufnJfx9ppnoV/vc/utnvaxNcb8TQU/IMOtfhlq8ceHW/zfD0cDF7Z7I4Hfqp02vSpg06se2gzqpxlGTdyeopFca4ocL3HJp/VHZTDik4mOzY34L33ab+7EXwz+wvLND7cEbo20BjK3exOB37KdNqM6YDOoH2YY1U+dabp4QaZJLhzZK9F3q2UkGpCJDU/70Ks77TcMvl+GWnyJwYjvyVBL4J3t3jzgTbDTZlQHMoyah9lm/dOKPc74pfPl0vPxORmLhX6d035TwV9YEV98sMU/NRDm8g94VXbaU7UBl8X48ESJ6+kn9Ud+Hgh7EuPtoVdz2rdtJvQvDv5gxLewvH8ciHg7hloClu3eNOBNstNtSw34jxc9bH2nenaoxTc33h6aH4uF4uPtwcR48n/u/RNO+80G3ydDEd//DIR99wbCvsbt3izgTbTzaqgy0PPxufBINBAbbw89Go+FZsdjobnx9tDcaCw4P9oWjI/FgomxWCAx+gpO++G1xvxVwR+M+GQw7P1xMOx7PBj29fZHvFXbvVHAm2rn4prsrKkd6wiFR9tDsfH2mthILPRorC04O9YWmhuNheZG2wLzI9FgfLQtkBiNBhLPhf4XnPaLayDik4GwTwbC3v8daPY+HIj4Pupv9jL+A7+CncvXeHtN7WgsGB6NhWKjsVBsJBp8NBoNzo5EA3MLa364NRAfafUnhpPr5U77lcGXgbD37wNhz5/7m70jA2HPmW3eE+D/rZWF0BasHW4LhkeigdhILBQbbg08Gm4NzA63+OeGW/xzQ63++aEWf3yoxZdIrmWhb3k+9INLoV8KvvQ3e+MDzd4f+ps9/9Ef9rYNRHyObd4DAAtWFMJoW7B2uDUYHooGYkPRQGyoxf9oqMU3OxTxzQ1FfHNDLb75oYgvPhjxJpZWeO3gJ8PvSfQ3eX8aCHtn+5u9M33NXP4Br7MVhTDcGqgdbvWHB1v9scFWf2ww4n80GPHNDoa9c4MR39xg2Ds3EPbOD4S98YGwJzEQ9iT6m73S3+yVvmbPfH+zZ76vyfO0v9n7p75mb29/M5d/wG/Jc4Uw1OIP90f8scGIP9Yf8ccGwr5HA2Hv7ECzd26g2TvXlwx9vK/Z821/s+e/+po83/Y3eT7ra/Y0cfkH/LbtXL2GWny1A2FfuC/sjfWHvbH+Zs+jvrD3Zm+TZ6i3yTPW1+yZ7GvyXO9r9vi3908H8M+wohB6m7xlt695Tw6EfecGw15ff5Pnnb5mT6D32oUD2/x3AvgV7dyxY8fOgSavu7/Jk9V3zave7j8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICV/g9tPJEQu1XvmQAAAABJRU5ErkJggg==">
+<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,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAATVElEQVR4nO3d+VPUd57Hcf2b9k9Y+z44+qK7OZoGFVA5VfBGzah9cxpNzGEOoRua5lBEue/DK4fZ7MapmSm3Mlshu8xOdCpDJt3v/aEBAUHAOMG4z0fV53fqU/V6fd7fT/e32bEDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwOvBkar7l+3+GwBsk8xUrT0rTb8vx2Q45janlu7YsWPnsgXgTeYwak85U3Xv5ZiM3+XbUh/l2dICBc6080WZ1ur92baSHRQB8GayGdUWu1HzoSNFO+ZM1f2cbTLM51lT5woc5rkDObbZ/Vm2SEm23VvsyjhV5nJQBsCbxGZQVtmN6p4Mo/YPdqNGHKlayUrXJ9zWlESh0xIvzsmYL3HZ54pzMm6VuRyRMpfTW+pyUAbAm8BmVNVnGNTTdqP6vzOMGrGnaMSZqpNsk17ybKlS6DTL/ixbotRlj5flOubL3I65MpfjVrnbEalYKINSl335vQGA3wKbUW2xGdWRDKP66wyjWhYLwJGiFWeaTrJNBnFbU2SP3ST7s6xSmmuXcrczUe52xstzHfPlbsdcudt5qyzX3lKWlxkszXGeK8mxnyzJySjeQRkArzebQVllM6p7bUb149UF4EjVSmaaTrLS9eKypMgee7ocyLZJmdshFXmZUpHnXFEGB/OzJsrdjqEyt/NmWa49XJbt9Ja6Mk4Vu7hEBF5LNr2q3mZQz9gM6u9XFEBqsgCcaTrJXJgEci0pstdhkv3ZNinNTZbAofwsOZSfJQfzMqU8z5kodzsSZbmOeIXb+XW52zFa5nLcKnPZI2ULl4jFfKIAvB7MOrXFZlBHbAb11zaj+kmGUbNuAWSm65dKYHdGmhRlWqQ8zyFHCnLk+L5cOV6UK0cKXVK5J1sO5mdKhdspZavKoDTX0VPiciTLIHtFGVAIwK/NYlBW2fTqXptB/dhmSJ7+LyqArHS95JiTJVDgNEllQZZ4KgulrrpU6qtLJXBsv5wt3yMn9rvlaIFLDi8vg1xH4mB+5p+Wl0Fpjr2lJMcRLM6ynyvOzjhxIIt7A+BXY9Gr6q0L4/9SAaRoxL7w/L9WAWSbDJJrTZFid4Z4jxZJU/1xufHhOem+ek6il0/LB74qaTxTJoGj++Vs2R45vj9XjhTkyOHdC48JC2VwaHfmnyrczn+vcDsmynLtQyU5GTeLczLCpTk2T3GW7VhxVsae7d4f4I1l1qktVoM6YjOovrYa1D8sFoB9WQE415kA8u1pcvRAjnwUOiLDLQG5190o9242ylRHnQyG/XLz6nmJXqqWD3yV0nC6VPxH98nZst1yfF+uHC10SdXebDmUnyyDqoLs7w7lZ35b7nb8scxt/7dSl32kJCejqyQn40pJTkbZDiYC4NWzaJVVVr2q12ZQPbYa1H9fuwB0SwWQla6XLFOyAAoyTfLW4T3SfuWM3L3RIA/7L8vD/svyZe8l+ezW23Kvu1EmO2ploNkn3VfPSevb1fK+t1Iaz5RJ7cli8R0pktOl+XKsKFkGBxfKoHJv1l8P5mf+uSLP8fvyXMdMmdsRKXc5qotdGQXbvV/AG8WiV9Vb9aoZq141azOoxWbcXAHkWlOkJC9Dak8Xy61PL8iDnotLBbBUBH2X5Yvbl+RBz0W5e6NBJtprpL/ZJzc/Oi/XP3hLWi6ekvc8h6WuukS8Vc/KYPEC8WhhzpOqguzvKvdmfXV4d2b3wfzM9w/lZTENAK+CWaewWHWqiE2v+tqqV/2w2QLINhkkP2Nh/K89ImNtIfmi99Kz8Pcl15dL65J80XtJPr/1tty/2Sh3uxvkzvV6GY+FpO+aV65/8DuJXDwpVzyHpO7UQhmU5MvRIpdU7c2RQ7uz5MR+9x+OFbnuHi3MiVQVuKoP784u2u79A37TLFpllVWn6rXqVY+tetWPGxbAsgvAvU6TvHVot8SunJY7N+rly761g/9lb3J9sWx9fvuSfH77bXnQc1HudTfITFedjLWFpPeaR7o+eEvCjSflyoVDUlddKsHjB+TC4UI5VZwnVQU5ibcq9nx1ujS/58QB99XqYnf5DqYB4OVYdM/Gf6te9Y/k8//GBeCyGKXEnSE11Qek55Pzcv9m48rQrxP8L25fki9uvy2fr1qf3bqYnAxuNMh0Z52MRINy+1OPXP/wd9J+5Yw015+Qd84flJqTxXLhcIGcLM77+UhBzt8uVBa2nqvce/ZsxZ6y7d5L4Ddlcfy36FVfW/SqH6wGlawugMWvATvTlhWAySB5GalydH+OfFRzREajQfn81tvrh/6FwV9cF+WzWxflwa2Lcr/notzrbpSZ6/Uy1VUnkx21MtwSkJ5PLkjHe2elqf64XD53UEInDiQuHC6Yry7Omz1W5HrY+FbF4R1MA8DmWLTKKsuy8d9qUL+wAJZ/C3CPM13OHtwtbe+elunr9fLFusF/PvSf31o7+A96nq37PRflfk+j3L+Z/Fjx7o0Gme6qk4n2Ghlq8UvPx+el/coZuVZ3XC6fq/i57lTx32pOHngUOlUc/jR4lEtCYCMWnareolfNWPSqWatB9dOaBbDGl4BcFqMUu20SOnVAbn58Tu52N27qtP98g9A/WAz9QvAX173FEuhukLvdDcnJoLNWxmM1Mhjxy82Pzknn+2cSsXdPz4cbT8x+GKh8+FHwSO0OSgBYm1mnsJh1qohFr1wY/5XxZwWw/teAs9KTvwtwZH+2XA1VyXBrUB70XFz/tF9nzN9K8O91N8i9hfAvrjs3GuTOjXqZXnhEGG+vkdFoUAbD/p97Pj7/t56r57/pu+b5pOXd6qPbvdfAa8ei3VVl0al6LXrlY4tO+aNFr0pstgD2ONLlzMHdEn2nWqY66+SzlxzzHywb858L/TrBv3vjWfgX18z15JruqpOpzlqZaA8lxmKhv49Gg3/oD/s+3u69Bl47Fp2i3qJVzVh0ylmrTvmTVZ+8AFz5HsDzBZBjNkpxrk2Cpw5I90fn5M6Nhhee9lsOfvfmg3/n+rPwz1yvk5muOpleWJMdtfHJjprvJjtqKABgueT4r4iYdcqvzbpdP1j0yvjqArCv9SJQul7ctlSp2pctHwYrZaglIPdvNq5/2r/gYm9Twb+x9eBPd9XJVHISmJ/qrP1murOGRwBgOZN2V5VFp+y1aBfGf50ysVQAa3wHYLEAstL1stuRLqcr8qX18imZ7KiVBz0XXxj6jZ/vNxn86xsHP/kIUCdTnXXx6c7av0x11PRs914Drx2TTlFv0ipmzDrlrEWn/MmiV8lmCiDbbJADuTYJntwvN67+Tmau1ydDvmbot36x9yz49S8Z/NrFNT/dVfv7qc66k9u918BrxaxePf4r4hsVgHPh9wBzrSlSVZQtHwQqZTDil7vdjVs77bcY/JmtB1+mOmsTkx21T6a6ake2e6+B145Ju6vKpFP2mrTKx2bts/F/8VuALyqA3fY0OV2eLy2XTspEe43cf8Gz/TYEXyY7amWyoyY+1VHz/VRnXfN27zXw2lka/7XKWYtW+ZNFp5TNFEC2ySD7XVYJnNgnXR++JdNddZs+7X+d4NfKZEeNTHbUzE921Dya5PIPWClNrbCYtcnx36Td9YNZp4hbdKqNC2Bh/K8szJL3/YdlIOyTOzcatvwx3sY3+r8o+DLZEUpMtNc8mehg/AeeY1LvqjJplb0mjeKxWav40axVJlYXwFpvAmam6STfnibVZXkSefukjMVCcrd7EyP+eqf9loJfu2HwJzpqZKK9RsbbQ/HJ9tD3k501jP/AaiaNot6kSY7/Zq3iJ7NOKYsXgC8qgCyTQfblWMV/fJ90fnBWJjtrV4z3Wzntn7vRv/586Lca/GcrND/RHno02c74D6yQplZYTFpFxKRVLI3/Kwvg+ReB7CnJ3wFwWVLkcGGWvOc/LP3NXpm5Xv/LT/tNBn9yE8EfT4Y/MR4LPRlvDzH+A6uZNYpKk3ZXb/rC+G/SKhKbLYC8jDQ5VZYn4YsnZLQtKHdubC70mx3zf0nwx9tDMh4LyVgsFB+PBb8fb2f8B56TrlHUp2sV0yaNYmn830wBZKXrZV+2RXzH90nH+2dloqMmWQCv4LR/+eCHloK/EH4ZjwXnx2PBR2PtQcZ/YDmTRpmarlY0mTS7vkrTKP5q0ip+NuuUYtmgABypWnFZjHKoIFOueA9JX5NHprvqNh36zZ72vyT4C+FPjLYFn4zHgoz/wGomza7d6ZpdMZNG8Y1Jo3hi1i48/2+iAPIyUuVkqVuaGk/ISDQoM9df3Wm/Mvg1Ww7+WCwkY21BGW0Lxkfbgt+PxUKM/8BqaZpdu9PUiiaTRvGVSav4y9InABsUQGa6XoqyLeI9ViTt752R8fbQqsC/4tN+i8EfawvKaDQoI9HA/Ghb8JuxKOM/8ByT5l9T09SKQLpGMWTSKv7TrFU8NeuUieUFYFv1YyCOVK3kmJPj/7veg9J7zSNTnbWv6LR/BcFfWCPRQHwkGvjLSDTAm3/AetLVyjyTRvmOSauYNOsU35p1yn9sVABuW6qcLM2Vaw3HZbg1INNdr+a0X/sz/K0FfzQalNFoIHn6RwO/H2kL8uYf8CImza5Ck27Xe2atcsqiU8bXLYAUjWSm66QwyyzeY4USu3JaxmKhtUP/i0/7mhWhXxH8tvWCH5SRaEBGo4HESKv/yWhrgMs/YDPSdcois1bxvkWnfGrRK+NrFYA9RSvZZoMc3OuUdzwH5fa1CzLRUfNPPe3H1zjt1wv+4hpuDcRHooHvR6IBLv+AzTLrlEVmnfKhRad8al3z58C04ralyImSXLnWcEyGWv0y2VkrU13Ph/6lTvsNgj+6QfBHWgMy3BqQ4Vb//HBr4NFI1M/lH7AVFr0qYNGrHlr1qqc2gyq+/E1AZ5pOCrNM4jlaIG1XTstoW/Cfd9q/VPADMtzqTwy3+J8MM/4DL2XnihIwquI2o1rsKRrJNhmkYq9DLl+okFufnJfx9ppnoV/vc/utnvaxNcb8TQU/IMOtfhlq8ceHW/zfD0cDF7Z7I4Hfqp02vSpg06se2gzqpxlGTdyeopFca4ocL3HJp/VHZTDik4mOzY34L33ab+7EXwz+wvLND7cEbo20BjK3exOB37KdNqM6YDOoH2YY1U+dabp4QaZJLhzZK9F3q2UkGpCJDU/70Ks77TcMvl+GWnyJwYjvyVBL4J3t3jzgTbDTZlQHMoyah9lm/dOKPc74pfPl0vPxORmLhX6d035TwV9YEV98sMU/NRDm8g94VXbaU7UBl8X48ESJ6+kn9Ud+Hgh7EuPtoVdz2rdtJvQvDv5gxLewvH8ciHg7hloClu3eNOBNstNtSw34jxc9bH2nenaoxTc33h6aH4uF4uPtwcR48n/u/RNO+80G3ydDEd//DIR99wbCvsbt3izgTbTzaqgy0PPxufBINBAbbw89Go+FZsdjobnx9tDcaCw4P9oWjI/FgomxWCAx+gpO++G1xvxVwR+M+GQw7P1xMOx7PBj29fZHvFXbvVHAm2rn4prsrKkd6wiFR9tDsfH2mthILPRorC04O9YWmhuNheZG2wLzI9FgfLQtkBiNBhLPhf4XnPaLayDik4GwTwbC3v8daPY+HIj4Pupv9jL+A7+CncvXeHtN7WgsGB6NhWKjsVBsJBp8NBoNzo5EA3MLa364NRAfafUnhpPr5U77lcGXgbD37wNhz5/7m70jA2HPmW3eE+D/rZWF0BasHW4LhkeigdhILBQbbg08Gm4NzA63+OeGW/xzQ63++aEWf3yoxZdIrmWhb3k+9INLoV8KvvQ3e+MDzd4f+ps9/9Ef9rYNRHyObd4DAAtWFMJoW7B2uDUYHooGYkPRQGyoxf9oqMU3OxTxzQ1FfHNDLb75oYgvPhjxJpZWeO3gJ8PvSfQ3eX8aCHtn+5u9M33NXP4Br7MVhTDcGqgdbvWHB1v9scFWf2ww4n80GPHNDoa9c4MR39xg2Ds3EPbOD4S98YGwJzEQ9iT6m73S3+yVvmbPfH+zZ76vyfO0v9n7p75mb29/M5d/wG/Jc4Uw1OIP90f8scGIP9Yf8ccGwr5HA2Hv7ECzd26g2TvXlwx9vK/Z821/s+e/+po83/Y3eT7ra/Y0cfkH/LbtXL2GWny1A2FfuC/sjfWHvbH+Zs+jvrD3Zm+TZ6i3yTPW1+yZ7GvyXO9r9vi3908H8M+wohB6m7xlt695Tw6EfecGw15ff5Pnnb5mT6D32oUD2/x3AvgV7dyxY8fOgSavu7/Jk9V3zave7j8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICV/g9tPJEQu1XvmQAAAABJRU5ErkJggg==">
+<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>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/arrayOutOfBounds.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/arrayOutOfBounds.html
new file mode 100644
index 0000000000..195b224a9e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/arrayOutOfBounds.html
@@ -0,0 +1,258 @@
+<!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.testOk = function(gl) {
+ var sh = new Filter(gl, 'okvert', 'frag');
+ assertOk(function(){sh.apply();});
+ sh.destroy();
+
+ var sh = new Filter(gl, 'vert', 'okfrag');
+ assertOk(function(){sh.apply();});
+ sh.destroy();
+
+ var sh = new Filter(gl, 'vert', 'frag');
+ assertOk(function(){sh.apply();});
+ sh.destroy();
+}
+
+var arr = ['cr', 'cw', 'vr', 'vw'];
+arr.forEach(function(e){
+ if (e == 'cr' || e == 'cw') {
+ Tests['test'+e+'vert'] = function(gl) {
+ var sh = new Filter(gl, e+'vert', 'frag');
+ assertFail(function(){sh.apply();});
+ sh.destroy();
+ }
+ }
+ Tests['test'+e+'frag'] = function(gl) {
+ var sh = new Filter(gl, 'vert', e+'frag');
+ assertFail(function(){sh.apply();});
+ sh.destroy();
+ }
+});
+
+
+</script>
+<script id="okvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex;
+ attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Tex;
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ gl_Position = vec4(Vertex, x[2]);
+ }
+</script>
+<script id="crvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex;
+ attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Tex;
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ gl_Position = vec4(Vertex, x[4]);
+ }
+</script>
+<script id="cwvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex;
+ attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Tex;
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ x[4] = Vertex.z;
+ gl_Position = vec4(Vertex, x[4]);
+ }
+</script>
+<!-- This one can't be required to fail compilation, because vertex shaders must support arbitrary array indexing -->
+<script id="vrvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex;
+ attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Tex;
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ int idx = 4 * int(max(1.0, Vertex.x*20.0));
+ gl_Position = vec4(Vertex, x[idx]);
+ }
+</script>
+<!-- This one can't be required to fail compilation, because vertex shaders must support arbitrary array indexing -->
+<script id="vwvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex;
+ attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Tex;
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ int idx = 4 * int(max(1.0, Vertex.x*20.0));
+ x[idx] = Vertex.z;
+ gl_Position = vec4(Vertex, x[idx]);
+ }
+</script>
+<script id="vert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex;
+ attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Tex;
+ gl_Position = vec4(Vertex, 0.0);
+ }
+</script>
+
+<script id="okfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ varying vec2 TexCoord;
+
+ void main()
+ {
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ gl_FragColor = vec4(1.0, 0.0, TexCoord.s, x[2]);
+ }
+</script>
+<script id="crfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ varying vec2 TexCoord;
+
+ void main()
+ {
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+ gl_FragColor = vec4(1.0, 0.0, TexCoord.s, x[4]);
+ }
+</script>
+<script id="cwfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ varying vec2 TexCoord;
+
+ void main()
+ {
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+
+ x[4] = 6.0;
+ gl_FragColor = vec4(1.0, 0.0, TexCoord.s, x[4]);
+ }
+</script>
+<!-- This one actually fails because of WebGL's restrictions on indexing expressions in fragment shaders -->
+<script id="vrfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ varying vec2 TexCoord;
+
+ void main()
+ {
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+
+ int idx = 4 * int(max(1.0, TexCoord.x*20.0));
+ gl_FragColor = vec4(1.0, 0.0, TexCoord.s, x[idx]);
+ }
+</script>
+<!-- This one actually fails because of WebGL's restrictions on indexing expressions in fragment shaders -->
+<script id="vwfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ varying vec2 TexCoord;
+
+ void main()
+ {
+ float x[3];
+ x[0] = 1.0;
+ x[1] = 2.0;
+ x[2] = 3.0;
+
+ int idx = 4 * int(max(1.0, TexCoord.x*20.0));
+ x[idx] = 6.0;
+ gl_FragColor = vec4(1.0, 0.0, TexCoord.s, x[idx]);
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ varying vec2 TexCoord;
+
+ void main()
+ {
+ gl_FragColor = vec4(1.0, 0.0, TexCoord.s, 1.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/glsl/uniformOutOfBounds.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/uniformOutOfBounds.html
new file mode 100644
index 0000000000..c53347e604
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/uniformOutOfBounds.html
@@ -0,0 +1,196 @@
+<!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];
+}
+
+var arr = ['cr', 'cw', 'vr', 'vw', 'tvw'];
+arr.forEach(function(e){
+ Tests['test'+e+'vert'] = function(gl) {
+ var sh = new Filter(gl, e+'vert', 'frag');
+ assertFail(function(){sh.apply(function(f){
+ f.uniform3fv('x', [0.0, 1.0, 2.0]);
+ throwError(e+"vert");
+ });});
+ sh.destroy();
+ }
+ Tests['test'+e+'frag'] = function(gl) {
+ var sh = new Filter(gl, 'vert', e+'frag');
+ assertFail(function(){sh.apply(function(f){
+ f.uniform3fv('x', [0.0, 1.0, 2.0]);
+ throwError(e+"frag");
+ });});
+ sh.destroy();
+ }
+});
+
+</script>
+<script id="crvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex; attribute vec2 Tex;
+ uniform float x[3];
+ void main()
+ {
+ gl_Position = vec4(Vertex.st, Tex.s, x[4]);
+ }
+</script>
+<script id="cwvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex; attribute vec2 Tex;
+ uniform float x[3];
+ void main()
+ {
+ x[4] = Vertex.z;
+ gl_Position = vec4(Vertex.st, Tex.s, x[4]);
+ }
+</script>
+<script id="vrvert" type="x-shader/x-vertex">
+
+
+ uniform float x[3];
+ attribute vec3 Vertex; attribute vec2 Tex;
+ void main()
+ {
+ float idx = 40.0 * max(1.0, Vertex.x*20.0);
+ gl_Position = vec4(Vertex, x[2] + Tex.s + x[int(idx)]);
+ }
+</script>
+<script id="vwvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex; attribute vec2 Tex;
+ uniform float x[3];
+ void main()
+ {
+ int idx = 4 * int(max(1.0, Vertex.x*20.0));
+ x[idx] = Vertex.z;
+ gl_Position = vec4(Vertex.st, Tex.s, x[idx]);
+ }
+</script>
+<script id="tvwvert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex; attribute vec2 Tex;
+ uniform float x[3];
+ void main()
+ {
+ int idx = 4 * int(max(1.0, Vertex.x*20.0));
+ x[2] = Vertex[idx];
+ gl_Position = vec4(Vertex.st, Tex.s, x[2]);
+ }
+</script>
+<script id="vert" type="x-shader/x-vertex">
+
+
+ attribute vec3 Vertex; attribute vec2 Tex;
+ varying vec2 TexCoord;
+ void main()
+ {
+ TexCoord = Vertex.st;
+ gl_Position = vec4(Vertex, Tex.s);
+ }
+</script>
+
+<script id="crfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ uniform float x[3];
+
+ varying vec2 TexCoord;
+ void main()
+ {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, x[4]);
+ }
+</script>
+<script id="cwfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ uniform float x[3];
+
+ varying vec2 TexCoord;
+ void main()
+ {
+ x[4] = 6.0;
+ gl_FragColor = vec4(1.0, 0.0, 0.0, x[4]);
+ }
+</script>
+<script id="vrfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ uniform float x[3];
+
+ varying vec2 TexCoord;
+ void main()
+ {
+ int idx = 4 * int(max(1.0, TexCoord.s*20.0));
+ gl_FragColor = vec4(1.0, 0.0, 0.0, x[idx]);
+ }
+</script>
+<script id="vwfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ uniform float x[3];
+
+ varying vec2 TexCoord;
+ void main()
+ {
+ int idx = 4 * int(max(1.0, TexCoord.s*20.0));
+ x[idx] = 6.0;
+ gl_FragColor = vec4(1.0, 0.0, 0.0, x[idx]);
+ }
+</script>
+<script id="tvwfrag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ uniform float x[3];
+
+ varying vec2 TexCoord;
+ void main()
+ {
+ int idx = 4 * int(max(1.0, TexCoord.s*20.0));
+ x[2] = TexCoord[idx];
+ gl_FragColor = vec4(1.0, 0.0, 0.0, x[2]);
+ }
+</script>
+<script id="frag" type="x-shader/x-fragment">
+
+
+ precision mediump float;
+
+ void main()
+ {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+</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/index.html b/dom/canvas/test/webgl-conf/checkout/conformance/more/index.html
new file mode 100644
index 0000000000..2be2bd3a8d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/index.html
@@ -0,0 +1,75 @@
+<!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>WebGL tests</title>
+ </head>
+ <body>
+
+ <h1>Tests for the WebGL canvas context</h1>
+
+ <h2>These tests are intended to serve the following purposes:</h2>
+ <ul>
+ <li>Assert spec conformance (so that WebGL pages work the same across browsers and hardware)</li>
+ <li>Check the safety of the GL binding (bounds checking, same origin policy)</li>
+ <li>Provide performance numbers for developers</li>
+ </ul>
+
+ <h2>Test runners</h2>
+ <ul>
+ <li><a href="all_tests_linkonly.html">Run tests manually</a></li>
+ <li><a href="all_tests.html">Run all tests in parallel</a></li>
+ <li><a href="all_tests_sequential.html">Run all tests sequentially</a></li>
+ </ul>
+
+
+ <h2>Demos</h2>
+ <ul>
+ <li><a href="demos/opengl_web.html">OpenGL for the web</a> (requires working FBOs and null textures or using canvases as textures)</li>
+ <li><a href="demos/video.html">Green screen video demo with a color remapping filter</a> (requires loading &lt;video> to texture with texImage2D)</li>
+ </ul>
+
+ <h2>Running the tests</h2>
+
+ <ol>
+ <li><a href="http://learningwebgl.com/blog/?p=11">Install a browser with WebGL support</a></li>
+ <li>Open one of the test runners linked above in your browser.</li>
+ <li>For more control over the tests, go the <a href="http://github.com/kig/canvas3d-tests">GitHub page</a>, see the readme, and clone the repo.</li>
+ </ol>
+
+ <h2>Want to contribute?</h2>
+
+ <p>See the <a href="README.md">README</a>.</p>
+ <p>See the <a href="http://github.com/kig/canvas3d-tests">GitHub page</a>.</p>
+ <p>Mail me at <a href="mailto:ilmari.heikkinen@gmail.com">ilmari.heikkinen@gmail.com</a></p>
+
+
+ <h2>For more information on WebGL</h2>
+
+ <ul>
+ <li><a href="http://planet-webgl.org">Planet WebGL</a></li>
+ <li><a href="http://learningwebgl.com">Learning WebGL</a></li>
+ <li><a href="http://www.khronos.org/message_boards/viewforum.php?f=34">WebGL on Khronos Message Boards</a></li>
+ </ul>
+
+ <h2>Developer links</h2>
+ <ul>
+ <li><a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=webgl">WebGL on Mozilla Bugzilla</a></li>
+ <li><a href="https://bugzilla.webkit.org/buglist.cgi?quicksearch=webgl">WebGL on WebKit Bugzilla</a></li>
+ <li><a href="http://code.google.com/p/chromium/issues/list?q=label:3D-WebGL">WebGL on Chromium Bugzilla</a></li>
+ </ul>
+
+
+ <h2>License</h2>
+
+ <p>
+ These tests are released under the BSD license. The images and videos used in the tests are the respective property of their authors.
+ </p>
+
+ </body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/unit.css b/dom/canvas/test/webgl-conf/checkout/conformance/more/unit.css
new file mode 100644
index 0000000000..0758b43bd9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/unit.css
@@ -0,0 +1,66 @@
+/*
+Tests for the OpenGL ES 2.0 HTML Canvas context
+
+Copyright (C) 2009 Ilmari Heikkinen <ilmari.heikkinen@gmail.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+.ok {
+ color: green;
+}
+.fail {
+ color: red;
+}
+canvas {
+ display: none;
+}
+#test-status {
+ font-size: large;
+}
+
+#test-log {
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+ background: white;
+ color: black;
+}
+#test-log > div {
+ padding-bottom: 0.5em;
+}
+#test-log h2 {
+ font-size: 1em;
+ margin-bottom: 0em;
+ padding-top: 0.5em;
+}
+#test-log h3 {
+ font-size: small;
+ margin-left: 1.5em;
+ margin-bottom: 0em;
+ margin-top: 0.5em;
+}
+#test-log p {
+ margin-left: 4em;
+ font-size: small;
+ margin-top: 0em;
+ margin-bottom: 0.2em;
+}
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/unit.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/unit.js
new file mode 100644
index 0000000000..3ca21c4cae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/unit.js
@@ -0,0 +1,970 @@
+/*
+Unit testing library for the OpenGL ES 2.0 HTML Canvas context
+*/
+
+/*
+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.
+*/
+
+/* -- plaform specific code -- */
+
+// WebKit
+if (window.testRunner && !window.layoutTestController) {
+ window.layoutTestController = window.testRunner;
+}
+
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+
+ // The WebKit testing system compares console output.
+ // Because the output of the WebGL Tests is GPU dependent
+ // we turn off console messages.
+ window.console.log = function() { };
+ window.console.error = function() { };
+
+ // RAF doesn't work in LayoutTests. Disable it so the tests will
+ // use setTimeout instead.
+ window.requestAnimationFrame = undefined;
+ window.webkitRequestAnimationFrame = undefined;
+}
+
+if (window.internals) {
+ window.internals.settings.setWebGLErrorsToConsoleEnabled(false);
+}
+
+/* -- end platform specific code --*/
+Tests = {
+ autorun : true,
+ message : null,
+ delay : 0,
+ autoinit: true,
+
+ startUnit : function(){ return []; },
+ setup : function() { return arguments; },
+ teardown : function() {},
+ endUnit : function() {}
+}
+
+var __testSuccess__ = true;
+var __testFailCount__ = 0;
+var __testLog__;
+var __backlog__ = [];
+
+var getUrlOptions = (function() {
+ var _urlOptionsParsed = false;
+ var _urlOptions = {};
+ return function() {
+ if (!_urlOptionsParsed) {
+ var s = window.location.href;
+ var q = s.indexOf("?");
+ var e = s.indexOf("#");
+ if (e < 0) {
+ e = s.length;
+ }
+ var query = s.substring(q + 1, e);
+ var pairs = query.split("&");
+ for (var ii = 0; ii < pairs.length; ++ii) {
+ var keyValue = pairs[ii].split("=");
+ var key = keyValue[0];
+ var value = decodeURIComponent(keyValue[1]);
+ _urlOptions[key] = value;
+ }
+ _urlOptionsParsed = true;
+ }
+
+ return _urlOptions;
+ }
+})();
+
+if (typeof quietMode == 'undefined') {
+ var quietMode = (function() {
+ var _quietModeChecked = false;
+ var _isQuiet = false;
+ return function() {
+ if (!_quietModeChecked) {
+ _isQuiet = (getUrlOptions().quiet == 1);
+ _quietModeChecked = true;
+ }
+ return _isQuiet;
+ }
+ })();
+}
+
+Object.toSource = function(a, seen){
+ if (a == null) return "null";
+ if (typeof a == 'boolean') return a ? "true" : "false";
+ if (typeof a == 'string') return '"' + a.replace(/"/g, '\\"') + '"';
+ if (a instanceof HTMLElement) return a.toString();
+ if (a.width && a.height && a.data) return "[ImageData]";
+ if (a instanceof Array) {
+ if (!seen) seen = [];
+ var idx = seen.indexOf(a);
+ if (idx != -1) return '#'+(idx+1)+'#';
+ seen.unshift(a);
+ var srcs = a.map(function(o){ return Object.toSource(o,seen) });
+ var prefix = '';
+ idx = seen.indexOf(a);
+ if (idx != -1) prefix = '#'+(idx+1)+'=';
+ return prefix + '[' + srcs.join(", ") + ']';
+ }
+ if (typeof a == 'object') {
+ if (!seen) seen = [];
+ var idx = seen.indexOf(a);
+ if (idx != -1) return '#'+(idx+1)+'#';
+ seen.unshift(a);
+ var members = [];
+ var name;
+ try {
+ for (var i in a) {
+ if (i.search(/^[a-zA-Z0-9]+$/) != -1)
+ name = i;
+ else
+ name = '"' + i.replace(/"/g, '\\"') + '"';
+ var ai;
+ try { ai = a[i]; }
+ catch(e) { ai = 'null /*ERROR_ACCESSING*/'; }
+ var s = name + ':' + Object.toSource(ai, seen);
+ members.push(s);
+ }
+ } catch (e) {}
+ var prefix = '';
+ idx = seen.indexOf(a);
+ if (idx != -1) prefix = '#'+(idx+1)+'=';
+ return prefix + '{' + members.join(", ") + '}'
+ }
+ if (typeof a == 'function')
+ return '('+a.toString().replace(/\n/g, " ").replace(/\s+/g, " ")+')';
+ return a.toString();
+}
+
+function formatError(e) {
+ if (window.console) console.log(e);
+ var pathSegs = location.href.toString().split("/");
+ var currentDoc = e.lineNumber != null ? pathSegs[pathSegs.length - 1] : null;
+ var trace = (e.filename || currentDoc) + ":" + e.lineNumber + (e.trace ? "\n"+e.trace : "");
+ return e.message + "\n" + trace;
+}
+
+function runTests() {
+ var h = document.getElementById('test-status');
+ if (h == null) {
+ h = document.createElement('h1');
+ h.id = 'test-status';
+ document.body.appendChild(h);
+ }
+ h.textContent = "";
+ var log = document.getElementById('test-log');
+ if (log == null) {
+ log = document.createElement('div');
+ log.id = 'test-log';
+ document.body.appendChild(log);
+ }
+ while (log.childNodes.length > 0)
+ log.removeChild(log.firstChild);
+
+ var setup_args = [];
+
+ if (Tests.startUnit != null) {
+ __testLog__ = document.createElement('div');
+ try {
+ setup_args = Tests.startUnit();
+ if (__testLog__.childNodes.length > 0)
+ log.appendChild(__testLog__);
+ } catch(e) {
+ testFailed("startUnit", formatError(e));
+ log.appendChild(__testLog__);
+ printTestStatus();
+ return;
+ }
+ }
+
+ var testsRun = false;
+ var allTestsSuccessful = true;
+
+ for (var i in Tests) {
+ if (i.substring(0,4) != "test") continue;
+ __testLog__ = document.createElement('div');
+ __testSuccess__ = true;
+ try {
+ doTestNotify (i);
+ var args = setup_args;
+ if (Tests.setup != null)
+ args = Tests.setup.apply(Tests, setup_args);
+ Tests[i].apply(Tests, args);
+ if (Tests.teardown != null)
+ Tests.teardown.apply(Tests, args);
+ }
+ catch (e) {
+ testFailed(i, e.name, formatError(e));
+ }
+ if (__testSuccess__ == false) {
+ ++__testFailCount__;
+ }
+ var h = document.createElement('h2');
+ h.textContent = i;
+ __testLog__.insertBefore(h, __testLog__.firstChild);
+ log.appendChild(__testLog__);
+ allTestsSuccessful = allTestsSuccessful && __testSuccess__ == true;
+ reportTestResultsToHarness(__testSuccess__, i);
+ doTestNotify (i+"--"+(__testSuccess__?"OK":"FAIL"));
+ testsRun = true;
+ }
+
+ printTestStatus(testsRun);
+ if (Tests.endUnit != null) {
+ __testLog__ = document.createElement('div');
+ try {
+ Tests.endUnit.apply(Tests, setup_args);
+ if (__testLog__.childNodes.length > 0)
+ log.appendChild(__testLog__);
+ } catch(e) {
+ testFailed("endUnit", e.name, formatError(e));
+ log.appendChild(__testLog__);
+ }
+ }
+ notifyFinishedToHarness(allTestsSuccessful, "finished tests");
+}
+
+function doTestNotify(name) {
+ //try {
+ // var xhr = new XMLHttpRequest();
+ // xhr.open("GET", "http://localhost:8888/"+name, true);
+ // xhr.send(null);
+ //} catch(e) {}
+}
+
+function testFailed(assertName, name) {
+ var d = document.createElement('div');
+ var h = document.createElement('h3');
+ var d1 = document.createElement("span");
+ h.appendChild(d1);
+ d1.appendChild(document.createTextNode("FAIL: "));
+ d1.style.color = "red";
+ h.appendChild(document.createTextNode(
+ name==null ? assertName : name + " (in " + assertName + ")"));
+ d.appendChild(h);
+ var args = []
+ for (var i=2; i<arguments.length; i++) {
+ var a = arguments[i];
+ var p = document.createElement('p');
+ p.style.whiteSpace = 'pre';
+ p.textContent = (a == null) ? "null" :
+ (typeof a == 'boolean' || typeof a == 'string') ? a : Object.toSource(a);
+ args.push(p.textContent);
+ d.appendChild(p);
+ }
+ __testLog__.appendChild(d);
+ __testSuccess__ = false;
+ doTestNotify([assertName, name].concat(args).join("--"));
+}
+
+function testPassed(assertName, name) {
+ if (!quietMode()) {
+ var d = document.createElement('div');
+ var h = document.createElement('h3');
+ var d1 = document.createElement("span");
+ h.appendChild(d1);
+ d1.appendChild(document.createTextNode("PASS: "));
+ d1.style.color = "green";
+ h.appendChild(document.createTextNode(
+ name==null ? assertName : name + " (in " + assertName + ")"));
+ d.appendChild(h);
+ var args = []
+ for (var i=2; i<arguments.length; i++) {
+ var a = arguments[i];
+ var p = document.createElement('p');
+ p.style.whiteSpace = 'pre';
+ p.textContent = (a == null) ? "null" :
+ (typeof a == 'boolean' || typeof a == 'string') ? a : Object.toSource(a);
+ args.push(p.textContent);
+ d.appendChild(p);
+ }
+ __testLog__.appendChild(d);
+ }
+ doTestNotify([assertName, name].concat(args).join("--"));
+}
+
+function checkTestSuccess() {
+ return __testFailCount__ == 0;
+}
+
+window.addEventListener('load', function(){
+ for (var i=0; i<__backlog__.length; i++)
+ log(__backlog__[i]);
+}, false);
+
+function log(msg) {
+ var p = document.createElement('p');
+ var a = [];
+ for (var i=0; i<arguments.length; i++)
+ a.push(arguments[i]);
+ p.textContent = a.join(", ");
+ if (!__testLog__) {
+ if (document.body)
+ document.body.appendChild(p);
+ else
+ __backlog__.push(msg);
+ } else {
+ __testLog__.appendChild(p);
+ }
+}
+
+function printTestStatus(testsRun) {
+ var status = document.getElementById('test-status');
+ if (testsRun) {
+ status.className = checkTestSuccess() ? 'ok' : 'fail';
+ status.textContent = checkTestSuccess() ? "PASS" : "FAIL";
+ } else {
+ status.className = 'fail';
+ status.textContent = "NO TESTS FOUND";
+ }
+}
+
+function assertFail(name, f) {
+ if (f == null) { f = name; name = null; }
+ var r = false;
+ try { f(); } catch(e) { r=true; }
+ if (!r) {
+ testFailed("assertFail", name, f);
+ return false;
+ } else {
+ testPassed("assertFail", name, f);
+ return true;
+ }
+}
+
+function assertOk(name, f) {
+ if (f == null) { f = name; name = null; }
+ var r = false;
+ var err;
+ try { f(); r=true; } catch(e) { err = e; }
+ if (!r) {
+ testFailed("assertOk", name, f, err.toString());
+ return false;
+ } else {
+ testPassed("assertOk", name, f);
+ return true;
+ }
+}
+
+function assert(name, v) {
+ if (v == null) { v = name; name = null; }
+ if (!v) {
+ testFailed("assert", name, v);
+ return false;
+ } else {
+ testPassed("assert", name, v);
+ return true;
+ }
+}
+
+function assertProperty(name, v, p) {
+ if (p == null) { p = v; v = name; name = p; }
+ if (v[p] == null) {
+ testFailed("assertProperty", name);
+ return false;
+ } else {
+ testPassed("assertProperty", name);
+ return true;
+ }
+}
+
+function compare(a,b) {
+ if (typeof a == 'number' && typeof b == 'number') {
+ return a == b;
+ } else {
+ return Object.toSource(a) == Object.toSource(b);
+ }
+}
+
+function assertEquals(name, v, p) {
+ if (p == null) { p = v; v = name; name = null; }
+ if (!compare(v, p)) {
+ testFailed("assertEquals", name, v, p);
+ return false;
+ } else {
+ testPassed("assertEquals", name, v, p);
+ return true;
+ }
+}
+
+function assertArrayEquals(name, v, p) {
+ if (p == null) { p = v; v = name; name = null; }
+ if (!v) {
+ testFailed("assertArrayEquals: first array undefined", name, v, p);
+ return false;
+ }
+ if (!p) {
+ testFailed("assertArrayEquals: second array undefined", name, v, p);
+ return false;
+ }
+ if (v.length != p.length) {
+ testFailed("assertArrayEquals", name, v, p);
+ return false;
+ }
+ for (var ii = 0; ii < v.length; ++ii) {
+ if (v[ii] != p[ii]) {
+ testFailed("assertArrayEquals", name, v, p);
+ return false;
+ }
+ }
+ testPassed("assertArrayEquals", name, v, p);
+ return true;
+}
+
+function assertArrayEqualsWithEpsilon(name, v, p, l) {
+ if (l == null) { l = p; p = v; v = name; name = null; }
+ if (!v) {
+ testFailed("assertArrayEqualsWithEpsilon: first array undefined", name, v, p);
+ return false;
+ }
+ if (!p) {
+ testFailed("assertArrayEqualsWithEpsilon: second array undefined", name, v, p);
+ return false;
+ }
+ if (!l) {
+ testFailed("assertArrayEqualsWithEpsilon: limit array undefined", name, v, p);
+ return false;
+ }
+ if (v.length != p.length) {
+ testFailed("assertArrayEqualsWithEpsilon", name, v, p, l);
+ return false;
+ }
+ if (v.length != l.length) {
+ testFailed("assertArrayEqualsWithEpsilon", name, v, p, l);
+ return false;
+ }
+ for (var ii = 0; ii < v.length; ++ii) {
+ if (Math.abs(v[ii]- p[ii])>l[ii]) {
+ testFailed("assertArrayEqualsWithEpsilon", name, v, p, l);
+ return false;
+ }
+ }
+ testPassed("assertArrayEqualsWithEpsilon", name, v, p, l);
+ return true;
+}
+
+function assertNotEquals(name, v, p) {
+ if (p == null) { p = v; v = name; name = null; }
+ if (compare(v, p)) {
+ testFailed("assertNotEquals", name, v, p)
+ return false;
+ } else {
+ testPassed("assertNotEquals", name, v, p)
+ return true;
+ }
+}
+
+function time(elementId, f) {
+ var s = document.getElementById(elementId);
+ var t0 = new Date().getTime();
+ f();
+ var t1 = new Date().getTime();
+ s.textContent = 'Elapsed: '+(t1-t0)+' ms';
+}
+
+function randomFloat () {
+ // note that in fuzz-testing, this can used as the size of a buffer to allocate.
+ // so it shouldn't return astronomic values. The maximum value 10000000 is already quite big.
+ var fac = 1.0;
+ var r = Math.random();
+ if (r < 0.25)
+ fac = 10;
+ else if (r < 0.4)
+ fac = 100;
+ else if (r < 0.5)
+ fac = 1000;
+ else if (r < 0.6)
+ fac = 100000;
+ else if (r < 0.7)
+ fac = 10000000;
+ else if (r < 0.8)
+ fac = NaN;
+ return -0.5*fac + Math.random() * fac;
+}
+function randomFloatFromRange(lo, hi) {
+ var r = Math.random();
+ if (r < 0.05)
+ return lo;
+ else if (r > 0.95)
+ return hi;
+ else
+ return lo + Math.random()*(hi-lo);
+}
+function randomInt (sz) {
+ if (sz != null)
+ return Math.floor(Math.random()*sz);
+ else
+ return Math.floor(randomFloat());
+}
+function randomIntFromRange(lo, hi) {
+ return Math.floor(randomFloatFromRange(lo, hi));
+}
+function randomLength () {
+ var l = Math.floor(Math.random() * 256);
+ if (Math.random < 0.5) l = l / 10;
+ if (Math.random < 0.3) l = l / 10;
+ return l;
+}
+function randomSmallIntArray () {
+ var l = randomLength();
+ var s = new Array(l);
+ for (var i=0; i<l; i++)
+ s[i] = Math.floor(Math.random() * 256)-1;
+ return s;
+}
+function randomFloatArray () {
+ var l = randomLength();
+ var s = new Array(l);
+ for (var i=0; i<l; i++)
+ s[i] = randomFloat();
+ return s;
+}
+function randomIntArray () {
+ var l = randomLength();
+ var s = new Array(l);
+ for (var i=0; i<l; i++)
+ s[i] = randomFloat();
+ return s;
+}
+function randomMixedArray () {
+ var l = randomLength();
+ var s = new Array(l);
+ for (var i=0; i<l; i++)
+ s[i] = randomNonArray();
+ return s;
+}
+function randomArray () {
+ var r = Math.random();
+ if (r < 0.3)
+ return randomFloatArray();
+ else if (r < 0.6)
+ return randomIntArray();
+ else if (r < 0.8)
+ return randomSmallIntArray();
+ else
+ return randomMixedArray();
+}
+function randomString () {
+ return String.fromCharCode.apply(String, randomSmallIntArray());
+}
+function randomGLConstant () {
+ return GLConstants[Math.floor(Math.random() * GLConstants.length)];
+}
+
+function randomNonArray() {
+ var r = Math.random();
+ if (r < 0.25) {
+ return randomFloat();
+ } else if (r < 0.6) {
+ return randomInt();
+ } else if (r < 0.7) {
+ return (r < 0.65);
+ } else if (r < 0.87) {
+ return randomString();
+ } else if (r < 0.98) {
+ return randomGLConstant();
+ } else {
+ return null;
+ }
+}
+
+function generateRandomArg(pos, count) {
+ if (pos == 0 && Math.random() < 0.5)
+ return randomGLConstant();
+ if (pos == count-1 && Math.random() < 0.25)
+ if (Math.random() < 0.5)
+ return randomString();
+ else
+ return randomArray();
+ var r = Math.random();
+ if (r < 0.25) {
+ return randomFloat();
+ } else if (r < 0.6) {
+ return randomInt();
+ } else if (r < 0.7) {
+ return (r < 0.65);
+ } else if (r < 0.77) {
+ return randomString();
+ } else if (r < 0.84) {
+ return randomArray();
+ } else if (r < 0.98) {
+ return randomGLConstant();
+ } else {
+ return null;
+ }
+}
+
+
+function generateRandomArgs(count) {
+ var arr = new Array(count);
+ for (var i=0; i<count; i++)
+ arr[i] = generateRandomArg(i, count);
+ return arr;
+}
+
+// qc (arg1gen, arg2gen, ..., predicate)
+// qc (randomString, randomInt, randomInt, function(s,i,j){ s.substring(i,j) })
+function qc() {
+}
+
+GLConstants = [
+1,
+0x00000100,
+0x00000400,
+0x00004000,
+0x0000,
+0x0001,
+0x0002,
+0x0003,
+0x0004,
+0x0005,
+0x0006,
+0,
+1,
+0x0300,
+0x0301,
+0x0302,
+0x0303,
+0x0304,
+0x0305,
+0x0306,
+0x0307,
+0x0308,
+0x8006,
+0x8009,
+0x8009,
+0x883D,
+0x800A,
+0x800B,
+0x80C8,
+0x80C9,
+0x80CA,
+0x80CB,
+0x8001,
+0x8002,
+0x8003,
+0x8004,
+0x8005,
+0x8892,
+0x8893,
+0x8894,
+0x8895,
+0x88E0,
+0x88E4,
+0x88E8,
+0x8764,
+0x8765,
+0x8626,
+0x0404,
+0x0405,
+0x0408,
+0x0DE1,
+0x0B44,
+0x0BE2,
+0x0BD0,
+0x0B90,
+0x0B71,
+0x0C11,
+0x8037,
+0x809E,
+0x80A0,
+0,
+0x0500,
+0x0501,
+0x0502,
+0x0505,
+0x0900,
+0x0901,
+0x0B21,
+0x846D,
+0x846E,
+0x0B45,
+0x0B46,
+0x0B70,
+0x0B72,
+0x0B73,
+0x0B74,
+0x0B91,
+0x0B92,
+0x0B94,
+0x0B95,
+0x0B96,
+0x0B97,
+0x0B93,
+0x0B98,
+0x8800,
+0x8801,
+0x8802,
+0x8803,
+0x8CA3,
+0x8CA4,
+0x8CA5,
+0x0BA2,
+0x0C10,
+0x0C22,
+0x0C23,
+0x0CF5,
+0x0D05,
+0x0D33,
+0x0D3A,
+0x0D50,
+0x0D52,
+0x0D53,
+0x0D54,
+0x0D55,
+0x0D56,
+0x0D57,
+0x2A00,
+0x8038,
+0x8069,
+0x80A8,
+0x80A9,
+0x80AA,
+0x80AB,
+0x86A2,
+0x86A3,
+0x1100,
+0x1101,
+0x1102,
+0x8192,
+0x1400,
+0x1401,
+0x1402,
+0x1403,
+0x1404,
+0x1405,
+0x1406,
+0x140C,
+0x1902,
+0x1906,
+0x1907,
+0x1908,
+0x1909,
+0x190A,
+0x8033,
+0x8034,
+0x8363,
+0x8B30,
+0x8B31,
+0x8869,
+0x8DFB,
+0x8DFC,
+0x8B4D,
+0x8B4C,
+0x8872,
+0x8DFD,
+0x8B4F,
+0x8B80,
+0x8B82,
+0x8B83,
+0x8B85,
+0x8B86,
+0x8B87,
+0x8B89,
+0x8B8A,
+0x8B8C,
+0x8B8D,
+0x0200,
+0x0201,
+0x0202,
+0x0203,
+0x0204,
+0x0205,
+0x0206,
+0x0207,
+0x1E00,
+0x1E01,
+0x1E02,
+0x1E03,
+0x150A,
+0x8507,
+0x8508,
+0x1F00,
+0x1F01,
+0x1F02,
+0x1F03,
+0x2600,
+0x2601,
+0x2700,
+0x2701,
+0x2702,
+0x2703,
+0x2800,
+0x2801,
+0x2802,
+0x2803,
+0x1702,
+0x8513,
+0x8514,
+0x8515,
+0x8516,
+0x8517,
+0x8518,
+0x8519,
+0x851A,
+0x851C,
+0x84C0,
+0x84C1,
+0x84C2,
+0x84C3,
+0x84C4,
+0x84C5,
+0x84C6,
+0x84C7,
+0x84C8,
+0x84C9,
+0x84CA,
+0x84CB,
+0x84CC,
+0x84CD,
+0x84CE,
+0x84CF,
+0x84D0,
+0x84D1,
+0x84D2,
+0x84D3,
+0x84D4,
+0x84D5,
+0x84D6,
+0x84D7,
+0x84D8,
+0x84D9,
+0x84DA,
+0x84DB,
+0x84DC,
+0x84DD,
+0x84DE,
+0x84DF,
+0x84E0,
+0x2901,
+0x812F,
+0x8370,
+0x8B50,
+0x8B51,
+0x8B52,
+0x8B53,
+0x8B54,
+0x8B55,
+0x8B56,
+0x8B57,
+0x8B58,
+0x8B59,
+0x8B5A,
+0x8B5B,
+0x8B5C,
+0x8B5E,
+0x8B60,
+0x8622,
+0x8623,
+0x8624,
+0x8625,
+0x886A,
+0x8645,
+0x889F,
+0x8B9A,
+0x8B9B,
+0x8B81,
+0x8B84,
+0x8B88,
+0x8DFA,
+0x8DF8,
+0x8DF9,
+0x8DF0,
+0x8DF1,
+0x8DF2,
+0x8DF3,
+0x8DF4,
+0x8DF5,
+0x8D40,
+0x8D41,
+0x8056,
+0x8057,
+0x8D62,
+0x81A5,
+0x1901,
+0x8D48,
+0x8D42,
+0x8D43,
+0x8D44,
+0x8D50,
+0x8D51,
+0x8D52,
+0x8D53,
+0x8D54,
+0x8D55,
+0x8CD0,
+0x8CD1,
+0x8CD2,
+0x8CD3,
+0x8CE0,
+0x8D00,
+0x8D20,
+0,
+0x8CD5,
+0x8CD6,
+0x8CD7,
+0x8CD9,
+0x8CDD,
+0x8CA6,
+0x8CA7,
+0x84E8,
+0x0506,
+0x809D
+];
+
+function reportTestResultsToHarness(success, msg) {
+ if (window.parent.webglTestHarness) {
+ window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg);
+ }
+}
+
+function notifyFinishedToHarness() {
+ if (window.parent.webglTestHarness) {
+ window.parent.webglTestHarness.notifyFinished(window.location.pathname);
+ }
+}
+
+function initTests() {
+ if (Tests.message != null) {
+ var h = document.getElementById('test-message');
+ if (h == null) {
+ h = document.createElement('p');
+ h.id = 'test-message';
+ document.body.insertBefore(h, document.body.firstChild);
+ }
+ h.textContent = Tests.message;
+ }
+ if (Tests.autorun) {
+ runTests();
+ } else {
+ var h = document.getElementById('test-run');
+ if (h == null) {
+ h = document.createElement('input');
+ h.type = 'submit';
+ h.value = "Run tests";
+ h.addEventListener('click', function(ev){
+ runTests();
+ ev.preventDefault();
+ }, false);
+ h.id = 'test-run';
+ document.body.insertBefore(h, document.body.firstChild);
+ }
+ h.textContent = Tests.message;
+ }
+
+}
+
+window.addEventListener('load', function(){
+ if (Tests.autoinit) {
+ // let the browser hopefully finish updating the gl canvas surfaces if we are given a delay
+ if (Tests.delay)
+ setTimeout(initTests, Tests.delay);
+ else
+ initTests()
+ }
+}, false);
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/more/util.js b/dom/canvas/test/webgl-conf/checkout/conformance/more/util.js
new file mode 100644
index 0000000000..78cc08a652
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/more/util.js
@@ -0,0 +1,1287 @@
+/*
+Utilities for the OpenGL ES 2.0 HTML Canvas context
+*/
+
+/*
+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.
+*/
+
+function loadTexture(gl, elem, mipmaps) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elem);
+ if (mipmaps != false)
+ gl.generateMipmap(gl.TEXTURE_2D);
+ 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);
+ if (mipmaps)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ else
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ return tex;
+}
+
+function getShader(gl, id) {
+ var shaderScript = document.getElementById(id);
+ if (!shaderScript) {
+ throw(new Error("No shader element with id: "+id));
+ }
+
+ var str = "";
+ var k = shaderScript.firstChild;
+ while (k) {
+ if (k.nodeType == 3)
+ str += k.textContent;
+ k = k.nextSibling;
+ }
+
+ var shader;
+ if (shaderScript.type == "x-shader/x-fragment") {
+ shader = gl.createShader(gl.FRAGMENT_SHADER);
+ } else if (shaderScript.type == "x-shader/x-vertex") {
+ shader = gl.createShader(gl.VERTEX_SHADER);
+ } else {
+ throw(new Error("Unknown shader type "+shaderScript.type));
+ }
+
+ gl.shaderSource(shader, str);
+ gl.compileShader(shader);
+
+ if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) != 1) {
+ var ilog = gl.getShaderInfoLog(shader);
+ gl.deleteShader(shader);
+ throw(new Error("Failed to compile shader "+shaderScript.id + ", Shader info log: " + ilog));
+ }
+ return shader;
+}
+
+function loadShaderArray(gl, shaders) {
+ var id = gl.createProgram();
+ var shaderObjs = [];
+ for (var i=0; i<shaders.length; ++i) {
+ try {
+ var sh = getShader(gl, shaders[i]);
+ shaderObjs.push(sh);
+ gl.attachShader(id, sh);
+ } catch (e) {
+ var pr = {program: id, shaders: shaderObjs};
+ deleteShader(gl, pr);
+ throw (e);
+ }
+ }
+ var prog = {program: id, shaders: shaderObjs};
+ gl.linkProgram(id);
+ gl.validateProgram(id);
+ if (gl.getProgramParameter(id, gl.LINK_STATUS) != 1) {
+ deleteShader(gl,prog);
+ throw(new Error("Failed to link shader"));
+ }
+ if (gl.getProgramParameter(id, gl.VALIDATE_STATUS) != 1) {
+ deleteShader(gl,prog);
+ throw(new Error("Failed to validate shader"));
+ }
+ return prog;
+}
+function loadShader(gl) {
+ var sh = [];
+ for (var i=1; i<arguments.length; ++i)
+ sh.push(arguments[i]);
+ return loadShaderArray(gl, sh);
+}
+
+function deleteShader(gl, sh) {
+ gl.useProgram(null);
+ sh.shaders.forEach(function(s){
+ gl.detachShader(sh.program, s);
+ gl.deleteShader(s);
+ });
+ gl.deleteProgram(sh.program);
+}
+
+function getGLErrorAsString(ctx, err) {
+ if (err === ctx.NO_ERROR) {
+ return "NO_ERROR";
+ }
+ for (var name in ctx) {
+ if (ctx[name] === err) {
+ return name;
+ }
+ }
+ return err.toString();
+}
+
+function checkError(gl, msg) {
+ var e = gl.getError();
+ if (e != gl.NO_ERROR) {
+ log("Error " + getGLErrorAsString(gl, e) + " at " + msg);
+ }
+ return e;
+}
+
+function throwError(gl, msg) {
+ var e = gl.getError();
+ if (e != 0) {
+ throw(new Error("Error " + getGLErrorAsString(gl, e) + " at " + msg));
+ }
+}
+
+Math.cot = function(z) { return 1.0 / Math.tan(z); }
+
+/*
+ Matrix utilities, using the OpenGL element order where
+ the last 4 elements are the translation column.
+
+ Uses flat arrays as matrices for performance.
+
+ Most operations have in-place variants to avoid allocating temporary matrices.
+
+ Naming logic:
+ Matrix.method operates on a 4x4 Matrix and returns a new Matrix.
+ Matrix.method3x3 operates on a 3x3 Matrix and returns a new Matrix. Not all operations have a 3x3 version (as 3x3 is usually only used for the normal matrix: Matrix.transpose3x3(Matrix.inverseTo3x3(mat4x4)))
+ Matrix.method[3x3]InPlace(args, target) stores its result in the target matrix.
+
+ Matrix.scale([sx, sy, sz]) -- non-uniform scale by vector
+ Matrix.scale1(s) -- uniform scale by scalar
+ Matrix.scale3(sx, sy, sz) -- non-uniform scale by scalars
+
+ Ditto for translate.
+*/
+Matrix = {
+ identity : [
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+ ],
+
+ newIdentity : function() {
+ return [
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+ ];
+ },
+
+ newIdentity3x3 : function() {
+ return [
+ 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0
+ ];
+ },
+
+ copyMatrix : function(src, dst) {
+ for (var i=0; i<16; i++) dst[i] = src[i];
+ return dst;
+ },
+
+ to3x3 : function(m) {
+ return [
+ m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10]
+ ];
+ },
+
+ // orthonormal matrix inverse
+ inverseON : function(m) {
+ var n = this.transpose4x4(m);
+ var t = [m[12], m[13], m[14]];
+ n[3] = n[7] = n[11] = 0;
+ n[12] = -Vec3.dot([n[0], n[4], n[8]], t);
+ n[13] = -Vec3.dot([n[1], n[5], n[9]], t);
+ n[14] = -Vec3.dot([n[2], n[6], n[10]], t);
+ return n;
+ },
+
+ inverseTo3x3 : function(m) {
+ return this.inverse4x4to3x3InPlace(m, this.newIdentity3x3());
+ },
+
+ inverseTo3x3InPlace : function(m,n) {
+ var a11 = m[10]*m[5]-m[6]*m[9],
+ a21 = -m[10]*m[1]+m[2]*m[9],
+ a31 = m[6]*m[1]-m[2]*m[5],
+ a12 = -m[10]*m[4]+m[6]*m[8],
+ a22 = m[10]*m[0]-m[2]*m[8],
+ a32 = -m[6]*m[0]+m[2]*m[4],
+ a13 = m[9]*m[4]-m[5]*m[8],
+ a23 = -m[9]*m[0]+m[1]*m[8],
+ a33 = m[5]*m[0]-m[1]*m[4];
+ var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
+ if (det == 0) // no inverse
+ return [1,0,0,0,1,0,0,0,1];
+ var idet = 1 / det;
+ n[0] = idet*a11;
+ n[1] = idet*a21;
+ n[2] = idet*a31;
+ n[3] = idet*a12;
+ n[4] = idet*a22;
+ n[5] = idet*a32;
+ n[6] = idet*a13;
+ n[7] = idet*a23;
+ n[8] = idet*a33;
+ return n;
+ },
+
+ inverse3x3 : function(m) {
+ return this.inverse3x3InPlace(m, this.newIdentity3x3());
+ },
+
+ inverse3x3InPlace : function(m,n) {
+ var a11 = m[8]*m[4]-m[5]*m[7],
+ a21 = -m[8]*m[1]+m[2]*m[7],
+ a31 = m[5]*m[1]-m[2]*m[4],
+ a12 = -m[8]*m[3]+m[5]*m[6],
+ a22 = m[8]*m[0]-m[2]*m[6],
+ a32 = -m[5]*m[0]+m[2]*m[3],
+ a13 = m[7]*m[4]-m[4]*m[8],
+ a23 = -m[7]*m[0]+m[1]*m[6],
+ a33 = m[4]*m[0]-m[1]*m[3];
+ var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
+ if (det == 0) // no inverse
+ return [1,0,0,0,1,0,0,0,1];
+ var idet = 1 / det;
+ n[0] = idet*a11;
+ n[1] = idet*a21;
+ n[2] = idet*a31;
+ n[3] = idet*a12;
+ n[4] = idet*a22;
+ n[5] = idet*a32;
+ n[6] = idet*a13;
+ n[7] = idet*a23;
+ n[8] = idet*a33;
+ return n;
+ },
+
+ frustum : function (left, right, bottom, top, znear, zfar) {
+ var X = 2*znear/(right-left);
+ var Y = 2*znear/(top-bottom);
+ var A = (right+left)/(right-left);
+ var B = (top+bottom)/(top-bottom);
+ var C = -(zfar+znear)/(zfar-znear);
+ var D = -2*zfar*znear/(zfar-znear);
+
+ return [
+ X, 0, 0, 0,
+ 0, Y, 0, 0,
+ A, B, C, -1,
+ 0, 0, D, 0
+ ];
+ },
+
+ perspective : function (fovy, aspect, znear, zfar) {
+ var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
+ var ymin = -ymax;
+ var xmin = ymin * aspect;
+ var xmax = ymax * aspect;
+
+ return this.frustum(xmin, xmax, ymin, ymax, znear, zfar);
+ },
+
+ mul4x4 : function (a,b) {
+ return this.mul4x4InPlace(a,b,this.newIdentity());
+ },
+
+ mul4x4InPlace : function (a, b, c) {
+ c[0] = b[0] * a[0] +
+ b[0+1] * a[4] +
+ b[0+2] * a[8] +
+ b[0+3] * a[12];
+ c[0+1] = b[0] * a[1] +
+ b[0+1] * a[5] +
+ b[0+2] * a[9] +
+ b[0+3] * a[13];
+ c[0+2] = b[0] * a[2] +
+ b[0+1] * a[6] +
+ b[0+2] * a[10] +
+ b[0+3] * a[14];
+ c[0+3] = b[0] * a[3] +
+ b[0+1] * a[7] +
+ b[0+2] * a[11] +
+ b[0+3] * a[15];
+ c[4] = b[4] * a[0] +
+ b[4+1] * a[4] +
+ b[4+2] * a[8] +
+ b[4+3] * a[12];
+ c[4+1] = b[4] * a[1] +
+ b[4+1] * a[5] +
+ b[4+2] * a[9] +
+ b[4+3] * a[13];
+ c[4+2] = b[4] * a[2] +
+ b[4+1] * a[6] +
+ b[4+2] * a[10] +
+ b[4+3] * a[14];
+ c[4+3] = b[4] * a[3] +
+ b[4+1] * a[7] +
+ b[4+2] * a[11] +
+ b[4+3] * a[15];
+ c[8] = b[8] * a[0] +
+ b[8+1] * a[4] +
+ b[8+2] * a[8] +
+ b[8+3] * a[12];
+ c[8+1] = b[8] * a[1] +
+ b[8+1] * a[5] +
+ b[8+2] * a[9] +
+ b[8+3] * a[13];
+ c[8+2] = b[8] * a[2] +
+ b[8+1] * a[6] +
+ b[8+2] * a[10] +
+ b[8+3] * a[14];
+ c[8+3] = b[8] * a[3] +
+ b[8+1] * a[7] +
+ b[8+2] * a[11] +
+ b[8+3] * a[15];
+ c[12] = b[12] * a[0] +
+ b[12+1] * a[4] +
+ b[12+2] * a[8] +
+ b[12+3] * a[12];
+ c[12+1] = b[12] * a[1] +
+ b[12+1] * a[5] +
+ b[12+2] * a[9] +
+ b[12+3] * a[13];
+ c[12+2] = b[12] * a[2] +
+ b[12+1] * a[6] +
+ b[12+2] * a[10] +
+ b[12+3] * a[14];
+ c[12+3] = b[12] * a[3] +
+ b[12+1] * a[7] +
+ b[12+2] * a[11] +
+ b[12+3] * a[15];
+ return c;
+ },
+
+ mulv4 : function (a, v) {
+ c = new Array(4);
+ for (var i=0; i<4; ++i) {
+ var x = 0;
+ for (var k=0; k<4; ++k)
+ x += v[k] * a[k*4+i];
+ c[i] = x;
+ }
+ return c;
+ },
+
+ rotate : function (angle, axis) {
+ axis = Vec3.normalize(axis);
+ var x=axis[0], y=axis[1], z=axis[2];
+ var c = Math.cos(angle);
+ var c1 = 1-c;
+ var s = Math.sin(angle);
+ return [
+ x*x*c1+c, y*x*c1+z*s, z*x*c1-y*s, 0,
+ x*y*c1-z*s, y*y*c1+c, y*z*c1+x*s, 0,
+ x*z*c1+y*s, y*z*c1-x*s, z*z*c1+c, 0,
+ 0,0,0,1
+ ];
+ },
+ rotateInPlace : function(angle, axis, m) {
+ axis = Vec3.normalize(axis);
+ var x=axis[0], y=axis[1], z=axis[2];
+ var c = Math.cos(angle);
+ var c1 = 1-c;
+ var s = Math.sin(angle);
+ var tmpMatrix = this.tmpMatrix;
+ var tmpMatrix2 = this.tmpMatrix2;
+ tmpMatrix[0] = x*x*c1+c; tmpMatrix[1] = y*x*c1+z*s; tmpMatrix[2] = z*x*c1-y*s; tmpMatrix[3] = 0;
+ tmpMatrix[4] = x*y*c1-z*s; tmpMatrix[5] = y*y*c1+c; tmpMatrix[6] = y*z*c1+x*s; tmpMatrix[7] = 0;
+ tmpMatrix[8] = x*z*c1+y*s; tmpMatrix[9] = y*z*c1-x*s; tmpMatrix[10] = z*z*c1+c; tmpMatrix[11] = 0;
+ tmpMatrix[12] = 0; tmpMatrix[13] = 0; tmpMatrix[14] = 0; tmpMatrix[15] = 1;
+ this.copyMatrix(m, tmpMatrix2);
+ return this.mul4x4InPlace(tmpMatrix2, tmpMatrix, m);
+ },
+
+ scale : function(v) {
+ return [
+ v[0], 0, 0, 0,
+ 0, v[1], 0, 0,
+ 0, 0, v[2], 0,
+ 0, 0, 0, 1
+ ];
+ },
+ scale3 : function(x,y,z) {
+ return [
+ x, 0, 0, 0,
+ 0, y, 0, 0,
+ 0, 0, z, 0,
+ 0, 0, 0, 1
+ ];
+ },
+ scale1 : function(s) {
+ return [
+ s, 0, 0, 0,
+ 0, s, 0, 0,
+ 0, 0, s, 0,
+ 0, 0, 0, 1
+ ];
+ },
+ scale3InPlace : function(x, y, z, m) {
+ var tmpMatrix = this.tmpMatrix;
+ var tmpMatrix2 = this.tmpMatrix2;
+ tmpMatrix[0] = x; tmpMatrix[1] = 0; tmpMatrix[2] = 0; tmpMatrix[3] = 0;
+ tmpMatrix[4] = 0; tmpMatrix[5] = y; tmpMatrix[6] = 0; tmpMatrix[7] = 0;
+ tmpMatrix[8] = 0; tmpMatrix[9] = 0; tmpMatrix[10] = z; tmpMatrix[11] = 0;
+ tmpMatrix[12] = 0; tmpMatrix[13] = 0; tmpMatrix[14] = 0; tmpMatrix[15] = 1;
+ this.copyMatrix(m, tmpMatrix2);
+ return this.mul4x4InPlace(tmpMatrix2, tmpMatrix, m);
+ },
+ scale1InPlace : function(s, m) { return this.scale3InPlace(s, s, s, m); },
+ scaleInPlace : function(s, m) { return this.scale3InPlace(s[0],s[1],s[2],m); },
+
+ translate3 : function(x,y,z) {
+ return [
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ x, y, z, 1
+ ];
+ },
+
+ translate : function(v) {
+ return this.translate3(v[0], v[1], v[2]);
+ },
+ tmpMatrix : [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0],
+ tmpMatrix2 : [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0],
+ translate3InPlace : function(x,y,z,m) {
+ var tmpMatrix = this.tmpMatrix;
+ var tmpMatrix2 = this.tmpMatrix2;
+ tmpMatrix[0] = 1; tmpMatrix[1] = 0; tmpMatrix[2] = 0; tmpMatrix[3] = 0;
+ tmpMatrix[4] = 0; tmpMatrix[5] = 1; tmpMatrix[6] = 0; tmpMatrix[7] = 0;
+ tmpMatrix[8] = 0; tmpMatrix[9] = 0; tmpMatrix[10] = 1; tmpMatrix[11] = 0;
+ tmpMatrix[12] = x; tmpMatrix[13] = y; tmpMatrix[14] = z; tmpMatrix[15] = 1;
+ this.copyMatrix(m, tmpMatrix2);
+ return this.mul4x4InPlace(tmpMatrix2, tmpMatrix, m);
+ },
+ translateInPlace : function(v,m){ return this.translate3InPlace(v[0], v[1], v[2], m); },
+
+ lookAt : function (eye, center, up) {
+ var z = Vec3.direction(eye, center);
+ var x = Vec3.normalizeInPlace(Vec3.cross(up, z));
+ var y = Vec3.normalizeInPlace(Vec3.cross(z, x));
+
+ var m = [
+ x[0], y[0], z[0], 0,
+ x[1], y[1], z[1], 0,
+ x[2], y[2], z[2], 0,
+ 0, 0, 0, 1
+ ];
+
+ var t = [
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ -eye[0], -eye[1], -eye[2], 1
+ ];
+
+ return this.mul4x4(m,t);
+ },
+
+ transpose4x4 : function(m) {
+ return [
+ m[0], m[4], m[8], m[12],
+ m[1], m[5], m[9], m[13],
+ m[2], m[6], m[10], m[14],
+ m[3], m[7], m[11], m[15]
+ ];
+ },
+
+ transpose4x4InPlace : function(m) {
+ var tmp = 0.0;
+ tmp = m[1]; m[1] = m[4]; m[4] = tmp;
+ tmp = m[2]; m[2] = m[8]; m[8] = tmp;
+ tmp = m[3]; m[3] = m[12]; m[12] = tmp;
+ tmp = m[6]; m[6] = m[9]; m[9] = tmp;
+ tmp = m[7]; m[7] = m[13]; m[13] = tmp;
+ tmp = m[11]; m[11] = m[14]; m[14] = tmp;
+ return m;
+ },
+
+ transpose3x3 : function(m) {
+ return [
+ m[0], m[3], m[6],
+ m[1], m[4], m[7],
+ m[2], m[5], m[8]
+ ];
+ },
+
+ transpose3x3InPlace : function(m) {
+ var tmp = 0.0;
+ tmp = m[1]; m[1] = m[3]; m[3] = tmp;
+ tmp = m[2]; m[2] = m[6]; m[6] = tmp;
+ tmp = m[5]; m[5] = m[7]; m[7] = tmp;
+ return m;
+ },
+}
+
+Vec3 = {
+ make : function() { return [0,0,0]; },
+ copy : function(v) { return [v[0],v[1],v[2]]; },
+
+ add : function (u,v) {
+ return [u[0]+v[0], u[1]+v[1], u[2]+v[2]];
+ },
+
+ sub : function (u,v) {
+ return [u[0]-v[0], u[1]-v[1], u[2]-v[2]];
+ },
+
+ negate : function (u) {
+ return [-u[0], -u[1], -u[2]];
+ },
+
+ direction : function (u,v) {
+ return this.normalizeInPlace(this.sub(u,v));
+ },
+
+ normalizeInPlace : function(v) {
+ var imag = 1.0 / Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+ v[0] *= imag; v[1] *= imag; v[2] *= imag;
+ return v;
+ },
+
+ normalize : function(v) {
+ return this.normalizeInPlace(this.copy(v));
+ },
+
+ scale : function(f, v) {
+ return [f*v[0], f*v[1], f*v[2]];
+ },
+
+ dot : function(u,v) {
+ return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
+ },
+
+ inner : function(u,v) {
+ return [u[0]*v[0], u[1]*v[1], u[2]*v[2]];
+ },
+
+ cross : function(u,v) {
+ return [
+ u[1]*v[2] - u[2]*v[1],
+ u[2]*v[0] - u[0]*v[2],
+ u[0]*v[1] - u[1]*v[0]
+ ];
+ }
+}
+
+Shader = function(gl){
+ this.gl = gl;
+ this.shaders = [];
+ this.uniformLocations = {};
+ this.attribLocations = {};
+ for (var i=1; i<arguments.length; i++) {
+ this.shaders.push(arguments[i]);
+ }
+}
+Shader.prototype = {
+ id : null,
+ gl : null,
+ compiled : false,
+ shader : null,
+ shaders : [],
+
+ destroy : function() {
+ if (this.shader != null) deleteShader(this.gl, this.shader);
+ },
+
+ compile : function() {
+ this.shader = loadShaderArray(this.gl, this.shaders);
+ },
+
+ use : function() {
+ if (this.shader == null)
+ this.compile();
+ this.gl.useProgram(this.shader.program);
+ },
+
+ uniform1fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform1fv(loc, value);
+ },
+
+ uniform2fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform2fv(loc, value);
+ },
+
+ uniform3fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform3fv(loc, value);
+ },
+
+ uniform4fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform4fv(loc, value);
+ },
+
+ uniform1f : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform1f(loc, value);
+ },
+
+ uniform2f : function(name, v1,v2) {
+ var loc = this.uniform(name);
+ this.gl.uniform2f(loc, v1,v2);
+ },
+
+ uniform3f : function(name, v1,v2,v3) {
+ var loc = this.uniform(name);
+ this.gl.uniform3f(loc, v1,v2,v3);
+ },
+
+ uniform4f : function(name, v1,v2,v3,v4) {
+ var loc = this.uniform(name);
+ this.gl.uniform4f(loc, v1, v2, v3, v4);
+ },
+
+ uniform1iv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform1iv(loc, value);
+ },
+
+ uniform2iv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform2iv(loc, value);
+ },
+
+ uniform3iv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform3iv(loc, value);
+ },
+
+ uniform4iv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform4iv(loc, value);
+ },
+
+ uniform1i : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniform1i(loc, value);
+ },
+
+ uniform2i : function(name, v1,v2) {
+ var loc = this.uniform(name);
+ this.gl.uniform2i(loc, v1,v2);
+ },
+
+ uniform3i : function(name, v1,v2,v3) {
+ var loc = this.uniform(name);
+ this.gl.uniform3i(loc, v1,v2,v3);
+ },
+
+ uniform4i : function(name, v1,v2,v3,v4) {
+ var loc = this.uniform(name);
+ this.gl.uniform4i(loc, v1, v2, v3, v4);
+ },
+
+ uniformMatrix4fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniformMatrix4fv(loc, false, value);
+ },
+
+ uniformMatrix3fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniformMatrix3fv(loc, false, value);
+ },
+
+ uniformMatrix2fv : function(name, value) {
+ var loc = this.uniform(name);
+ this.gl.uniformMatrix2fv(loc, false, value);
+ },
+
+ attrib : function(name) {
+ if (this.attribLocations[name] == null) {
+ var loc = this.gl.getAttribLocation(this.shader.program, name);
+ this.attribLocations[name] = loc;
+ }
+ return this.attribLocations[name];
+ },
+
+ uniform : function(name) {
+ if (this.uniformLocations[name] == null) {
+ var loc = this.gl.getUniformLocation(this.shader.program, name);
+ this.uniformLocations[name] = loc;
+ }
+ return this.uniformLocations[name];
+ }
+}
+Filter = function(gl, shader) {
+ Shader.apply(this, arguments);
+}
+Filter.prototype = new Shader();
+Filter.prototype.apply = function(init) {
+ this.use();
+ var va = this.attrib("Vertex");
+ var ta = this.attrib("Tex");
+ var vbo = Quad.getCachedVBO(this.gl);
+ if (init) init(this);
+ vbo.draw(va, null, ta);
+}
+
+
+VBO = function(gl) {
+ this.gl = gl;
+ this.data = [];
+ this.elementsVBO = null;
+ for (var i=1; i<arguments.length; i++) {
+ if (arguments[i].elements)
+ this.elements = arguments[i];
+ else
+ this.data.push(arguments[i]);
+ }
+}
+
+VBO.prototype = {
+ initialized : false,
+ length : 0,
+ vbos : null,
+ type : 'TRIANGLES',
+ elementsVBO : null,
+ elements : null,
+
+ setData : function() {
+ this.destroy();
+ this.data = [];
+ for (var i=0; i<arguments.length; i++) {
+ if (arguments[i].elements)
+ this.elements = arguments[i];
+ else
+ this.data.push(arguments[i]);
+ }
+ },
+
+ destroy : function() {
+ if (this.vbos != null)
+ for (var i=0; i<this.vbos.length; i++)
+ this.gl.deleteBuffer(this.vbos[i]);
+ if (this.elementsVBO != null)
+ this.gl.deleteBuffer(this.elementsVBO);
+ this.length = this.elementsLength = 0;
+ this.vbos = this.elementsVBO = null;
+ this.initialized = false;
+ },
+
+ init : function() {
+ this.destroy();
+ var gl = this.gl;
+
+ gl.getError();
+ var vbos = [];
+ var length = 0;
+ for (var i=0; i<this.data.length; i++)
+ vbos.push(gl.createBuffer());
+ if (this.elements != null)
+ this.elementsVBO = gl.createBuffer();
+ try {
+ throwError(gl, "genBuffers");
+ for (var i = 0; i<this.data.length; i++) {
+ var d = this.data[i];
+ var dlen = Math.floor(d.data.length / d.size);
+ if (i == 0 || dlen < length)
+ length = dlen;
+ if (!d.floatArray)
+ d.floatArray = new Float32Array(d.data);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbos[i]);
+ throwError(gl, "bindBuffer");
+ gl.bufferData(gl.ARRAY_BUFFER, d.floatArray, gl.STATIC_DRAW);
+ throwError(gl, "bufferData");
+ }
+ if (this.elementsVBO != null) {
+ var d = this.elements;
+ this.elementsLength = d.data.length;
+ this.elementsType = d.type == gl.UNSIGNED_BYTE ? d.type : gl.UNSIGNED_SHORT;
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementsVBO);
+ throwError(gl, "bindBuffer ELEMENT_ARRAY_BUFFER");
+ if (this.elementsType == gl.UNSIGNED_SHORT && !d.ushortArray) {
+ d.ushortArray = new Uint16Array(d.data);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, d.ushortArray, gl.STATIC_DRAW);
+ } else if (this.elementsType == gl.UNSIGNED_BYTE && !d.ubyteArray) {
+ d.ubyteArray = new Uint8Array(d.data);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, d.ubyteArray, gl.STATIC_DRAW);
+ }
+ throwError(gl, "bufferData ELEMENT_ARRAY_BUFFER");
+ }
+ } catch(e) {
+ for (var i=0; i<vbos.length; i++)
+ gl.deleteBuffer(vbos[i]);
+ throw(e);
+ }
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+
+ this.length = length;
+ this.vbos = vbos;
+
+ this.initialized = true;
+ },
+
+ use : function() {
+ if (!this.initialized) this.init();
+ var gl = this.gl;
+ for (var i=0; i<arguments.length; i++) {
+ if (arguments[i] == null || arguments[i] == -1) continue;
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vbos[i]);
+ gl.vertexAttribPointer(arguments[i], this.data[i].size, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(arguments[i]);
+ }
+ if (this.elementsVBO != null) {
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementsVBO);
+ }
+ },
+
+ draw : function() {
+ var args = [];
+ this.use.apply(this, arguments);
+ var gl = this.gl;
+ if (this.elementsVBO != null) {
+ gl.drawElements(gl[this.type], this.elementsLength, this.elementsType, 0);
+ } else {
+ gl.drawArrays(gl[this.type], 0, this.length);
+ }
+ }
+}
+
+FBO = function(gl, width, height, use_depth) {
+ this.gl = gl;
+ this.width = width;
+ this.height = height;
+ if (use_depth != null)
+ this.useDepth = use_depth;
+}
+FBO.prototype = {
+ initialized : false,
+ useDepth : true,
+ fbo : null,
+ rbo : null,
+ texture : null,
+
+ destroy : function() {
+ if (this.fbo) this.gl.deleteFramebuffer(this.fbo);
+ if (this.rbo) this.gl.deleteRenderbuffer(this.rbo);
+ if (this.texture) this.gl.deleteTexture(this.texture);
+ },
+
+ init : function() {
+ var gl = this.gl;
+ var w = this.width, h = this.height;
+ var fbo = this.fbo != null ? this.fbo : gl.createFramebuffer();
+ var rb;
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ checkError(gl, "FBO.init bindFramebuffer");
+ if (this.useDepth) {
+ rb = this.rbo != null ? this.rbo : gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ checkError(gl, "FBO.init bindRenderbuffer");
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ checkError(gl, "FBO.init renderbufferStorage");
+ }
+
+ var tex = this.texture != null ? this.texture : gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ try {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } catch (e) { // argh, no null texture support
+ var tmp = this.getTempCanvas(w,h);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tmp);
+ }
+ 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);
+ checkError(gl, "FBO.init tex");
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ checkError(gl, "FBO.init bind tex");
+
+ if (this.useDepth) {
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
+ checkError(gl, "FBO.init bind depth buffer");
+ }
+
+ var fbstat = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (fbstat != gl.FRAMEBUFFER_COMPLETE) {
+ var glv;
+ for (var v in gl) {
+ try { glv = gl[v]; } catch (e) { glv = null; }
+ if (glv == fbstat) { fbstat = v; break; }}
+ log("Framebuffer status: " + fbstat);
+ }
+ checkError(gl, "FBO.init check fbo");
+
+ this.fbo = fbo;
+ this.rbo = rb;
+ this.texture = tex;
+ this.initialized = true;
+ },
+
+ getTempCanvas : function(w, h) {
+ if (!FBO.tempCanvas) {
+ FBO.tempCanvas = document.createElement('canvas');
+ }
+ FBO.tempCanvas.width = w;
+ FBO.tempCanvas.height = h;
+ return FBO.tempCanvas;
+ },
+
+ use : function() {
+ if (!this.initialized) this.init();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fbo);
+ }
+}
+
+function GLError(err, msg, fileName, lineNumber) {
+ this.message = msg;
+ this.glError = err;
+}
+
+GLError.prototype = new Error();
+
+function makeGLErrorWrapper(gl, fname) {
+ return (function() {
+ try {
+ var rv = gl[fname].apply(gl, arguments);
+ var err = gl.getError();
+ if (err != gl.NO_ERROR) {
+ throw(new GLError(
+ err, "GL error "+getGLErrorAsString(gl, err)+" in "+fname));
+ }
+ return rv;
+ } catch (e) {
+ if (e.glError !== undefined) {
+ throw e;
+ }
+ throw(new Error("Threw " + e.name +
+ " in " + fname + "\n" +
+ e.message + "\n" +
+ arguments.callee.caller));
+ }
+ });
+}
+
+function wrapGLContext(gl) {
+ var wrap = {};
+ for (var i in gl) {
+ try {
+ if (typeof gl[i] == 'function') {
+ wrap[i] = makeGLErrorWrapper(gl, i);
+ } else {
+ wrap[i] = gl[i];
+ }
+ } catch (e) {
+ // log("wrapGLContext: Error accessing " + i);
+ }
+ }
+ wrap.getError = function(){ return gl.getError(); };
+ return wrap;
+}
+
+function getGLContext(canvas) {
+ return canvas.getContext(GL_CONTEXT_ID, {antialias: false});
+}
+
+// Assert that f generates a specific GL error.
+function assertGLError(gl, err, name, f) {
+ if (f == null) { f = name; name = null; }
+ var r = false;
+ var glErr = 0;
+ try { f(); } catch(e) { r=true; glErr = e.glError; }
+ if (glErr !== err) {
+ if (glErr === undefined) {
+ testFailed("assertGLError: UNEXPECTED EXCEPTION", name, f);
+ } else {
+ testFailed("assertGLError: expected: " + getGLErrorAsString(gl, err) +
+ " actual: " + getGLErrorAsString(gl, glErr), name, f);
+ }
+ return false;
+ }
+ return true;
+}
+
+// Assert that f generates a GL error from a list.
+function assertGLErrorIn(gl, expectedErrorList, name, f) {
+ if (f == null) { f = name; name = null; }
+
+ var actualError = 0;
+ try {
+ f();
+ } catch(e) {
+ if ('glError' in e) {
+ actualError = e.glError;
+ } else {
+ testFailed("assertGLError: UNEXPCETED EXCEPTION", name, f);
+ return false;
+ }
+ }
+
+ var expectedErrorStrList = [];
+ var expectedErrorSet = {};
+ for (var i in expectedErrorList) {
+ var cur = expectedErrorList[i];
+ expectedErrorSet[cur] = true;
+ expectedErrorStrList.push(getGLErrorAsString(gl, cur));
+ }
+ var expectedErrorListStr = "[" + expectedErrorStrList.join(", ") + "]";
+
+ if (actualError in expectedErrorSet) {
+ return true;
+ }
+
+ testFailed("assertGLError: expected: " + expectedErrorListStr +
+ " actual: " + getGLErrorAsString(gl, actualError), name, f);
+ return false;
+}
+
+// Assert that f generates some GL error. Used in situations where it's
+// ambigious which of multiple possible errors will be generated.
+function assertSomeGLError(gl, name, f) {
+ if (f == null) { f = name; name = null; }
+ var r = false;
+ var glErr = 0;
+ var err = 0;
+ try { f(); } catch(e) { r=true; glErr = e.glError; }
+ if (glErr === 0) {
+ if (glErr === undefined) {
+ testFailed("assertGLError: UNEXPECTED EXCEPTION", name, f);
+ } else {
+ testFailed("assertGLError: expected: " + getGLErrorAsString(gl, err) +
+ " actual: " + getGLErrorAsString(gl, glErr), name, f);
+ }
+ return false;
+ }
+ return true;
+}
+
+// Assert that f throws an exception but does not generate a GL error.
+function assertThrowNoGLError(gl, name, f) {
+ if (f == null) { f = name; name = null; }
+ var r = false;
+ var glErr = undefined;
+ var exp;
+ try { f(); } catch(e) { r=true; glErr = e.glError; exp = e;}
+ if (!r) {
+ testFailed(
+ "assertThrowNoGLError: should have thrown exception", name, f);
+ return false;
+ } else {
+ if (glErr !== undefined) {
+ testFailed(
+ "assertThrowNoGLError: should be no GL error but generated: " +
+ getGLErrorAsString(gl, glErr), name, f);
+ return false;
+ }
+ }
+ testPassed("assertThrowNoGLError", name, f);
+ return true;
+}
+
+function assertThrows(gl, shouldThrow, info, func) {
+ var didThrow = false;
+ try {
+ func();
+ } catch (e) {
+ var didGLError = (e instanceof GLError);
+ if (!didGLError) {
+ didThrow = true;
+ }
+ }
+
+ var text = shouldThrow ? "Should throw: "
+ : "Should not throw: ";
+ var func = (didThrow == shouldThrow) ? testPassed : testFailed;
+
+ func(text + info);
+}
+
+Quad = {
+ vertices : [
+ -1,-1,0,
+ 1,-1,0,
+ -1,1,0,
+ 1,-1,0,
+ 1,1,0,
+ -1,1,0
+ ],
+ normals : [
+ 0,0,-1,
+ 0,0,-1,
+ 0,0,-1,
+ 0,0,-1,
+ 0,0,-1,
+ 0,0,-1
+ ],
+ texcoords : [
+ 0,0,
+ 1,0,
+ 0,1,
+ 1,0,
+ 1,1,
+ 0,1
+ ],
+ indices : [0,1,2,1,5,2],
+ makeVBO : function(gl) {
+ return new VBO(gl,
+ {size:3, data: Quad.vertices},
+ {size:3, data: Quad.normals},
+ {size:2, data: Quad.texcoords}
+ )
+ },
+ cache: {},
+ getCachedVBO : function(gl) {
+ if (!this.cache[gl])
+ this.cache[gl] = this.makeVBO(gl);
+ return this.cache[gl];
+ }
+}
+Cube = {
+ vertices : [ 0.5, -0.5, 0.5, // +X
+ 0.5, -0.5, -0.5,
+ 0.5, 0.5, -0.5,
+ 0.5, 0.5, 0.5,
+
+ 0.5, 0.5, 0.5, // +Y
+ 0.5, 0.5, -0.5,
+ -0.5, 0.5, -0.5,
+ -0.5, 0.5, 0.5,
+
+ 0.5, 0.5, 0.5, // +Z
+ -0.5, 0.5, 0.5,
+ -0.5, -0.5, 0.5,
+ 0.5, -0.5, 0.5,
+
+ -0.5, -0.5, 0.5, // -X
+ -0.5, 0.5, 0.5,
+ -0.5, 0.5, -0.5,
+ -0.5, -0.5, -0.5,
+
+ -0.5, -0.5, 0.5, // -Y
+ -0.5, -0.5, -0.5,
+ 0.5, -0.5, -0.5,
+ 0.5, -0.5, 0.5,
+
+ -0.5, -0.5, -0.5, // -Z
+ -0.5, 0.5, -0.5,
+ 0.5, 0.5, -0.5,
+ 0.5, -0.5, -0.5,
+ ],
+
+ normals : [ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1,
+
+ -1, 0, 0,
+ -1, 0, 0,
+ -1, 0, 0,
+ -1, 0, 0,
+
+ 0,-1, 0,
+ 0,-1, 0,
+ 0,-1, 0,
+ 0,-1, 0,
+
+ 0, 0,-1,
+ 0, 0,-1,
+ 0, 0,-1,
+ 0, 0,-1
+ ],
+
+ indices : [],
+ create : function(){
+ for (var i = 0; i < 6; i++) {
+ Cube.indices.push(i*4 + 0);
+ Cube.indices.push(i*4 + 1);
+ Cube.indices.push(i*4 + 3);
+ Cube.indices.push(i*4 + 1);
+ Cube.indices.push(i*4 + 2);
+ Cube.indices.push(i*4 + 3);
+ }
+ },
+
+ makeVBO : function(gl) {
+ return new VBO(gl,
+ {size:3, data: Cube.vertices},
+ {size:3, data: Cube.normals},
+ {elements: true, data: Cube.indices}
+ )
+ },
+ cache : {},
+ getCachedVBO : function(gl) {
+ if (!this.cache[gl])
+ this.cache[gl] = this.makeVBO(gl);
+ return this.cache[gl];
+ }
+}
+Cube.create();
+
+Sphere = {
+ vertices : [],
+ normals : [],
+ indices : [],
+ create : function(){
+ var r = 0.75;
+ function vert(theta, phi)
+ {
+ var r = 0.75;
+ var x, y, z, nx, ny, nz;
+
+ nx = Math.sin(theta) * Math.cos(phi);
+ ny = Math.sin(phi);
+ nz = Math.cos(theta) * Math.cos(phi);
+ Sphere.normals.push(nx);
+ Sphere.normals.push(ny);
+ Sphere.normals.push(nz);
+
+ x = r * Math.sin(theta) * Math.cos(phi);
+ y = r * Math.sin(phi);
+ z = r * Math.cos(theta) * Math.cos(phi);
+ Sphere.vertices.push(x);
+ Sphere.vertices.push(y);
+ Sphere.vertices.push(z);
+ }
+ for (var phi = -Math.PI/2; phi < Math.PI/2; phi += Math.PI/20) {
+ var phi2 = phi + Math.PI/20;
+ for (var theta = -Math.PI/2; theta <= Math.PI/2; theta += Math.PI/20) {
+ vert(theta, phi);
+ vert(theta, phi2);
+ }
+ }
+ }
+}
+
+Sphere.create();
+
+initGL_CONTEXT_ID = function(){
+ var c = document.createElement('canvas');
+ var contextNames = ['webgl', 'experimental-webgl'];
+ GL_CONTEXT_ID = null;
+ for (var i=0; i<contextNames.length; i++) {
+ try {
+ if (c.getContext(contextNames[i])) {
+ GL_CONTEXT_ID = contextNames[i];
+ break;
+ }
+ } catch (e) {
+ }
+ }
+ if (!GL_CONTEXT_ID) {
+ log("No WebGL context found. Unable to run tests.");
+ }
+}
+
+initGL_CONTEXT_ID();