summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/misc
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/misc')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html176
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html285
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html57
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html44
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html61
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html114
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html583
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html320
9 files changed, 1648 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt
new file mode 100644
index 0000000000..8f1343f91d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt
@@ -0,0 +1,8 @@
+--min-version 2.0.1 blend-integer.html
+expando-loss-2.html
+getextension-while-pbo-bound-stability.html
+instanceof-test.html
+--min-version 2.0.1 null-object-behaviour-2.html
+object-deletion-behaviour-2.html
+uninitialized-test-2.html
+views-with-offsets.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html
new file mode 100644
index 0000000000..40ccfd0d86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html
@@ -0,0 +1,176 @@
+<!--
+Copyright (c) 2021 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Blend Integer Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css" />
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="outputVertexShader" type="x-shader/x-vertex">
+#version 300 es
+in vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+<script id="outputFragmentShaderSigned" type="x-shader/x-fragment">
+#version 300 es
+layout(location = 1) out highp vec4 o_drawBuffer1;
+layout(location = 2) out highp ivec4 o_drawBuffer2;
+layout(location = 3) out highp vec4 o_drawBuffer3;
+void main(void)
+{
+ o_drawBuffer1 = vec4(0, 0, 0, 0);
+ o_drawBuffer2 = ivec4(0, 0, 0, 0);
+ o_drawBuffer3 = vec4(0, 0, 0, 0);
+}
+</script>
+<script id="outputFragmentShaderUnsigned" type="x-shader/x-fragment">
+ #version 300 es
+ layout(location = 1) out highp vec4 o_drawBuffer1;
+ layout(location = 2) out highp uvec4 o_drawBuffer2;
+ layout(location = 3) out highp vec4 o_drawBuffer3;
+ void main(void)
+ {
+ o_drawBuffer1 = vec4(0, 0, 0, 0);
+ o_drawBuffer2 = uvec4(0, 0, 0, 0);
+ o_drawBuffer3 = vec4(0, 0, 0, 0);
+ }
+ </script>
+
+<script>
+"use strict";
+description("This test verifies correct behavior of min/max blending operations on integer attachments.");
+
+debug("");
+
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext(null, undefined, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("")
+ debug("GL_MIN");
+ runTest(false, gl.MIN);
+ runTest(true, gl.MIN);
+
+ debug("")
+ debug("GL_MAX");
+ runTest(false, gl.MAX);
+ runTest(true, gl.MAX);
+}
+
+function compareValue(value, attachment, isSigned) {
+ const pixel = isSigned ? new Int32Array(4) : new Uint32Array(4);
+ gl.readBuffer(attachment);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, isSigned ? gl.INT : gl.UNSIGNED_INT, pixel);
+ let pass = true;
+ for (let i = 0; i < 4; i++) {
+ if (value[i] != pixel[i]) {
+ testFailed(`Read value of channel ${i} should be ${pixel[i]}, was ${value[i]}.`);
+ pass = false;
+ }
+ }
+ return pass;
+}
+
+function runTest(isSigned, operation) {
+ gl.viewport(0, 0, 1, 1);
+ gl.disable(gl.BLEND);
+
+ const program = wtu.setupProgram(gl,
+ ["outputVertexShader",
+ isSigned ? "outputFragmentShaderSigned" : "outputFragmentShaderUnsigned"],
+ ['vPosition'], [0]);
+ const quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+
+ // Setup render targets
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ const rb1 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1);
+
+ const rb2 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb2);
+ gl.renderbufferStorage(gl.RENDERBUFFER, isSigned ? gl.RGBA32I : gl.RGBA32UI, 50, 50);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.RENDERBUFFER, rb2);
+
+ const rb3 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb3);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.RENDERBUFFER, rb3);
+
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Pipeline setup complete.");
+
+ if (isSigned) {
+ const clearValue = new Int32Array([-1, 2, -3, 4]);
+ gl.clearBufferiv(gl.COLOR, 2, clearValue);
+ if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Signed clear passed.");
+ } else {
+ testFailed("Signed clear failed.");
+ }
+ } else {
+ const clearValue = new Uint32Array([1, 2, 3, 4]);
+ gl.clearBufferuiv(gl.COLOR, 2, clearValue);
+ if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Unsigned clear passed.");
+ } else {
+ testFailed("Unsigned clear failed.");
+ }
+ }
+
+ gl.blendEquation(operation);
+ gl.enable(gl.BLEND);
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw complete.");
+
+ if (isSigned) {
+ const drawValue = new Int32Array([0, 0, 0, 0]);
+ if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Signed draw passed.");
+ } else {
+ testFailed("Signed draw failed.");
+ }
+ } else {
+ const drawValue = new Uint32Array([0, 0, 0, 0]);
+ if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Unsigned draw passed.");
+ } else {
+ testFailed("Unsigned draw failed.");
+ }
+ }
+ gl.deleteRenderbuffer(rb1);
+ gl.deleteRenderbuffer(rb2);
+ gl.deleteRenderbuffer(rb3);
+ gl.deleteFramebuffer(fb);
+ gl.deleteProgram(program);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html
new file mode 100644
index 0000000000..141a5377a8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html
@@ -0,0 +1,285 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<title>WebGL 2 Object Expandos Conformance Test</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script>
+"use strict";
+description("This test verifies that WebGL object expandos are preserved across garbage collections.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false}, 2);
+
+// Helpers that set expandos and verify they are set to the correct value.
+var expandoValue = "WebGL is awesome!"
+function setTestExpandos(instance, extra) {
+ instance.expando1 = expandoValue;
+ instance.expando2 = { subvalue : expandoValue };
+ instance.expando_extra = extra;
+}
+function verifyTestExpandos(instance, msg, extra) {
+ assertMsg(instance.expando1 === expandoValue, msg + ": Expect basic expando to survive despite GC.");
+ assertMsg(instance.expando2 && instance.expando2.subvalue === expandoValue, msg + ": Expect subobject expando to survive despite GC.");
+ assertMsg(instance.expando_extra === extra, msg + ": Expect extra expando to survive despite GC.");
+}
+
+// Tests that we don't get expando loss for bound resources where the
+// only remaining reference is internal to WebGL
+function testBasicBindings() {
+ debug('Basic Bindings');
+
+ // Test data that describes how to create, bind, and retrieve an object off of the context
+ var glProt = Object.getPrototypeOf(gl);
+ var simpleData = [
+ {
+ typeName: 'WebGLSampler',
+ creationFn: glProt.createSampler,
+ bindFn: glProt.bindSampler,
+ bindConstant: 0,
+ retrieveConstant: glProt.SAMPLER_BINDING,
+ name: "SAMPLER_BINDING",
+ },
+ {
+ typeName: 'WebGLTransformFeedback',
+ creationFn: glProt.createTransformFeedback,
+ bindFn: glProt.bindTransformFeedback,
+ bindConstant: glProt.TRANSFORM_FEEDBACK,
+ retrieveConstant: glProt.TRANSFORM_FEEDBACK_BINDING,
+ name: "TRANSFORM_FEEDBACK_BINDING",
+ },
+ {
+ typeName: 'WebGLVertexArrayObject',
+ creationFn: glProt.createVertexArray,
+ bindFn: glProt.bindVertexArray,
+ bindConstant: null,
+ retrieveConstant: glProt.VERTEX_ARRAY_BINDING,
+ name: "VERTEX_ARRAY_BINDING",
+ },
+ {
+ typeName: 'WebGLTexture',
+ creationFn: glProt.createTexture,
+ bindFn: glProt.bindTexture,
+ bindConstant: glProt.TEXTURE_3D,
+ retrieveConstant: glProt.TEXTURE_BINDING_3D,
+ name: "TEXTURE_BINDING_3D",
+ },
+ {
+ typeName: 'WebGLTexture',
+ creationFn: glProt.createTexture,
+ bindFn: glProt.bindTexture,
+ bindConstant: glProt.TEXTURE_2D_ARRAY,
+ retrieveConstant: glProt.TEXTURE_BINDING_2D_ARRAY,
+ name: "TEXTURE_BINDING_2D_ARRAY",
+ },
+ {
+ typeName: 'WebGLFramebuffer',
+ creationFn: glProt.createFramebuffer,
+ bindFn: glProt.bindFramebuffer,
+ bindConstant: glProt.READ_FRAMEBUFFER,
+ retrieveConstant: glProt.READ_FRAMEBUFFER_BINDING,
+ name: "READ_FRAMEBUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLFramebuffer',
+ creationFn: glProt.createFramebuffer,
+ bindFn: glProt.bindFramebuffer,
+ bindConstant: glProt.DRAW_FRAMEBUFFER,
+ retrieveConstant: glProt.DRAW_FRAMEBUFFER_BINDING,
+ name: "DRAW_FRAMEBUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.COPY_READ_BUFFER,
+ retrieveConstant: glProt.COPY_READ_BUFFER_BINDING,
+ name: "COPY_READ_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.COPY_WRITE_BUFFER,
+ retrieveConstant: glProt.COPY_WRITE_BUFFER_BINDING,
+ name: "COPY_WRITE_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.PIXEL_PACK_BUFFER,
+ retrieveConstant: glProt.PIXEL_PACK_BUFFER_BINDING,
+ name: "PIXEL_PACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.PIXEL_UNPACK_BUFFER,
+ retrieveConstant: glProt.PIXEL_UNPACK_BUFFER_BINDING,
+ name: "PIXEL_UNPACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.TRANSFORM_FEEDBACK_BUFFER,
+ retrieveConstant: glProt.TRANSFORM_FEEDBACK_BUFFER_BINDING,
+ name: "TRANSFORM_FEEDBACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.UNIFORM_BUFFER,
+ retrieveConstant: glProt.UNIFORM_BUFFER_BINDING,
+ name: "UNIFORM_BUFFER_BINDING",
+ },
+ ];
+
+ simpleData.forEach(function(test) {
+ var instance = test.creationFn.call(gl);
+ var msg = "getParameter(" + test.name + ")";
+ setTestExpandos(instance);
+
+ if (test.bindConstant === null) {
+ test.bindFn.call(gl, instance);
+ } else {
+ test.bindFn.call(gl, test.bindConstant, instance);
+ }
+ assertMsg(instance === gl.getParameter(test.retrieveConstant), msg + " returns instance that was bound.");
+
+ // Garbage collect Javascript references. Remaining references should be internal to WebGL.
+ instance = null;
+ webglHarnessCollectGarbage();
+
+ var retrievedObject = gl.getParameter(test.retrieveConstant);
+ verifyTestExpandos(retrievedObject, msg);
+ shouldBeType(retrievedObject, test.typeName);
+ debug('');
+ });
+}
+
+function testIndexedBindings() {
+ debug('Indexed Bindings');
+
+ // Test data that describes how to create, bind, and retrieve an indexed object off of the context
+ var glProt = Object.getPrototypeOf(gl);
+ var simpleData = [
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBufferBase,
+ indexMax: gl.getParameter(glProt.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS) - 1,
+ bindConstant: glProt.TRANSFORM_FEEDBACK_BUFFER,
+ retrieveConstant: glProt.TRANSFORM_FEEDBACK_BUFFER_BINDING,
+ name: "TRANSFORM_FEEDBACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBufferBase,
+ indexMax: gl.getParameter(glProt.MAX_UNIFORM_BUFFER_BINDINGS) - 1,
+ bindConstant: glProt.UNIFORM_BUFFER,
+ retrieveConstant: glProt.UNIFORM_BUFFER_BINDING,
+ name: "UNIFORM_BUFFER_BINDING",
+ },
+ ];
+
+ simpleData.forEach(function(test) {
+ // This test sets all of the separate indexed bindings first, then
+ // tests them all. It puts a different extra expando on each indexed
+ // parameter so that we can ensure they're all distinct.
+ var instances = [];
+ for (var i = 0; i <= test.indexMax; i++) {
+ var instance = test.creationFn.call(gl);
+ var msg = "getIndexedParameter(" + test.name + ", " + i + ")";
+ setTestExpandos(instance, i);
+ instances[i] = instance;
+ test.bindFn.call(gl, test.bindConstant, i, instance);
+ }
+
+ for (var i = 0; i <= test.indexMax; i++) {
+ var msg = "getIndexedParameter(" + test.name + ", " + i + ")";
+ assertMsg(instances[i] === gl.getIndexedParameter(test.retrieveConstant, i), msg + " returns instance that was bound.");
+ }
+
+ // Garbage collect Javascript references. Remaining references should be internal to WebGL.
+ instances = null;
+ webglHarnessCollectGarbage();
+
+ for (var i = 0; i <= test.indexMax; i++) {
+ var msg = "getIndexedParameter(" + test.name + ", " + i + ")";
+ var retrievedObject = gl.getIndexedParameter(test.retrieveConstant, i);
+ verifyTestExpandos(retrievedObject, msg, i);
+ shouldBeType(retrievedObject, test.typeName);
+ debug('');
+ }
+ });
+}
+
+function testQueries() {
+ debug('Query');
+
+ expandoValue = "First query";
+ var query1 = gl.createQuery();
+ setTestExpandos(query1);
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, query1);
+
+ expandoValue = "Second query";
+ var query2 = gl.createQuery();
+ setTestExpandos(query2);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query2);
+
+
+ assertMsg(query1 === gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY), "CURRENT_QUERY returns instance that was bound.");
+ assertMsg(query2 === gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY), "CURRENT_QUERY returns instance that was bound.");
+
+ // Garbage collect Javascript references. Remaining references should be internal to WebGL.
+ query1 = null;
+ query2 = null;
+ webglHarnessCollectGarbage();
+
+ var retrievedQuery1 = gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY);
+ var retrievedQuery2 = gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY);
+ expandoValue = "First query";
+ verifyTestExpandos(retrievedQuery1, "Query");
+ shouldBeType(retrievedQuery1, 'WebGLQuery');
+
+ expandoValue = "Second query";
+ verifyTestExpandos(retrievedQuery2, "Query");
+ shouldBeType(retrievedQuery2, 'WebGLQuery');
+
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+
+ debug('');
+}
+
+// Run tests
+testBasicBindings();
+testIndexedBindings();
+testQueries();
+
+// FYI: There's no need to test WebGLSync objects because there is no notion of an "active" sync,
+// and thus no way to query them back out of the context.
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html
new file mode 100644
index 0000000000..73e34fdc1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html
@@ -0,0 +1,57 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 getExtension while PBO bound stability conformance test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+
+function runTest(extension_name) {
+ debug("");
+ debug("getExtension('" + extension_name + "') while PIXEL_UNPACK_BUFFER bound should be stable");
+
+ var gl = wtu.create3DContext(null, undefined, 2);
+ if (!gl) {
+ testFailed("Fail to get a WebGL context");
+ return;
+ }
+
+ var pbo = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo);
+ var ext = gl.getExtension('EXT_color_buffer_float');
+ var gl_texture_float_linear = gl.getExtension(extension_name);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Late-enable of extension should succeed");
+ if (pbo != gl.getParameter(gl.PIXEL_UNPACK_BUFFER_BINDING)) {
+ testFailed("Fail to maintain PIXEL_UNPACK_BUFFER binding when enabling extension " + extension_name);
+ }
+}
+
+function runTests() {
+ debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=641643'>Chromium Issue 641642</a>");
+ runTest('EXT_color_buffer_float');
+ runTest('OES_texture_float_linear');
+}
+
+runTests();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html
new file mode 100644
index 0000000000..4ecbd6e2d3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html
@@ -0,0 +1,44 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL instanceof test.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 color;
+void main()
+{
+ gl_FragColor = color;
+}
+</script>
+
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/instanceof-test.js"></script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html
new file mode 100644
index 0000000000..1a65dc57bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html
@@ -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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description("Tests calling WebGL 2 APIs without providing the necessary objects");
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+var shouldGenerateGLError = wtu.shouldGenerateGLError;
+
+
+for (let nullOrUndefined of [null, undefined]) {
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteQuery(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isQuery(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteSync(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isSync(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteTransformFeedback(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isTransformFeedback(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteSampler(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isSampler(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteVertexArray(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isVertexArray(${nullOrUndefined})`);
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindSampler(0, ${nullOrUndefined})`);
+ shouldThrow(`gl.samplerParameteri(${nullOrUndefined}, gl.TEXTURE_MAG_FILTER, gl.NEAREST)`);
+ shouldThrow(`gl.samplerParameterf(${nullOrUndefined}, gl.TEXTURE_MAX_LOD, 1)`);
+ shouldThrow(`gl.getSamplerParameter(${nullOrUndefined}, gl.TEXTURE_MAX_LOD)`);
+
+ shouldThrow(`gl.waitSync(${nullOrUndefined}, 0, 0)`);
+ shouldThrow(`gl.clientWaitSync(${nullOrUndefined}, 0, 0)`);
+ shouldThrow(`gl.getSyncParameter(${nullOrUndefined}, gl.OBJECT_TYPE)`);
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, ${nullOrUndefined})`);
+ shouldThrow(`gl.transformFeedbackVaryings(${nullOrUndefined}, [], gl.SEPARATE_ATTRIBS)`);
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindVertexArray(${nullOrUndefined})`);
+}
+
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html
new file mode 100644
index 0000000000..0551a1bd97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html
@@ -0,0 +1,114 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Tests deletion behavior for WebGL2 buffer, sampler, vertexArray and transformFeedback objects.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+var shouldGenerateGLError = wtu.shouldGenerateGLError;
+
+debug("");
+debug("buffer deletion");
+
+var bufferBaseUniform = gl.createBuffer();
+shouldBeNonNull("bufferBaseUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, bufferBaseUniform)");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "bufferBaseUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferBaseUniform)");
+shouldBeFalse("gl.isBuffer(bufferBaseUniform)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, bufferBaseUniform)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+
+var bufferBaseTransformFeedback = gl.createBuffer();
+shouldBeNonNull("bufferBaseTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferBaseTransformFeedback)");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "bufferBaseTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferBaseTransformFeedback)");
+shouldBeFalse("gl.isBuffer(bufferBaseTransformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferBaseTransformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+
+var bufferRangeUniform = gl.createBuffer();
+shouldBeNonNull("bufferRangeUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufferRangeUniform, 0, gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT)");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "bufferRangeUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferRangeUniform)");
+shouldBeFalse("gl.isBuffer(bufferRangeUniform)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufferRangeUniform, 0, gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+
+var bufferRangeTransformFeedback = gl.createBuffer();
+shouldBeNonNull("bufferRangeTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferRangeTransformFeedback, 0, 4)");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "bufferRangeTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferRangeTransformFeedback)");
+shouldBeFalse("gl.isBuffer(bufferRangeTransformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferRangeTransformFeedback, 0, 4)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+
+debug("");
+debug("sampler deletion");
+
+var sampler = gl.createSampler();
+shouldBeNonNull("sampler");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindSampler(0, sampler)");
+shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "sampler");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteSampler(sampler)");
+shouldBeFalse("gl.isSampler(sampler)");
+shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindSampler(0, sampler)");
+shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+
+debug("");
+debug("vertexArray deletion");
+
+var vertexArray = gl.createVertexArray();
+shouldBeNonNull("vertexArray");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindVertexArray(vertexArray)");
+shouldBe("gl.getParameter(gl.VERTEX_ARRAY_BINDING)", "vertexArray");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteVertexArray(vertexArray)");
+shouldBeFalse("gl.isVertexArray(vertexArray)");
+shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindVertexArray(vertexArray)");
+shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+
+debug("");
+debug("transformFeedback deletion");
+
+var transformFeedback = gl.createTransformFeedback();
+shouldBeNonNull("transformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback)");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)", "transformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTransformFeedback(transformFeedback)");
+shouldBeFalse("gl.isTransformFeedback(transformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
new file mode 100644
index 0000000000..4befe35c93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
@@ -0,0 +1,583 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Uninitialized GL Resources Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("Tests to check user code cannot access uninitialized data from GL resources.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", undefined, 2);
+if (!gl)
+ testFailed("Context created.");
+else
+ testPassed("Context created.");
+
+// This is the maximum size that will end up being allocated with the tests
+// currently written as they are. It could need to be increased later.
+var scratchBuffer = new ArrayBuffer(1024 * 1024 * 8 * 4);
+function zeroArrayBuffer(arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ arr[i] = 0;
+ }
+}
+function getUint32Array(length) {
+ var arr = new Uint32Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getInt32Array(length) {
+ var arr = new Int32Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getUint8Array(length) {
+ var arr = new Uint8Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getInt8Array(length) {
+ var arr = new Int8Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+
+function setupTexture(target, texWidth, texHeight, texDepth) {
+ var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
+ var texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ if (is3d) {
+ gl.texImage3D(target, 0, gl.RGBA8, texWidth, texHeight, texDepth, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } else if (target == gl.TEXTURE_2D) {
+ gl.texImage2D(target, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ // this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
+ // into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
+ // with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
+
+ var badData = getUint8Array(texWidth * texHeight * texDepth * 4);
+ for (var i = 0; i < badData.length; ++i)
+ badData[i] = i % 255;
+
+ if (is3d) {
+ gl.texSubImage3D(target, 0, 0, 0, 0, texWidth, texHeight, texDepth, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ } else if (target == gl.TEXTURE_2D) {
+ gl.texSubImage2D(target, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ }
+ gl.finish(); // make sure it has been uploaded
+
+ gl.deleteTexture(texture);
+ gl.finish(); // make sure it has been deleted
+
+ var texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ return texture;
+}
+
+function checkNonZeroPixels(texture, target, format, type, texWidth, texHeight, level, layer, exceptions) {
+ var tol = 2;
+ var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
+ switch (target) {
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ break;
+ default:
+ gl.bindTexture(target, null);
+ break;
+ }
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ if (is3d) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level, layer);
+ } else {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, texture, level);
+ }
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+
+ var data;
+ switch (type) {
+ case gl.UNSIGNED_INT:
+ data = getUint32Array(texWidth * texHeight * 4);
+ break;
+ case gl.INT:
+ data = getInt32Array(texWidth * texHeight * 4);
+ break;
+ case gl.UNSIGNED_BYTE:
+ default:
+ data = getUint8Array(texWidth * texHeight * 4);
+ break;
+ }
+ gl.readPixels(0, 0, texWidth, texHeight, format, type, data);
+
+ var k = 0;
+ var failed_exceptions = 0;
+ for (var y = 0; y < texHeight; ++y) {
+ for (var x = 0; x < texWidth; ++x) {
+ var index = (y * texWidth + x) * 4;
+ var is_exception = false;
+ for (var ii = 0; ii < exceptions.length; ++ii) {
+ if (exceptions[ii].x == x && exceptions[ii].y == y) {
+ is_exception = true;
+ if (Math.abs(data[index] - exceptions[ii].r) > tol ||
+ Math.abs(data[index + 1] - exceptions[ii].g) > tol ||
+ Math.abs(data[index + 2] - exceptions[ii].b) > tol ||
+ Math.abs(data[index + 3] - exceptions[ii].a) > tol) {
+ failed_exceptions++;
+ }
+ }
+ }
+ if (is_exception)
+ continue;
+ for (var i = 0; i < 4; ++i) {
+ if (data[index + i] != 0) {
+ k++;
+ }
+ }
+ }
+ }
+ var info = "Level = " + level;
+ if (is3d)
+ info += ", layer = " + layer;
+ info += " : ";
+ if (k) {
+ testFailed(info + "found " + k + " non-zero elements");
+ } else {
+ testPassed(info + "all data initialized");
+ }
+ if (exceptions.length > 0) {
+ if (failed_exceptions) {
+ testFailed(info + "found " + failed_exceptions + " elements incorrectly overwritten");
+ } else {
+ testPassed(info + "all initialized elements stay untouched");
+ }
+ }
+}
+
+function testTexImage3D() {
+
+ var max_3d_texture_size = Math.min(gl.getParameter(gl.MAX_3D_TEXTURE_SIZE), 1024);
+
+ var test_cases = [
+ // TEXTURE_3D + RGBA8
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 0, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_3D + RGBA8UI
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 0, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 128, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_3D + RGBA8I
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 128, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 128, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 1023, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8UI
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 1023, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8I
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 512, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // If more tests are added here, make sure to increase the size of
+ // scratchBuffer above, if needed.
+ ];
+
+ for (var ii = 0; ii < test_cases.length; ++ii) {
+ debug("");
+ var test = test_cases[ii];
+ debug("TexImage3D with target = " + test.target + ", internal_format = " + test.internal_format +
+ ", width = " + test.width + ", height = " + test.height + ", depth = " + test.depth);
+ var tex = setupTexture(gl[test.target], test.width, test.height, test.depth);
+ gl.texImage3D(gl[test.target], 0, gl[test.internal_format], test.width, test.height, test.depth, 0, test.format, test.type, null);
+ for (var jj = 0; jj < test.exceptions.length; ++jj) {
+ var exception = test.exceptions[jj];
+ var data;
+ switch (test.type) {
+ case gl.BYTE:
+ data = getInt8Array(4 * test.depth);
+ break;
+ case gl.UNSIGNED_BYTE:
+ data = getUint8Array(4 * test.depth);
+ break;
+ default:
+ assert(false);
+ }
+ for (var pixel = 0; pixel < test.depth; ++pixel) {
+ data[pixel * 4] = exception.r;
+ data[pixel * 4 + 1] = exception.g;
+ data[pixel * 4 + 2] = exception.b;
+ data[pixel * 4 + 3] = exception.a;
+ }
+ gl.texSubImage3D(gl[test.target], 0, exception.x, exception.y, 0, 1, 1, test.depth, test.format, test.type, data);
+ }
+ for (var layer = 0; layer < test.depth; ++layer)
+ checkNonZeroPixels(tex, gl[test.target], test.format, test.read_type, test.width, test.height, 0, layer, test.exceptions);
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+function testTexStorage2D() {
+ var targets = [ "TEXTURE_2D", "TEXTURE_CUBE_MAP" ];
+ var width = 512;
+ var height = 512;
+ var levels = 5;
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ debug("");
+ debug("Reading an uninitialized texture (texStorage2D) should succeed with all bytes set to 0 : target = " + targets[ii]);
+ var tex = setupTexture(gl[targets[ii]], width, height, 1);
+ gl.texStorage2D(gl[targets[ii]], levels, gl.RGBA8, width, height);
+ for (var level = 0; level < levels; ++level) {
+ if (gl[targets[ii]] == gl.TEXTURE_2D) {
+ checkNonZeroPixels(tex, gl[targets[ii]], gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ } else {
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ }
+ }
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+function testTexStorage3D() {
+ var targets = [ "TEXTURE_3D", "TEXTURE_2D_ARRAY" ];
+ var internal_formats = [ "RGBA8", "RGBA8UI", "RGBA8I" ];
+ var formats = [ gl.RGBA, gl.RGBA_INTEGER, gl.RGBA_INTEGER ];
+ var read_types = [ gl.UNSIGNED_BYTE, gl.UNSIGNED_INT, gl.INT ];
+ var width = 256; // minimum MAX_3D_TEXTURE_SIZE is 256
+ var height = 256; // minimum MAX_3D_TEXTURE_SIZE is 256
+ var depth = 8;
+ var levels = 5;
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ debug("");
+ debug("Reading an uninitialized texture (texStorage3D) should succeed with all bytes set to 0 : target = " + targets[ii]);
+ for (var jj = 0; jj < internal_formats.length; ++jj) {
+ debug("");
+ debug("Internal format : " + internal_formats[jj]);
+ var tex = setupTexture(gl[targets[ii]], width, height, depth);
+ gl.texStorage3D(gl[targets[ii]], levels, gl[internal_formats[jj]], width, height, depth);
+ var level_depth = depth;
+ for (var level = 0; level < levels; ++level) {
+ for (var layer = 0; layer < level_depth; ++layer) {
+ checkNonZeroPixels(tex, gl[targets[ii]], formats[jj], read_types[jj], width, height, level, layer, []);
+ }
+ if (gl[targets[ii]] == gl.TEXTURE_3D)
+ level_depth = Math.max(1, level_depth >> 1);
+ }
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+ }
+}
+
+testTexImage3D();
+testTexStorage2D();
+testTexStorage3D();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html
new file mode 100644
index 0000000000..8e89b4b78a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html
@@ -0,0 +1,320 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Tests texture uploads with ArrayBufferView+offsets");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(null, undefined, 2);
+console.log(gl.getParameter(gl.VERSION));
+
+////
+
+function arrToStr(arr) {
+ return "[" + arr.map(x => x.toString()).join(", ") + "]";
+}
+
+function shouldBeWas(shouldBe, was, info) {
+ var text = "Should be " + shouldBe + ", was " + was + ".";
+ if (info) {
+ text = info + ": " + text;
+ }
+
+ if (shouldBe == was) {
+ testPassed(text);
+ return true;
+ } else {
+ testFailed(text);
+ return false;
+ }
+}
+
+function shouldBeWasArr(shouldBe, was, info) {
+ if (shouldBe.length != was.length) {
+ testFailed("Length should be " + shouldBe.length + ", was " + was.length + ".");
+ return false;
+ }
+
+ return shouldBeWas(arrToStr(shouldBe), arrToStr(was), info);
+}
+
+////
+
+// Textures
+
+var fibArr = [
+ 0, 1, 1, 2,
+ 3, 5, 8, 13,
+ 21, 34, 55, 89,
+ 144, 233,
+];
+
+var fb = gl.createFramebuffer();
+
+function probeWithBadOffset(fnTest, info) {
+ fnTest(+(-1|0));
+ if (!gl.getError()) {
+ testFailed("Does not support " + info + " with offsets into views.");
+ return false;
+ }
+ return true;
+}
+
+// fn(view, offset, expectedError, expectedResult)
+
+do {
+ var readPixelView = new Uint8Array(4);
+ var testView = new Uint8Array(fibArr);
+
+ function testTexOrSubImage(funcName, fnTexOrSubImage) {
+ debug("");
+ debug(funcName);
+
+ var fnProbe = function(viewOffset) {
+ fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, viewOffset);
+ };
+
+ if (!probeWithBadOffset(fnProbe, funcName))
+ return;
+
+ for (var i = 0; i <= testView.length+1; i++) {
+ debug("offset=" + i);
+
+ fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, i);
+
+ var effectiveViewLen = testView.length - i;
+
+ if (effectiveViewLen >= 4) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeWasArr(testView.slice(i, i+4), readPixelView);
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ }
+ }
+
+ debug("");
+
+ var yellow565 = (0x1f << 11) | (0x3f << 5);
+ var cyan565 = (0x3f << 5) | 0x1f;
+ var arr565 = [yellow565, cyan565];
+ var view565 = new Uint16Array(arr565);
+
+ function rgb888to565(arr888) {
+ return ((arr888[0] >> 3) << 11) | ((arr888[1] >> 2) << 5) | (arr888[2] >> 3);
+ }
+
+ for (var i = 0; i <= arr565.length+1; i++) {
+ debug("rgb565, offset=" + i);
+
+ fnTexOrSubImage(gl.RGB, gl.UNSIGNED_SHORT_5_6_5, view565, i);
+
+ var effectiveViewLen = arr565.length - i;
+
+ if (effectiveViewLen >= 1) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView);
+ debug(arrToStr(readPixelView));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeWas(arr565[i], rgb888to565(readPixelView));
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ }
+ }
+ }
+
+ var fn2D = function(format, type, view, viewOffset) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, view, viewOffset);
+ }
+
+ var fnSub2D = function(format, type, view, viewOffset) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, format, type, view, viewOffset);
+ }
+
+ var fn3D = function(format, type, view, viewOffset) {
+ gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, view, viewOffset);
+ }
+
+ var fnSub3D = function(format, type, view, viewOffset) {
+ gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, null);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, format, type, view, viewOffset);
+ }
+
+ ////
+
+ var tex2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2d, 0);
+
+ testTexOrSubImage("texImage2D", fn2D);
+ testTexOrSubImage("texSubImage2D", fnSub2D);
+
+ ////
+
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0);
+
+ testTexOrSubImage("texImage3D", fn3D);
+ testTexOrSubImage("texSubImage3D", fnSub3D);
+} while (false);
+
+
+do {
+ var compressedFormat = 0;
+ var compressedByteCount;
+
+ if (gl.getExtension("WEBGL_compressed_texture_s3tc")) {
+ var e = gl.getExtension("WEBGL_compressed_texture_s3tc");
+ compressedFormat = e.COMPRESSED_RGB_S3TC_DXT1_EXT;
+ compressedByteCount = 8;
+ } else if (gl.getExtension("WEBGL_compressed_texture_etc")) {
+ var e = gl.getExtension("WEBGL_compressed_texture_etc");
+ compressedFormat = e.COMPRESSED_RGB8_ETC2;
+ compressedByteCount = 8;
+ } else {
+ debug("No compressed texture format found. Skipping compressedTex(Sub)Image tests.");
+ break;
+ }
+
+ ////
+
+ var view = new Uint8Array(compressedByteCount+1);
+
+ var fn2D = function(viewOffset) {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0,
+ view, viewOffset, compressedByteCount);
+ };
+
+ var fnSub2D = function(viewOffset) {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0,
+ view, 0, compressedByteCount);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, compressedFormat,
+ view, viewOffset, compressedByteCount);
+ };
+
+ var fn3D = function(viewOffset) {
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0,
+ view, viewOffset, compressedByteCount);
+ };
+
+ var fnSub3D = function(viewOffset) {
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0,
+ view, 0, compressedByteCount);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 1, compressedFormat,
+ view, viewOffset, compressedByteCount);
+ };
+
+ ////
+
+ var testFunc = function(funcName, fnToTest) {
+ debug("");
+ debug(funcName);
+
+ if (!probeWithBadOffset(fnToTest, funcName))
+ return;
+
+ var viewLength = view.length;
+ var subViewLength = compressedByteCount;
+
+ for (var i = 0; i <= viewLength+1; i++) {
+ debug("offset=" + i);
+
+ fnToTest(i);
+ var effectiveViewLen = viewLength - i;
+
+ if (effectiveViewLen >= subViewLength) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+ }
+ }
+ };
+
+ var tex2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+ testFunc("compressedTexImage2D" , fn2D );
+ testFunc("compressedTexSubImage2D", fnSub2D);
+
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex3d);
+ testFunc("compressedTexImage3D" , fn3D );
+ testFunc("compressedTexSubImage3D", fnSub3D);
+} while (false);
+
+do {
+ debug("");
+ debug("readPixels");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ var testColor = [10, 20, 30, 40];
+ gl.clearColor(testColor[0]/255.0,
+ testColor[1]/255.0,
+ testColor[2]/255.0,
+ testColor[3]/255.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var readPixelView = new Uint8Array(6);
+
+ function doReadPixels(viewOffset) {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView, viewOffset);
+ return readPixelView;
+ }
+
+ if (!probeWithBadOffset(doReadPixels, "doReadPixels"))
+ break;
+
+ for (var i = 0; i <= readPixelView.length+1; i++) {
+ debug("offset=" + i);
+ var res = doReadPixels(i);
+ var effectiveViewLen = readPixelView.length - i;
+
+ if (effectiveViewLen >= 4) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeWasArr(testColor, res.slice(i,i+4));
+
+ } else if (effectiveViewLen >= 0) {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+ }
+ }
+} while (false);
+
+debug("")
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>