diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/js/tests/out-of-bounds-test.js')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/js/tests/out-of-bounds-test.js | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/js/tests/out-of-bounds-test.js b/dom/canvas/test/webgl-conf/checkout/js/tests/out-of-bounds-test.js new file mode 100644 index 0000000000..75e3496dfb --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/js/tests/out-of-bounds-test.js @@ -0,0 +1,321 @@ +/* +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. +*/ + +'use strict'; + +var OutOfBoundsTest = (function() { + +var runCommonInvalidValueTests = function(callTemplate, gl, wtu, ext) { + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {count: -1, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {count: 0, type: 'gl.UNSIGNED_BYTE', offset: -1})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {count: -1, type: 'gl.UNSIGNED_BYTE', offset: 1})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {count: 1, type: 'gl.UNSIGNED_BYTE', offset: -1})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {count: '0xffffffff', type: 'gl.UNSIGNED_BYTE', offset: 0})); +}; + +var setupProgramAndBindVertexArray = function(gl, wtu) { + var program = wtu.loadStandardProgram(gl); + + gl.useProgram(program); + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.enableVertexAttribArray(0); + + return program; +}; + +var setupProgram2 = function(gl, wtu) { + var vshader = [ + 'attribute vec3 aOne;', + 'attribute vec2 aTwo;', + 'void main() {', + ' gl_Position = vec4(aOne, 1.0) + vec4(aTwo, 0.0, 1.0);', + '}' + ].join('\n'); + + var fshader = [ + 'void main() {', + ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);', + '}' + ].join('\n'); + + var program = wtu.setupProgram(gl, [vshader, fshader], [ "aOne", "aTwo" ]); + if (!program) { + testFailed("failed to create test program"); + } + return program; +}; + +var runDrawArraysTest = function(callTemplate, gl, wtu, ext) { + var program = setupProgramAndBindVertexArray(gl, wtu); + + debug("Test empty buffer") + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ ]), gl.STATIC_DRAW); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {offset: 0, count: 1})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {offset: 0, count: 10000})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 1, count: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 100, count: 0})); + runCommonInvalidValueTests(callTemplate, gl, wtu, ext); + + debug("") + debug("Test buffer with 3 float vectors") + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 3})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {offset: 3, count: 2})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {offset: 0, count: 10000})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 100, count: 0})); + runCommonInvalidValueTests(callTemplate, gl, wtu, ext); + + debug("") + debug("Test buffer with interleaved (3+2) float vectors") + + setupProgram2(gl, wtu); + + var vbo = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo); + // enough for 9 vertices, so 3 triangles + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(9*5), gl.STATIC_DRAW); + + // bind first 3 elements, with a stride of 5 float elements + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 5*4, 0); + // bind 2 elements, starting after the first 3; same stride of 5 float elements + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 5*4, 3*4); + + gl.enableVertexAttribArray(0); + gl.enableVertexAttribArray(1); + + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9})); + + // negative values must generate INVALID_VALUE; they can never be valid + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {offset: 0, count: -500})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {offset: -200, count: 1})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {offset: -200, count: -500})); + + // 0xffffffff needs to convert to a 'long' IDL argument as -1, as per + // WebIDL 4.1.7. JS ToInt32(0xffffffff) == -1. Thus INVALID_VALUE. + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {offset: 0, count: '0xffffffff'})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {offset: '0xffffffff', count: '0xffffffff'})); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {offset: '0xffffffff', count: 1})); + + // values that could otherwise be valid but aren't due to bindings generate + // INVALID_OPERATION + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {offset: 0, count: 10000})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {offset: '0x7fffffff', count: 1})); +}; + +var runDrawElementsTest = function(callTemplate, gl, wtu, ext) { + var program = setupProgramAndBindVertexArray(gl, wtu); + var contextVersion = wtu.getDefault3DContextVersion(); + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + + + debug(''); + debug('Test null index buffer'); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 0, type: 'gl.UNSIGNED_BYTE', offset: 0})); + + debug(''); + debug('Test empty index buffer'); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 0, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {count: 10000, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {count: 1, type: 'gl.UNSIGNED_BYTE', offset: 0})); + runCommonInvalidValueTests(callTemplate, gl, wtu, ext); + + debug(''); + debug('Test buffer with 3 byte indexes'); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2 ]), gl.STATIC_DRAW); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_BYTE', offset: 2})); + wtu.shouldGenerateGLError(gl, [gl.NO_ERROR, gl.INVALID_OPERATION], wtu.replaceParams(callTemplate, {count: 10000, type: 'gl.UNSIGNED_BYTE', offset: 0})); + runCommonInvalidValueTests(callTemplate, gl, wtu, ext); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 0, type: 'gl.UNSIGNED_BYTE', offset: 4})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 10000, type: 'gl.UNSIGNED_BYTE', offset: 10000})); + + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, (new Uint8Array([ 3, 0, 1, 2 ])).subarray(1), gl.STATIC_DRAW)'); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint8Array([ 3, 0, 1]))'); + var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR], wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, 'gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, (new Uint8Array([ 3, 0, 1, 2 ])).subarray(1))'); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_BYTE', offset: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 0, type: 'gl.UNSIGNED_BYTE', offset: 0})); + + debug(''); + debug('Test buffer with interleaved (3+2) float vectors'); + + setupProgram2(gl, wtu); + + var vbo = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo); + // enough for 9 vertices, so 3 triangles + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(9*5), gl.STATIC_DRAW); + + // bind first 3 elements, with a stride of 5 float elements + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 5*4, 0); + // bind 2 elements, starting after the first 3; same stride of 5 float elements + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 5*4, 3*4); + + gl.enableVertexAttribArray(0); + gl.enableVertexAttribArray(1); + + var ebo = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo); + // For WebGL 2, PRIMITIVE_RESTART_FIXED_INDEX is always enabled. + // 0xffff will be handled as a primitive restart. + if (contextVersion <= 1) { + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( + [ 0, 1, 2, + 1, 2, 0, + 2, 0, 1, + 201, 202, 203, + 0x7fff, 0x7fff, 0x7fff, + 0xffff, 0xffff, 0xffff ]), + gl.STATIC_DRAW); + } else { + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( + [ 0, 1, 2, + 1, 2, 0, + 2, 0, 1, + 201, 202, 203, + 0x7fff, 0x7fff, 0x7fff, + 0xffff - 1, 0xffff - 1, 0xffff - 1 ]), + gl.STATIC_DRAW); + } + + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 9, type: 'gl.UNSIGNED_SHORT', offset: 0})); + + + // invalid operation with indices that would be valid with correct bindings + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 9, type: 'gl.UNSIGNED_SHORT', offset: 1000})); + wtu.shouldGenerateGLError(gl, indexValidationError, wtu.replaceParams(callTemplate, {count: 12, type: 'gl.UNSIGNED_SHORT', offset: 0})); + wtu.shouldGenerateGLError(gl, indexValidationError, wtu.replaceParams(callTemplate, {count: 15, type: 'gl.UNSIGNED_SHORT', offset: 0})); + wtu.shouldGenerateGLError(gl, indexValidationError, wtu.replaceParams(callTemplate, {count: 18, type: 'gl.UNSIGNED_SHORT', offset: 0})); + wtu.shouldGenerateGLError(gl, indexValidationError, wtu.replaceParams(callTemplate, {count: 3, type: 'gl.UNSIGNED_SHORT', offset: 2*15})); + + // 0xffffffff needs to convert to a 'long' IDL argument as -1, as per + // WebIDL 4.1.7. JS ToInt32(0xffffffff) == -1. Thus INVALID_VALUE. + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, wtu.replaceParams(callTemplate, {count: '0xffffffff', type: 'gl.UNSIGNED_SHORT', offset: 0})); + // offset is defined as GLintptr, which is long long in IDL (64-bit). + // 2^32 - 1 should not overflow, and only result in INVALID_OPERATION. + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 1, type: 'gl.UNSIGNED_SHORT', offset: '0xffffffff'})); + + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: '0x7fffffff', type: 'gl.UNSIGNED_SHORT', offset: 0})); + + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 0, type: 'gl.UNSIGNED_SHORT', offset: 0})); + + // invalid operation with offset that's not a multiple of the type size + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 6, type: 'gl.UNSIGNED_SHORT', offset: 0})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 6, type: 'gl.UNSIGNED_SHORT', offset: 1})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 6, type: 'gl.UNSIGNED_SHORT', offset: 2})); + + // invalid operation if no buffer is bound to ELEMENT_ARRAY_BUFFER + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 6, type: 'gl.UNSIGNED_SHORT', offset: 0})); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo); + + debug(''); + debug('Test buffer setting attrib 0 to a buffer too small and disable it.'); + var smallVBO = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, smallVBO); + gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0x10); + gl.disableVertexAttribArray(0); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {count: 6, type: 'gl.UNSIGNED_SHORT', offset: 2})); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {count: 6, type: 'gl.UNSIGNED_SHORT', offset: 2})); +}; + +var runInstancedTest = function(callTemplate, gl, wtu, ext) { + setupProgram2(gl, wtu); + + // Initialize non-instanced attribute data. + // Enough for 9 vertices, so 3 triangles. + var vbo = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(9*3), gl.STATIC_DRAW); + + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + + // Setup buffer for instanced attribute data. + var vbo2 = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo2); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0); + + gl.enableVertexAttribArray(0); + gl.enableVertexAttribArray(1); + + debug('Test out-of-range instanced attributes'); + debug(''); + + debug('Test with an empty buffer for the instanced attribute'); + ext.vertexAttribDivisorANGLE(1, 1); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 10000, primcount: 0})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 1})); + + debug('Test with a buffer with 1 float for the instanced attribute'); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(1), gl.STATIC_DRAW); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 0})); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 10000, primcount: 0})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 1})); + + debug(''); + debug('Test with a buffer with 2 floats for the instanced attribute'); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(2), gl.STATIC_DRAW); + debug('Divisor 1'); + ext.vertexAttribDivisorANGLE(1, 1); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 1})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 2})); + debug('Divisor 3'); + ext.vertexAttribDivisorANGLE(1, 3); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 3})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 4})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 10000})); + + debug(''); + debug('Test with a buffer with 4 floats for the instanced attribute'); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(4), gl.STATIC_DRAW); + debug('Divisor 1'); + ext.vertexAttribDivisorANGLE(1, 1); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 2})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 3})); + debug('Divisor 2'); + ext.vertexAttribDivisorANGLE(1, 2); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 4})); + wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, wtu.replaceParams(callTemplate, {offset: 0, count: 9, primcount: 5})); +}; + +var runDrawArraysInstancedTest = function(callTemplate, gl, wtu, ext) { + runInstancedTest(callTemplate, gl, wtu, ext); +}; + +var runDrawElementsInstancedTest = function(callTemplate, gl, wtu, ext) { + var ebo = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array( + [ 0, 1, 2, + 5, 4, 3, + 6, 7, 8 ]), + gl.STATIC_DRAW); + callTemplate = wtu.replaceParams(callTemplate, {type: 'gl.UNSIGNED_BYTE', offset: '$(offset)', count: '$(count)', primcount: '$(primcount)'}); + runInstancedTest(callTemplate, gl, wtu, ext); +}; + +return { + runDrawArraysTest: runDrawArraysTest, + runDrawArraysInstancedTest: runDrawArraysInstancedTest, + runDrawElementsTest: runDrawElementsTest, + runDrawElementsInstancedTest: runDrawElementsInstancedTest +}; + +})(); |