diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/extra')
34 files changed, 4030 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/extra/50x50pixel-black-with-red-triangle.png b/dom/canvas/test/webgl-conf/checkout/extra/50x50pixel-black-with-red-triangle.png Binary files differnew file mode 100644 index 000000000..4ec975107 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/50x50pixel-black-with-red-triangle.png diff --git a/dom/canvas/test/webgl-conf/checkout/extra/big-fbos-example.html b/dom/canvas/test/webgl-conf/checkout/extra/big-fbos-example.html new file mode 100644 index 000000000..8f6ce2049 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/big-fbos-example.html @@ -0,0 +1,277 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Big FBO Test</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../../devtools/src/debug/webgl-debug.js"></script> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +</head> +<body> +<canvas id="canvas" width="256" height="256"> </canvas> +<div id="description"></div> +<div id="console"></div> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec4 vPosition; +attribute vec2 texCoord0; +varying vec2 texCoord; +void main() +{ + gl_Position = vec4(vPosition.xyz, 1.0); + texCoord = texCoord0; +} +</script> + +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; +uniform sampler2D tex; +varying vec2 texCoord; +void main() +{ + gl_FragColor = texture2D(tex, texCoord); +} +</script> +<script> +"use strict"; +window.onload = init; + +var g_textures = []; + +debug("Tests the performance of using lots of large FBOs"); + +function init() { + if (confirm( + "After clicking OK your machine may become unresponsive or crash.")) { + main(); + } else { + debug("cancelled"); + } +} + +function checkFBOStatus(gl) { + var err = gl.getError(); + if (err != gl.NO_ERROR) { + if (err != gl.OUT_OF_MEMORY) + testFailed("gl.getError returned " + err); + else + testPassed("OUT-OF-MEMORY"); + return false; + } + var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (status != gl.FRAMEBUFFER_COMPLETE) { + testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status)); + return false; + } + return true; +} + +function setupFBO(gl, size) { + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + 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); + + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); + + gl.texImage2D(gl.TEXTURE_2D, + 0, // level + gl.RGBA, // internalFormat + size, // width + size, // height + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + null); // data + if (!checkFBOStatus(gl)) + return null; + + return { fb: fb, tex: tex }; +} + +function checkPixels(gl) { + var width = 256; + var height = 256; + + var thresh = 3; + + var buf = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); + for (var yy = 0; yy < height; ++yy) { + for (var xx = 0; xx < width; ++xx) { + var offset = (yy * width + xx) * 4; + if (Math.abs(buf[offset] - 255) > thresh || + Math.abs(buf[offset + 1] - 0) > thresh || + Math.abs(buf[offset + 2] - 0) > thresh) { + testFailed("drawing results incorrect"); + return false; + } + } + } + return true; +} + +function handleContextLost() { + debug("context lost"); +} + +function main() { + debug(""); + debug("Checking for out of memory handling."); + + var canvas = document.getElementById("canvas"); + canvas.addEventListener('webglcontextlost', handleContextLost); + var wtu = WebGLTestUtils; + var gl = wtu.create3DContext("canvas"); + var prog = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition", "texCoord0"]); + + WebGLDebugUtils.init(gl); + + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.BLEND); + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + -1,1,0, 1,1,0, -1,-1,0, + -1,-1,0, 1,1,0, 1,-1,0 + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0,1, + 0,1, 1,0, 1,1 + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0); + + var texLoc = gl.getUniformLocation(prog, "tex"); + gl.uniform1i(texLoc, 0); + + gl.clearColor(0, 0, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup should succeed"); + + var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE); + debug("max render buffer size: " + size + + ", size used: " + (size / 2)); + size /= 2; + + var maxFBOs = 200; + var numFBOs = 0; + allocateNextFBO(); + + function allocateNextFBO() { + if (numFBOs >= maxFBOs) { + phase2(); + return; + } + if (!allocateFBO()) { + phase2(); + return; + } + ++numFBOs; + setTimeout(allocateNextFBO, 100); + } + + function allocateFBO() { + debug(""); + debug("trying to create fbo #" + (numFBOs + 1)); + var t = setupFBO(gl, 2); + if (!t) { + return false; + } + + var tex = t.tex; + var fb = t.fb; + + debug("allocating fbo color buffer of size " + size + " x " + size); + gl.texImage2D(gl.TEXTURE_2D, + 0, // level + gl.RGBA, // internalFormat + size, // width + size, // height + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + null); // data + if (!checkFBOStatus(gl)) { + return false; + } + g_textures.push(tex); + debug("succeeded in creating fbo"); + + debug("clearing the fbo with red color"); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.clearColor(1, 0, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + + debug("deleting fbo, but the now red texture should be untouched"); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(fb); + + debug("drawing to the canvas using the red texture"); + gl.clearColor(0, 0, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLES, 0, 6); + if (!checkPixels(gl)) { + return false; + } + + debug("succeeded in drawing"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "each run with no error"); + return true; + } + + function phase2() { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + debug(""); + debug("fbos allocated:" + numFBOs); + if (!checkPixels(gl)) { + testFailed("final check of canvas drawing buffer pixels failed"); + } + debug(""); + finishTest(); + } +} + +var successfullyParsed = true; +</script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/buffer-gc-stress.html b/dom/canvas/test/webgl-conf/checkout/extra/buffer-gc-stress.html new file mode 100644 index 000000000..4b8dc23b2 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/buffer-gc-stress.html @@ -0,0 +1,176 @@ +<!-- + +/* +** Copyright (c) 2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Float32Array garbage collection 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="40" height="40"></canvas> +<div id="description"></div> +<div id="console"></div> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec2 inPosition; +attribute vec4 inColor; + +varying vec4 color; + +void main() +{ + color = inColor; + + gl_Position = vec4(inPosition, 0.0, 1.0); +} +</script> +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; + +varying vec4 color; + +void main() +{ + if (color == vec4(0.0)) + discard; + + gl_FragColor = color; +} +</script> + +<script> +"use strict"; + +description("Allocates a buffer object and then updates it repeatedly using throw-away Float32Array objects. " + + "Ideally, this should not result in a browser crash or instability, since GC should be able to collect all Float32Arrays."); +var wtu = WebGLTestUtils; + +var vertices = []; +var w = 0.25; +for (var x = -1; x < 1; x += w) { + for (var y = -1; y < 1; y += w) { + vertices.push(x + w, y + w); + vertices.push(x, y + w); + vertices.push(x, y ); + + vertices.push(x + w, y + w); + vertices.push(x, y ); + vertices.push(x + w, y ); + } +} +var numVertices = (vertices.length / 2); + +var gl; +var squareBuffer; +var buffer; +var updateBufferData; +var drawIterationsPerTest = 100; + +function initGL() { + gl = wtu.create3DContext("canvas"); + var attribs = ["inPosition", "inColor"]; + wtu.setupProgram(gl, ["vshader", "fshader"], attribs); + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.BLEND); + + squareBuffer = gl.createBuffer(); + gl.enableVertexAttribArray(0); + gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); + gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); + + buffer = gl.createBuffer(); + gl.enableVertexAttribArray(1); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0); +} + +var testIndex = -1; +var drawIterations = 0; +var size = 0; +function runNextTest() { + ++testIndex; + var prevSize = size; + size = Math.pow(2, testIndex) * numVertices * 16; + + if (size > 2 * 1024 * 1024 && prevSize <= 2 * 1024 * 1024) { + if (!confirm("The following tests can cause unresponsiveness or instability. Press OK to continue.")) { + testFailed("Tests aborted"); + return; + } + } + + if (size > 64 * 1024 * 1024) { + gl.deleteBuffer(buffer); + testPassed("Tests finished"); + return; + } + + debug('Initializing buffer with size: ' + size); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, size, gl.DYNAMIC_DRAW); + updateBufferData = new Float32Array(size / 4); + + debug("Drawing " + drawIterationsPerTest + " times, each time creating a new throw-away Float32Array of size " + size + " and using it to update the buffer"); + drawIterations = 0; + doDraw(); +}; + +var doDraw = function() { + gl.clearColor(0, 255, 0, 255); + gl.clear(gl.COLOR_BUFFER_BIT); + + // Update the array buffer with a throw-away Float32Array + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(updateBufferData)); + + gl.drawArrays(gl.TRIANGLES, 0, numVertices); + var error = gl.getError(); + if (error !== gl.NO_ERROR) { + testFailed("drawArrays failed with error " + wtu.glEnumToString(gl, error)); + return; + } + if (drawIterations < drawIterationsPerTest) { + ++drawIterations; + requestAnimationFrame(doDraw); + } else { + runNextTest(); + } +}; + +initGL(); +runNextTest(); + +var successfullyParsed = true; +</script> + +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html b/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html new file mode 100644 index 000000000..5238ec20e --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html @@ -0,0 +1,289 @@ +<!-- + +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Buffer allocation 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="canvasParent"></div> +<div id="description"></div> +<div id="console"></div> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec2 inPosition; +attribute vec4 inColor0; +attribute vec4 inColor1; +attribute vec4 inColor2; +attribute vec4 inColor3; +attribute vec4 inColor4; +attribute vec4 inColor5; +attribute vec4 inColor6; +attribute vec4 inColor7; + +varying vec4 color; + +void main() +{ + color = abs(inColor0) + abs(inColor1) + abs(inColor2) + abs(inColor3) + + abs(inColor4) + abs(inColor5) + abs(inColor6) + abs(inColor7); + + color = clamp(color, vec4(0.0), vec4(1.0)); + + gl_Position = vec4(inPosition, 0.0, 1.0); +} +</script> +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; + +varying vec4 color; + +void main() +{ + if (color == vec4(0.0)) + discard; + + gl_FragColor = color; +} +</script> + +<script> +description("Allocates a number of different sized buffers and checks that the buffers are cleared " + + "OR that the allocation results in gl.OUT_OF_MEMORY or context loss."); +var wtu = WebGLTestUtils; + +// The shader processes eight vec4 attributes at once to reduce the amount of +// draw calls. +var numColorAttrs = 8; + +// Process 64 squares at once to also reduce the amount of draw calls. +var vertices = []; +var w = 0.25; +for (var x = -1; x < 1; x += w) { + for (var y = -1; y < 1; y += w) { + vertices.push(x + w, y + w); + vertices.push(x, y + w); + vertices.push(x, y ); + + vertices.push(x + w, y + w); + vertices.push(x, y ); + vertices.push(x + w, y ); + } +} +var numVertices = (vertices.length / 2); + +var gl; +var squareBuffer; +var error = 0; +var expectContextLost = false; + +function initGLForBufferSizesTest() { + var canvas = document.createElement("canvas"); + canvas.width = 40; + canvas.height = 40; + var parent = document.getElementById("canvasParent"); + parent.innerHTML = ''; + parent.appendChild(canvas); + gl = wtu.create3DContext(canvas); + var attribs = ["inPosition", "inColor0", "inColor1", "inColor2", "inColor3", + "inColor4", "inColor5", "inColor6", "inColor7"]; + wtu.setupProgram(gl, ["vshader", "fshader"], attribs); + gl.enableVertexAttribArray(0); + for (var i = 0; i < numColorAttrs; i++) { + gl.enableVertexAttribArray(1 + i); + } + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.BLEND); + + squareBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); +} + +function createBuffer(size, allowedToFail) { + var msg = "Calling bufferData with size=" + size; + var buffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, size, gl.STATIC_DRAW); + + error = gl.getError(); + if (error !== gl.NO_ERROR) { + gl.deleteBuffer(buffer); + if (allowedToFail) { + if (error === gl.OUT_OF_MEMORY) { + testPassed(msg + " failed with gl.OUT_OF_MEMORY (this is allowed)"); + return null; + } else if (error === gl.CONTEXT_LOST_WEBGL) { + testPassed(msg + " failed with gl.CONTEXT_LOST_WEBGL (this is allowed)"); + return null; + } + } + testFailed(msg + " failed with error " + wtu.glEnumToString(gl, error)); + return null; + } + + testPassed(msg + " did not result in any errors"); + var reportedSize = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE); + expectContextLost = false; + if (reportedSize === null) { + testPassed("Null size reported by gl, this should happen if the context is lost which is allowed."); + expectContextLost = true; + } else if (reportedSize !== size) { + if (size > Math.pow(2, 32)) { + testPassed("gl reported different size " + reportedSize + " for the buffer, but this is expected since " + + "the requested size was above what the return value of getBufferParameter can represent."); + } else { + testFailed("gl reported different size " + reportedSize + " for the buffer."); + } + } else { + testPassed("Size reported by gl was the same as the requested size."); + } + + return buffer; +} + +// Draw a square on the canvas using attributes from the clear buffer created with bufferData. +function drawWithBuffer(buffer, allowedToFail) { + gl.clearColor(0, 1, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + var size = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE); + // Each vec4 is 16 bytes + var increment = numVertices * numColorAttrs * 16; + for (var offset = 0; offset + increment <= size; offset += increment) { + gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer); + gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); + + for (var i = 0; i < numColorAttrs; i++) { + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.vertexAttribPointer(1 + i, 4, gl.FLOAT, false, 0, + offset + increment * i / numColorAttrs); + } + gl.drawArrays(gl.TRIANGLES, 0, numVertices); + error = gl.getError(); + + if (error !== gl.NO_ERROR) { + if (allowedToFail) { + if (error === gl.OUT_OF_MEMORY) { + testPassed("drawArrays failed with gl.OUT_OF_MEMORY (this is allowed)"); + return; + } else if (error === gl.CONTEXT_LOST_WEBGL) { + testPassed("drawArrays failed with gl.CONTEXT_LOST_WEBGL (this is allowed)"); + return; + } + } + testFailed("drawArrays failed with error " + wtu.glEnumToString(gl, error)); + return; + } + } + wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green"); +} + + +// To be able to confirm the whole buffer has been cleared, the size needs to +// be divisible by the amount of vertices. Thus most sizes are multiples of 3. +var tests = [ + // Reasonable sized buffers. + { size: 3 * 1024, allowedToFail: false, tryDrawing: true }, + { size: 3 * 1024 * 1024, allowedToFail: false, tryDrawing: true }, + { size: 3 * 1024 * 1024 * 16, allowedToFail: false, tryDrawing: true }, + + // Huge buffers, which are meant to test out of memory handling. + // Allowed failures are gl.OUT_OF_MEMORY or context loss. + // Succeeding in the allocations is allowed as well for forward compatibility. + + // 1.5 GB allocation for stressing lower-end 32-bit systems. + // Allocation is likely to succeed on higher-end hardware. + { size: 3 * 1024 * 1024 * 512, allowedToFail: true, tryDrawing: true }, + // A buffer that no implementation will be able to allocate for some time + // to come. To do this, we use half of the lower 43-bit half of a 44-bit + // memory address space, so that the size is still valid on current common + // 64-bit implementations, and also below 52-bit limit for exact conversion + // from float to long long in WebIDL (though 2^n should be safe anyway). + // The 4 TB size is large enough that even extrapolating the historical + // exponential growth trend of memory sizes, hardware in 2020's should + // still have some trouble actually doing the allocation. + { size: (1 << 12) * (1 << 30), allowedToFail: true, tryDrawing: false } +]; + +function finishBufferSizesTest() { + gl.deleteBuffer(squareBuffer); + finishTest(); +} + +var testIndex = -1; +function runNextTest() { + ++testIndex; + if (testIndex > 0 && tests[testIndex - 1].allowedToFail) { + if (gl.isContextLost() || error === gl.OUT_OF_MEMORY) { + initGLForBufferSizesTest(); + } else if (expectContextLost) { + testFailed("Context was not lost after timeout even though gl.getBufferParameter returned null."); + } + } + var buffer = createBuffer(tests[testIndex].size, tests[testIndex].allowedToFail); + if (buffer) { + if (tests[testIndex].tryDrawing) { + drawWithBuffer(buffer, tests[testIndex].allowedToFail); + } + gl.deleteBuffer(buffer); + } + + if (testIndex + 1 >= tests.length) { + finishBufferSizesTest(); + } else { + if (tests[testIndex + 1].allowedToFail && !tests[testIndex].allowedToFail) { + if (!confirm("The following tests can cause unresponsiveness or instability. Press OK to continue.")) { + testFailed("Tests aborted"); + return; + } + } + if (tests[testIndex].allowedToFail) { + // Give plenty of time for possible context loss + setTimeout(runNextTest(), 5000); + } else { + runNextTest(); + } + } +}; + +initGLForBufferSizesTest(); +runNextTest(); + +var successfullyParsed = true; +</script> + +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.html b/dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.html new file mode 100644 index 000000000..654c458b7 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.html @@ -0,0 +1,109 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Canvas Compositing 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> +Below are 2 50x50 pixel canvas but using CSS to display them at 100x100 pixels. <br/> +They are solid black with a red triangle<br/> +They each have a 10px CSS solid black border around them.<br/> +Depending on how the browser composites the canvas with the page they will get +a white outline<hr/> +<div> +2d canvas<br/> +<canvas id="example2" width="50" height="50" style="width: 100px; height: 100px; border: 10px solid black;"></canvas> +</div> +<hr/> +3d canvas<br/> +<div> +<canvas id="example" width="50" height="50" style="width: 100px; height: 100px; border: 10px solid black;"></canvas> +</div> +<hr/> +img tag<br/> +<img src="50x50pixel-black-with-red-triangle.png" style="width: 100px; height: 100px; border: 10px solid black;"/> +<div id="description"></div> +<div id="console"></div> + <script id="vshader" type="x-shader/x-vertex"> + attribute vec4 vPosition; + void main() + { + gl_Position = vPosition; + } + </script> + + <script id="fshader" type="x-shader/x-fragment"> + void main() + { + gl_FragColor = vec4(1.0,0.0,0.0,1.0); + } + </script> + + <script> + "use strict"; + function init() + { + var wtu = WebGLTestUtils; + var canvas2d = document.getElementById("example2"); + var ctx2d = canvas2d.getContext("2d"); + ctx2d.fillStyle = "rgba(0, 0, 0, 255)" + ctx2d.fillRect(0, 0, 50, 50); + ctx2d.fillStyle = "rgba(255, 0, 0, 255)" + ctx2d.beginPath(); + ctx2d.moveTo(25, 12.5); + ctx2d.lineTo(12.5, 37.5); + ctx2d.lineTo(37.5, 37.5); + ctx2d.lineTo(25, 12.5); + ctx2d.fill(); + + + var gl = wtu.create3DContext("example"); + var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]); + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + 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.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLES, 0, 3); + } + + init(); + var successfullyParsed = true; + </script> +</body> +<script src="../js/js-test-post.js"></script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.png b/dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.png Binary files differnew file mode 100644 index 000000000..ba80dbe76 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.png diff --git a/dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html b/dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html new file mode 100644 index 000000000..de563c1a2 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html @@ -0,0 +1,240 @@ +<!-- + +/* +** Copyright (c) 2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Indexing with a constant expression should compile only if the index is in range</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<link rel="stylesheet" href="../resources/glsl-feature-tests.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +<script src="../js/glsl-conformance-test.js"></script> +<script id="VertexArrayTemplate" type="x-shader/x-vertex"> +precision mediump float; + +uniform float ua[4]; + +$(init) + +void main() { + float c = ua[$(constantExpression)]; + gl_Position = vec4(c); +} +</script> +<script id="FragmentArrayTemplate" type="x-shader/x-fragment"> +precision mediump float; + +uniform float ua[4]; + +$(init) + +void main() { + float c = ua[$(constantExpression)]; + gl_FragColor = vec4(c); +} +</script> +<script id="VertexVectorTemplate" type="x-shader/x-vertex"> +precision mediump float; + +uniform vec4 uv; + +$(init) + +void main() { + float c = uv[$(constantExpression)]; + gl_Position = vec4(c); +} +</script> +<script id="FragmentVectorTemplate" type="x-shader/x-fragment"> +precision mediump float; + +uniform vec4 uv; + +$(init) + +void main() { + float c = uv[$(constantExpression)]; + gl_FragColor = vec4(c); +} +</script> +<script id="VertexMatrixTemplate" type="x-shader/x-vertex"> +precision mediump float; + +uniform mat4 um; + +$(init) + +void main() { + float c = um[$(constantExpression)].x; + gl_Position = vec4(c); +} +</script> +<script id="FragmentMatrixTemplate" type="x-shader/x-fragment"> +precision mediump float; + +uniform mat4 um; + +$(init) + +void main() { + float c = um[$(constantExpression)].x; + gl_FragColor = vec4(c); +} +</script> +</head> +<body onload="runTest()"> +<div id="description"></div> +<div id="console"></div> +<script type="application/javascript"> +"use strict"; +description(); + +var wtu = WebGLTestUtils; + +// ESSL 1.00 section 4.1.9 Arrays +// It is illegal to index an array with an integral constant expression greater than or equal to its +// declared size. It is also illegal to index an array with a negative constant expression. + +// ESSL 1.00 section 5.5 Vector Components +// Reading from or writing to a vector using a constant integral expression with a value that is negative +// or greater than or equal to the size of the vector is illegal. + +// ESSL 1.00 section 5.6 Matrix components +// The behavior when accessing a component outside the bounds of a matrix are the same as those for +// vectors and arrays. The compiler must generate an error if the index expression is a constant expression. + +// ESSL 1.00 spec section 5.10. +// A constant expression is one of +// * a literal value (e.g., 5 or true) +// * a global or local variable qualified as const excluding function parameters +// * an expression formed by an operator on operands that are constant expressions, including getting +// an element of a constant vector or a constant matrix, or a field of a constant structure +// * a constructor whose arguments are all constant expressions +// * a built-in function call whose arguments are all constant expressions, with the exception of the +// texture lookup functions. + +var runTest = function() { + var vsArrayTemplate = document.getElementById('VertexArrayTemplate').text; + var fsArrayTemplate = document.getElementById('FragmentArrayTemplate').text; + var vsVectorTemplate = document.getElementById('VertexVectorTemplate').text; + var fsVectorTemplate = document.getElementById('FragmentVectorTemplate').text; + var vsMatrixTemplate = document.getElementById('VertexMatrixTemplate').text; + var fsMatrixTemplate = document.getElementById('FragmentMatrixTemplate').text; + + var tests = []; + + var pushTest = function(constantExpression, expectSuccess, opt_init) { + if (opt_init === undefined) { + opt_init = ''; + } + tests.push({ + vShaderSource: wtu.replaceParams(vsArrayTemplate, {constantExpression: constantExpression, init: opt_init}), + vShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as an index for an array with size 4 in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + fShaderSource: wtu.replaceParams(fsArrayTemplate, {constantExpression: constantExpression, init: opt_init}), + fShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as an index for an array with size 4 in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + vShaderSource: wtu.replaceParams(vsVectorTemplate, {constantExpression: constantExpression, init: opt_init}), + vShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a vec4 index in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + fShaderSource: wtu.replaceParams(fsVectorTemplate, {constantExpression: constantExpression, init: opt_init}), + fShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a vec4 index in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + vShaderSource: wtu.replaceParams(vsMatrixTemplate, {constantExpression: constantExpression, init: opt_init}), + vShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a mat4 index in a vertex shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + tests.push({ + fShaderSource: wtu.replaceParams(fsMatrixTemplate, {constantExpression: constantExpression, init: opt_init}), + fShaderSuccess: expectSuccess, + linkSuccess: expectSuccess, + passMsg: "Using " + constantExpression + " as a mat4 index in a fragment shader should " + (expectSuccess ? "compile." : "fail compilation.") + }); + } + + pushTest('0', true); + pushTest('3', true); + pushTest('-1', false); + pushTest('4', false); + pushTest('2 + 2', false); + pushTest('6 - 2', false); + pushTest('2 * 2', false); + pushTest('8 / 2', false); + pushTest('int(true) * 4', false); + pushTest('ivec4(4).x', false); + pushTest('ivec4(4)[0]', false); + pushTest('int(vec4(5.0).x)', false); + pushTest('int(mat4(5.0)[0].x)', false); + + pushTest('int(radians(360.0))', false); + pushTest('int(degrees(1.0))', false); + pushTest('int(5.0 + sin(0.0))', false); + pushTest('int(5.0 + asin(0.0))', false); + pushTest('int(pow(2.0, 3.0))', false); + pushTest('int(exp(3.0))', false); + pushTest('int(exp2(4.0))', false); + pushTest('int(floor(-0.5))', false); // floor(-0.5) = -1.0 + pushTest('int(5.0 + fract(-3.5))', false); + pushTest('int(mod(2.0, -4.0))', false); // mod(2.0, -4.0) = 2.0 - (-4.0) * floor(2.0 / -4.0) = 2.0 + 4.0 * (-1.0) = -2.0 + pushTest('int(mix(2.0, 8.0, 0.9))', false); + pushTest('int(length(vec4(3.0)))', false); + pushTest('int(lessThan(vec4(2.0), vec4(3.0)).x) * 4', false); + + pushTest('true ? 5 : 0', false); + pushTest('int(false ? 0.0 : 5.0)', false); + pushTest('my_struct(5, 1).field', false, 'struct my_struct { int field; int field2; };'); + + pushTest('int(-0.9)', true); // conversion to int drops the fractional part + + // Sequence operator returns the value of the right-most expression. + // Note that the sequence operator is allowed in constant expressions in ESSL 1.00, + // but not in ESSL 3.00, so with ESSL 3.00 failing compilation would not be required. + pushTest('5, 1', true); + pushTest('1, 5', false); + + GLSLConformanceTester.runTests(tests); +} + +var successfullyParsed = true; +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/context-creation-and-destruction-stress.html b/dom/canvas/test/webgl-conf/checkout/extra/context-creation-and-destruction-stress.html new file mode 100644 index 000000000..6822bc234 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/context-creation-and-destruction-stress.html @@ -0,0 +1,56 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test that contexts are freed and garbage collected reasonably</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"> </script> +<script src="../js/tests/iterable-test.js"> </script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +description(); + +var wtu = WebGLTestUtils; + +var test = IterableTest.createContextCreationAndDestructionTest(); +var iterations = parseInt(wtu.getUrlOptions().iterations, 10) || 500; +IterableTest.run(test, iterations); + +var successfullyParsed = true; +</script> + +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/cube-map-uploads-out-of-order.html b/dom/canvas/test/webgl-conf/checkout/extra/cube-map-uploads-out-of-order.html new file mode 100644 index 000000000..489aea6ca --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/cube-map-uploads-out-of-order.html @@ -0,0 +1,112 @@ +<!-- + +/* +** Copyright (c) 2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL cube map out of order upload test.</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +<script src="../js/glsl-conformance-test.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<canvas id="example" width="64" height="64"> +</canvas> +<script> +"use strict"; +description("Test out of order cube map uploads."); +debug("Regression test for crbug.com/473739 / Apple Radar 20444072."); + +<!-- Thanks to Gregg Tavares for the original report and test case. --> + +var wtu = WebGLTestUtils; + +var canvas = document.getElementById("example"); +canvas.addEventListener('webglcontextlost', contextLost, false); + +var contextWasLost = false; + +function contextLost(e) { + e.preventDefault(); + contextWasLost = true; + debug("***context lost -- should not happen***"); +} + +var dataWidth = 256; +var dataHeight = 256; +var gl = wtu.create3DContext(canvas); +var tex = gl.createTexture(); +// start with 1x1 pixel cubemap +gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); +var color = new Uint8Array([128, 192, 255, 255]); +for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color); +} +gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); +gl.generateMipmap(gl.TEXTURE_CUBE_MAP); // there's no need to call this but the code doesn't check the size. + +var textureData = new Uint8Array(dataWidth * dataHeight * 4); + +// The first texture has downlaoded +var first = 1; +gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); +gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + first, 0, gl.RGBA, dataWidth, dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData); + +// Now because the first face downloaded doesn't match the other 5 faces upload the same image to the other 5 +// 1x1 faces +for (var ii = 0; ii < 6; ++ii) { + if (ii !== first) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, dataWidth, dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData); + } +} +gl.generateMipmap(gl.TEXTURE_CUBE_MAP); + +// Now as each new face comes in add it +for (var ii = 0; ii < 6; ++ii) { + if (ii !== first) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, dataWidth, dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData); + gl.generateMipmap(gl.TEXTURE_CUBE_MAP); + } +} + +gl.flush(); + +setTimeout(function() { + shouldBe("contextWasLost", "false"); + finishTest(); +}, 1000); + +var successfullyParsed = true; +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/fbo-lost-context.html b/dom/canvas/test/webgl-conf/checkout/extra/fbo-lost-context.html new file mode 100644 index 000000000..a9aa71b47 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/fbo-lost-context.html @@ -0,0 +1,223 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL FBO Lost Context Test</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../../devtools/src/debug/webgl-debug.js"></script> +<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="vshader" type="x-shader/x-vertex"> +attribute vec4 vPosition; +attribute vec2 texCoord0; +uniform mat4 world; +varying vec2 texCoord; +void main() +{ + gl_Position = vPosition * world; + texCoord = texCoord0; +} +</script> + +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; +uniform sampler2D tex; +varying vec2 texCoord; +void main() +{ + gl_FragColor = texture2D(tex, texCoord); +} +</script> +<canvas id="canvas" width="1024" height="1024"> </canvas> +<script> +"use strict"; +description("This test is to help see if an WebGL app *can* get lost context."); + +debug(""); +debug("Canvas.getContext"); +var wtu = WebGLTestUtils; +var g_worldLoc; +var g_texLoc; +var g_textures = []; +var gl = wtu.create3DContext("canvas"); +if (!gl) { + testFailed("context does not exist"); +} else { + testPassed("context exists"); + + debug(""); + debug("Checking for out of memory handling."); + + var program = wtu.setupProgram(["vshader", "fshader"], ["vPosition", "texCoord0"]); + var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE); + debug("max render buffer size: " + size); + size = size / 2; + debug("size used: " + size); + + var allocateFramebuffers = true; + var itervalId; + var count = 0; + + gl = WebGLDebugUtils.makeDebugContext(gl, function(err, functionName, args) { + window.clearInterval(intervalId); + assertMsg(err == gl.OUT_OF_MEMORY, + "correctly returns gl.OUT_OF_MEMORY when out of memory"); + finish(); + }); + + function createFBO() { + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + 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.texImage2D(gl.TEXTURE_2D, + 0, // level + gl.RGBA, // internalFormat + size, // width + size, // height + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + null); // data + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + tex, + 0); + var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (status != gl.FRAMEBUFFER_COMPLETE) { + testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status)); + } + return { fb: fb, tex: tex }; + } + + gl.disable(gl.DEPTH_TEST); + + var numFBOs = 32; + for (var ii = 0; ii < numFBOs; ++ii) { + createFBO(); + var t = createFBO(); + tex = t.tex; + fb = t.fb; + + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.scissor(0, 0, size, size); + gl.clearColor(0, ii / numFBOs, 1 - ii / numFBOs, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + g_textures.push(tex); + } + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + -1,1,0, 1,1,0, -1,-1,0, + -1,-1,0, 1,1,0, 1,-1,0 + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + 0,0, 1,0, 0,1, + 0,1, 1,0, 1,1 + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0); + + gl.bindTexture(gl.TEXTURE_2D, tex); + g_texLoc = gl.getUniformLocation(gl.program, "tex"); + gl.uniform1i(g_texLoc, 0); + g_worldLoc = gl.getUniformLocation(gl.program, "world"); + gl.uniformMatrix4fv(g_worldLoc, false, [ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1]); + + 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_MIN_FILTER, gl.LINEAR); + + setInterval(render, 1000/60); +} + +var g_angle = 0; +var g_texIndex = 0; +function render() { + g_angle += 0.1; + g_texIndex++; + if (g_texIndex >= g_textures.length) { + g_texIndex = 0; + } + gl.bindTexture(gl.TEXTURE_2D, g_textures[g_texIndex]); + gl.uniformMatrix4fv(g_worldLoc, false, rotationZ(g_angle)); + gl.clearColor(1,0,0,1); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLES, 0, 6); +} + +/** + * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle. + * @param {number} angle The angle by which to rotate (in radians). + * @return {!o3djs.math.Matrix4} The rotation matrix. + */ +function rotationZ(angle) { + var c = Math.cos(angle); + var s = Math.sin(angle); + + return [ + c, s, 0, 0, + -s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ]; +}; + +debug(""); +var successfullyParsed = true; +</script> +<script> +"use strict"; +</script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-example.html b/dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-example.html new file mode 100644 index 000000000..519f023cf --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-example.html @@ -0,0 +1,110 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Lots of polygons example.</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"> </script> +</head> +<body> +<canvas id="example" width="1024" height="1024" style="width: 40px; height: 40px;"> +</canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +window.onload = init; +debug("Tests a WebGL program that draws a bunch of large polygons"); + +function init() { + if (confirm( + "After clicking OK your machine may become unresponsive or crash.")) { + main(); + } else { + debug("cancelled"); + } +} + +function main() { + var wtu = WebGLTestUtils; + var canvas = document.getElementById("example"); + canvas.addEventListener("webglcontextlost", function(e) { e.preventDefault(); }, false); + canvas.addEventListener("webglcontextrestored", function(e) { }, false); + + var gl = wtu.create3DContext(canvas); + var program = wtu.setupTexturedQuad(gl); + + assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup."); + + var tex = gl.createTexture(); + gl.enable(gl.BLEND); + gl.disable(gl.DEPTH_TEST); + + wtu.fillTexture(gl, tex, 4096, 4096, [0, 192, 128, 255], 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture"); + + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + 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); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting texture params"); + + var loc = gl.getUniformLocation(program, "tex"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting tex locations"); + gl.uniform1i(loc, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting tex uniform"); + + var numQuads = 100000; + var indexBuf = new ArrayBuffer(numQuads * 6); + var indices = new Uint8Array(indexBuf); + for (var ii = 0; ii < numQuads; ++ii) { + var offset = ii * 6; + indices[offset + 0] = 0; + indices[offset + 1] = 1; + indices[offset + 2] = 2; + indices[offset + 3] = 3; + indices[offset + 4] = 4; + indices[offset + 5] = 5; + } + var indexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating index buffer"); + gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing"); + + var successfullyParsed = true; +} +</script> +</body> +</html> + + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-shader-example.html b/dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-shader-example.html new file mode 100644 index 000000000..78f40ae8c --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-shader-example.html @@ -0,0 +1,176 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Lots of polygons example.</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> +<style> +html, body { + width: 100%; + height: 100%; +} +canvas { + border: 1px solid black; + width: 95%; + height: 80%; +} +</style +</head> +<body> +<canvas id="example"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +window.onload = init; +debug("Tests a WebGL program that draws a bunch of large polygons from a quad mesh"); + +function init() { + if (confirm( + "After clicking OK your machine may become unresponsive or crash.")) { + main(); + } else { + debug("cancelled"); + } +} + +function main() { + var wtu = WebGLTestUtils; + var canvas = document.getElementById("example"); + var gridRes = 1000; + canvas.width = canvas.clientWidth; + canvas.heigt = canvas.clientHeight; + canvas.addEventListener("webglcontextlost", function(e) { e.preventDefault(); }, false); + canvas.addEventListener("webglcontextrestored", function(e) { }, false); + + var gl = wtu.create3DContext(canvas); + var program = wtu.setupProgram( + gl, ['vshader', 'fshader'], ['vPosition'], [0]); + + wtu.setupIndexedQuad(gl, gridRes, 0, true); + + // make 1 texture since we'd have at least that in CSS shaders + var size = 256; + var pixels = new Uint8Array(size * size * 4); + for (var y = 0; y < size; ++y) { + for (var x = 0; x < size; ++x) { + var offset = (y * size + x) * 4; + pixels[offset + 0] = x * 255 / size; + pixels[offset + 1] = y * 255 / size; + pixels[offset + 2] = x * y * 255 / (size * size); + pixels[offset + 3] = 255; + } + } + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + 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_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + // add test colors. + if (false) { + var vertsAcross = gridRes + 1; + var numQuads = vertsAcross * vertsAcross; + var colors = new Float32Array(numQuads * 4); + for (var ii = 0; ii < numQuads; ++ii) { + var offset = ii * 4; + colors[offset + 0] = Math.random(); + colors[offset + 1] = Math.random(); + colors[offset + 2] = Math.random(); + colors[offset + 3] = 1; + } + var colorLocation = gl.getAttribLocation(program, "color") + var buf = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buf); + gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); + gl.enableVertexAttribArray(colorLocation); + gl.vertexAttribPointer(colorLocation, 3, gl.FLOAT, false, 0, 0); + } + + var gridResLoc = gl.getUniformLocation(program, "gridRes"); + gl.uniform1f(gridResLoc, gridRes); + + assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup."); + + gl.enable(gl.BLEND); + //gl.enable(gl.CULL_FACE); + //gl.cullFace(gl.FRONT); + + gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing"); + + var successfullyParsed = true; +} +</script> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec4 vPosition; +varying vec2 v_texCoord; +uniform float gridRes; + +#ifdef ADD_TEST_COLORS + attribute vec4 color; + varying vec4 v_color; +#endif + +void main() +{ + // expand each quad to cover the entire element. + vec2 p = mod((vPosition.xy * 0.5 + 0.5) * gridRes, 2.0) * 2.0 - 1.0; + gl_Position = vec4(p, 0, 1); + v_texCoord = vPosition.xy; + +#ifdef ADD_TEST_COLORS + v_color = color; +#endif +} +</script> + +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; +varying vec4 v_color; +varying vec2 v_texCoord; +uniform sampler2D tex; +void main() +{ +#ifdef ADD_TEST_COLORS + gl_FragColor = v_color; +#else + gl_FragColor = texture2D(tex, v_texCoord); +#endif +} +</script> +</body> +</html> + + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/multisample-corruption-stress.html b/dom/canvas/test/webgl-conf/checkout/extra/multisample-corruption-stress.html new file mode 100644 index 000000000..16cde8b20 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/multisample-corruption-stress.html @@ -0,0 +1,58 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Multisample Renderbuffer Corruption Test</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../jss/webgl-test-utils.js"> </script> +<script src="../js/tests/iterable-test.js"> </script> +</head> +<body> +<canvas id="example" width="2048" height="2048" style="width: 128px; height: 128px;"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; + +description(document.title); + +var wtu = WebGLTestUtils; + +var gl = wtu.create3DContext("example", {antialias: true, preserveDrawingBuffer: true}); +var test = IterableTest.createMultisampleCorruptionTest(gl); +var iterations = parseInt(wtu.getUrlOptions().iterations, 10) || 100; +IterableTest.run(test, iterations); + +var successfullyParsed = true; +</script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/offscreen-issue.html b/dom/canvas/test/webgl-conf/checkout/extra/offscreen-issue.html new file mode 100644 index 000000000..598be0e8a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/offscreen-issue.html @@ -0,0 +1,64 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<script type="application/javascript"> + +window.onload = function() { + setup("1"); + setup("2"); +} + +function setup(id) { + var c = document.getElementById(id); + var names = ["webgl", "experimental-webgl"]; + for (var i = 0; i < names.length; ++i) { + gl = canvas.getContext(names[i]); + if (gl) { + break; + } + } + gl.clearColor(1,0,0,1); + gl.clear(gl.COLOR_BUFFER_BIT); + setTimeout(function() { + gl.enable(gl.SCISSOR_TEST); + gl.scissor(0,0,50,50); + gl.clearColor(0,1,0,1); + gl.clear(gl.COLOR_BUFFER_BIT); + }, 500); +} +</script> +</head> +<body> +<canvas id="1"></canvas> +<div style="height:4000px;">content that is tall like several articles</div> +<canvas id="2"></canvas> +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/out-of-bounds-uniform-array-access.html b/dom/canvas/test/webgl-conf/checkout/extra/out-of-bounds-uniform-array-access.html new file mode 100644 index 000000000..4328d71eb --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/out-of-bounds-uniform-array-access.html @@ -0,0 +1,126 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL out of bounds uniform array access.</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 style="background: #666;"> +<div id="description"></div> +<div id="console"></div> +<div>elem mult: <span id="elemMultDisplay"></span></div> +<input type="range" id="elemMult" value="4" min="0" max="2048" style="width: 100%;"/> +<div>line width: <span id="lineWidthDisplay"></span></div> +<input type="range" id="lineWidth" value="512" min="0" max="2540" style="width: 100%;"/> +<canvas id="example" width="256" height="256" style="background: black;"> +</canvas> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec4 vPosition; +varying vec4 v_color; +uniform float lineWidth; +uniform int elemMult; +uniform vec4 someArray[2]; +void main() +{ + vec2 texcoord = vec2(vPosition.xy * 0.5 + vec2(0.5, 0.5)); + int index = int(texcoord.x + texcoord.y * lineWidth) * elemMult; + v_color = someArray[index]; + gl_Position = vPosition; +} +</script> + +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; +varying vec4 v_color; +void main() +{ + gl_FragColor = v_color * vec4(1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0) + vec4(0,0,0,0.5); +} +</script> +<script> +"use strict"; +window.onload = main; +debug("Tests a WebGL program that accesses out of bounds uniform array elements"); + +function main() { + var wtu = WebGLTestUtils; + var gl = wtu.create3DContext("example"); + var program = wtu.setupProgram( + gl, + ['vshader', 'fshader'], + ['vPosition'], [0]); + var gridRes = 255; + wtu.setupIndexedQuad(gl, gridRes, 0); + var lineWidthLoc = gl.getUniformLocation(program, "lineWidth"); + var elemMultLoc = gl.getUniformLocation(program, "elemMult"); + assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup."); + + var lineWidth = 512; + var lineWidthElem = document.getElementById("lineWidth"); + var lineWidthDisplayElem = document.getElementById("lineWidthDisplay"); + + lineWidthElem.value = lineWidth; + + lineWidthElem.addEventListener('change', function(event) { + //console.log(event.target.value); + lineWidth = event.target.value; + draw(); + }, false); + + var elemMult = 4; + var elemMultElem = document.getElementById("elemMult"); + var elemMultDisplayElem = document.getElementById("elemMultDisplay"); + + elemMultElem.value = elemMult; + + elemMultElem.addEventListener('change', function(event) { + //console.log(event.target.value); + elemMult = event.target.value; + draw(); + }, false); + + draw(); + + function draw() { + lineWidthDisplayElem.innerText = lineWidth; + elemMultDisplayElem.innerText = elemMult; + gl.uniform1f(lineWidthLoc, lineWidth); + gl.uniform1i(elemMultLoc, elemMult); + gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0); + } + + var successfullyParsed = true; +} + +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/out-of-memory.html b/dom/canvas/test/webgl-conf/checkout/extra/out-of-memory.html new file mode 100644 index 000000000..88b033e93 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/out-of-memory.html @@ -0,0 +1,105 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Out Of Memory 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> +<canvas id="canvas" width="2" height="2"> </canvas> +<script> +"use strict"; +debug("This tests WebGL running out of memory."); + +debug(""); +debug("Canvas.getContext"); + +var wtu = WebGLTestUtils; +var gl = wtu.create3DContext("canvas"); +if (!gl) { + testFailed("context does not exist"); +} else { + testPassed("context exists"); + + debug(""); + debug("Allocating shaders."); + + function makeBigShader() { + var lines = []; + var line = "// "; + for (var ii = 0; ii < 1024; ++ii) { + line += String.fromCharCode(48 + ii % 10); + } + for (var ii = 0; ii < 1024; ++ii) { + lines[ii] = line; + } + var oneMB = lines.join(); + for (var ii = 0; ii < 64; ++ii) { + lines[ii] = oneMB; + } + return lines.join("\n"); + } + + var shaderSource = makeBigShader(); + debug("created " + Math.floor(shaderSource.length / 1024 / 1024) + "MB shader"); + + var intervalId; + var count = 0; + + function makeShader() { + ++count; + debug ("creating shader #" + count + " mem = " + Math.floor(shaderSource.length * count / 1024 / 1024) + "MB"); + var shader = gl.createShader(gl.VERTEX_SHADER); + if (shader == null) { + window.clearInterval(intervalId); + testPassed("createShader returns null"); // not sure this is a passing + finishTest(); + } else { + gl.shaderSource(shader, shaderSource); + var err = gl.getError(); + if (err != gl.NO_ERROR) { + window.clearInterval(intervalId); + assertMsg(err == gl.OUT_OF_MEMORY, "shaderSource returns OUT_OF_MEMORY"); + finishTest(); + } + } + } + + intervalId = window.setInterval(makeShader, 1000/15); +} +</script> +<script src="../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/out-of-resources.html b/dom/canvas/test/webgl-conf/checkout/extra/out-of-resources.html new file mode 100644 index 000000000..86028f952 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/out-of-resources.html @@ -0,0 +1,141 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Out Of Resources Test</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../../devtools/src/debug/webgl-debug.js"></script> +<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> +<canvas id="canvas2" width="2" height="2"> </canvas> +<script> +"use strict"; +wtu = WebGLTestUtils; +window.onload = init; +debug("Tests a WebGL program that tries to use all of vram."); + +function init() { + if (confirm( + "After clicking OK your machine may become unresponsive or crash.")) { + main(); + } else { + debug("cancelled"); + } +} + +function main() { + debug(""); + debug("Canvas.getContext"); + + var gl = wtu.create3DContext("canvas"); + if (!gl) { + testFailed("context does not exist"); + } else { + testPassed("context exists"); + + var program = wtu.setupColorQuad(gl); + gl.useProgram(program); + + debug(""); + debug("Checking for out of memory handling."); + + var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE); + debug("max render buffer size: " + size); + + var allocateFramebuffers = true; + var itervalId; + var count = 0; + + gl = WebGLDebugUtils.makeDebugContext(gl, function(err, functionName, args) { + assertMsg(err == gl.OUT_OF_MEMORY, + "correctly returns gl.OUT_OF_MEMORY when out of memory"); + stop("got: " + wtu.glEnumToString(gl, err)); + }); + + var fbos = []; + + intervalId = window.setInterval(function() { + ++count; + var mem = count * size * size * 4; + debug("#" + count + " : memory allocated so far " + (mem / 1024 / 1024) + "MB"); + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + 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.texImage2D(gl.TEXTURE_2D, + 0, // level + gl.RGBA, // internalFormat + size, // width + size, // height + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + null); // data + var err = gl.getError(); + if (err != gl.NO_ERROR) { + stop("got error: " + wtu.glEnumToString(gl, err)); + return; + } + if (allocateFramebuffers) { + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + tex, + 0); + var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (status != gl.FRAMEBUFFER_COMPLETE) { + stop("got: " + wtu.glEnumToString(gl, status)); + return; + } + // use the framebuffer + wtu.drawFloatColorQuad(gl, [1, Math.random(), 1, 1]); + } + }, 200); + + function stop(msg) { + debug(msg); + window.clearInterval(intervalId); + finishTest(); + } + } +} +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/out-of-vram.html b/dom/canvas/test/webgl-conf/checkout/extra/out-of-vram.html new file mode 100644 index 000000000..16a3d3ef7 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/out-of-vram.html @@ -0,0 +1,135 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Out Of VRAM 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> +<canvas id="canvas" width="2" height="2"> </canvas> +<script> +"use strict"; +debug("This tests WebGL running out of vram."); + +debug(""); +debug("Canvas.getContext"); + +var wtu = WebGLTestUtils; +var canvas = document.getElementById("canvas"); +try { + var gl = wtu.create3DContext(canvas); +} catch(e) { +} +if (!gl) { + testFailed("could not create context"); +} else { + testPassed("context exists"); + + var args = wtu.getUrlArguments(); + + canvas.addEventListener('webglcontextlost', contextLost, false); + + function contextLost(e) { + e.preventDefault(); + debug("***context lost***"); + } + + function contextRestored(e) { + debug("***context restored***"); + } + + var program = wtu.setupTexturedQuad(gl); + gl.useProgram(program); + + debug(""); + debug("Allocating textures."); + + var intervalId; + var count = 0; + var textureMem = 0; + var textures = []; + var size = 2048; + var limit = (args.limit ? args.limit : 8192) * 1024 * 1024; + + debug("limit: " + InMB(limit)) + + function InMB(v) { + return "" + Math.floor(v / 1024 / 1024) + "MB"; + } + + function makeTexture() { + if (gl.isContextLost()) { + stop("out of memory"); + return; + } + ++count; + textureMem += size * size * 4; + if (textureMem > limit) { + stop("reached limit"); + return; + } + debug ("creating texture #" + count + " mem = " + InMB(textureMem)); + var texture = gl.createTexture(); + textures.push(texture); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, + 0, // level + gl.RGBA, // internalFormat + size, // width + size, // height + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + null); // data + var err = gl.getError(); + if (err != gl.NO_ERROR) { + stop("got error: " + wtu.glEnumToString(gl, err)); + return; + } + // use the texture + wtu.clearAndDrawUnitQuad(gl); + } + + intervalId = window.setInterval(makeTexture, 1000 / 15); + +} + +function stop(msg) { + window.clearInterval(intervalId); + testPassed(msg); + finishTest(); +} +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/point-no-attributes-stress.html b/dom/canvas/test/webgl-conf/checkout/extra/point-no-attributes-stress.html new file mode 100644 index 000000000..dcb2a272c --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/point-no-attributes-stress.html @@ -0,0 +1,82 @@ +<!-- + +/* +** Copyright (c) 2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +<script id="vshader" type="x-shader/x-vertex"> +void main() +{ + gl_PointSize = 1.0; + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); +} +</script> + +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; + +void main() +{ + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); +} +</script> +</head> +<body> +<canvas id="testbed" width="1" height="1" style="width: 100px; height: 100px;"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +description('Stress test drawing a huge number of points without enabling any attributes'); + +debug('This test stresses drawing a large number of points and workarounds created to run WebGL with simulated attrib 0'); + +if (confirm('After clicking OK your machine may become unresponsive or crash.')) { + var wtu = WebGLTestUtils; + var gl = wtu.create3DContext('testbed'); + + var program1 = wtu.setupProgram(gl, ['vshader', 'fshader']); + + gl.enable(gl.BLEND); + + debug('Draw 2^31 points with a shader that takes no attributes and verify it fills the whole canvas.'); + + gl.drawArrays(gl.POINTS, 0, Math.pow(2, 31) - 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + wtu.checkCanvas(gl, [0, 255, 0, 255]); +} + +var successfullyParsed = true; +</script> +<script src="../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/program-test-1.html b/dom/canvas/test/webgl-conf/checkout/extra/program-test-1.html new file mode 100644 index 000000000..9cfdfb2bd --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/program-test-1.html @@ -0,0 +1,101 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<!-- This is a visual test that programs must have both a vertex and + fragment shader attached; the fixed function pipeline on the + desktop must remain disabled. --> +<script type="application/javascript"> +function log() { + var s = ""; + for (var i = 0; i < arguments.length; ++i) { + s += arguments[i] + " "; + } + document.getElementById("log").innerHTML += s + "<br>"; +} + +function go() { + var gl = document.getElementById("c").getContext("experimental-webgl"); + + gl.clearColor(0.0, 0.0, 0.0, 0.0); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + var vs = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vs, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex; }"); + gl.compileShader(vs); + + var fs = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fs, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }"); + gl.compileShader(fs); + + var prog = gl.createProgram(); + gl.attachShader(prog, vs); + // don't attach a fragment shader -- may use fixed pipeline on desktop if the implementation doesn't check! + //gl.attachShader(prog, fs); + + gl.bindAttribLocation(prog, 0, "aVertex"); + gl.bindAttribLocation(prog, 1, "aColor"); + + gl.linkProgram(prog); + + var vbuf = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbuf); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + -1.0, -1.0, 0.0, 1.0, + -1.0, 1.0, 0.0, 1.0, + 1.0, -1.0, 0.0, 1.0, + 1.0, 1.0, 0.0, 1.0]), gl.STATIC_DRAW); + gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0); + + var cbuf = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, cbuf); + gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([255, 0, 0, + 0, 255, 0, + 0, 0, 255, + 255, 255, 0]), gl.STATIC_DRAW); + gl.vertexAttribPointer(1, 3, gl.UNSIGNED_BYTE, false, 0, 0); + + gl.enableVertexAttribArray(0); + gl.enableVertexAttribArray(1); + + gl.useProgram(prog); + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + + log("glError", "0x" + gl.getError().toString(16)); +} +</script> +</head> + +<body onload="go()"> +<p>Should be green in the rectangle below:</p> +<canvas style="background: green;" id="c"></canvas> +<div id="log"></div> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/readpixels-after-alert.html b/dom/canvas/test/webgl-conf/checkout/extra/readpixels-after-alert.html new file mode 100644 index 000000000..8c2a7419a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/readpixels-after-alert.html @@ -0,0 +1,86 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Behavior After Alert and Read Pixels Test</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../../devtools/src/debug/webgl-debug.js"></script> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +</head> +<body> +<canvas id="canvas" width="100" height="100"> </canvas> +<div id="description">Verify WebGL behavior after an alert and then a readPixels()</div> +<div id="console"></div> +<script> +"use strict"; + +function checkPixels(buf, width, height, thresh) { + for (var yy = 0; yy < height; ++yy) { + for (var xx = 0; xx < width; ++xx) { + var offset = (yy * width + xx) * 4; + if (Math.abs(buf[offset] - 255) > thresh || + Math.abs(buf[offset + 1] - 0) > thresh || + Math.abs(buf[offset + 2] - 0) > thresh) { + testFailed("Checking pixels"); + return false; + } + } + } + testPassed("Checking pixels"); + return true; +} + +var wtu = WebGLTestUtils; +var gl = wtu.create3DContext("canvas"); +gl.clearColor(1, 0, 0, 1); +gl.clear(gl.COLOR_BUFFER_BIT); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup should succeed"); + +wtu.checkCanvas(gl, [255, 0, 0, 255], undefined, 3); + +alert("Click me to continue"); + +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup should succeed"); +wtu.checkCanvas(gl, [255, 0, 0, 255], undefined, 3); + +alert("Click me to continue"); + +gl.clearColor(1, 0, 0, 1); +gl.clear(gl.COLOR_BUFFER_BIT); +wtu.checkCanvas(gl, [255, 0, 0, 255], undefined, 3); + +debug(""); +var successfullyParsed = true; +</script> +<script src="../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/sample-100.png b/dom/canvas/test/webgl-conf/checkout/extra/sample-100.png Binary files differnew file mode 100644 index 000000000..197c869b6 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/sample-100.png diff --git a/dom/canvas/test/webgl-conf/checkout/extra/sample-200.png b/dom/canvas/test/webgl-conf/checkout/extra/sample-200.png Binary files differnew file mode 100644 index 000000000..89f2b782a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/sample-200.png diff --git a/dom/canvas/test/webgl-conf/checkout/extra/sample-400.png b/dom/canvas/test/webgl-conf/checkout/extra/sample-400.png Binary files differnew file mode 100644 index 000000000..aaee3ce0d --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/sample-400.png diff --git a/dom/canvas/test/webgl-conf/checkout/extra/sample.svg b/dom/canvas/test/webgl-conf/checkout/extra/sample.svg new file mode 100644 index 000000000..dfca52402 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/sample.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> + <rect width="100" height="100" fill="red"/> + <circle cx="50" cy="50" r="50" fill="blue"/> +</svg> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/simulated-attrib-0-bug-test.html b/dom/canvas/test/webgl-conf/checkout/extra/simulated-attrib-0-bug-test.html new file mode 100644 index 000000000..c86ff6eea --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/simulated-attrib-0-bug-test.html @@ -0,0 +1,57 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Simulated Attrib 0 Bug Test</title> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +</head> +<body> +<div>Simulated Attrib 0 Bug Test</div> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +var wtu = WebGLTestUtils; +var context = wtu.create3DContext(); +var program = wtu.loadStandardProgram(context); + +context.useProgram(program); +debug("This line attempts to draw with 0x7FFFFFFF triangles with attrib 0 off"); +debug("A buggy simulated attrib 0 impl will probably mult 0x7FFFFFFF * sizeof(vec4)"); +shouldBe("context.drawArrays(context.TRIANGLES, 0, 0x7fffffff);", "undefined"); +debug("This line attempts to draw with 0x7ffffff triangles."); +debug("A buggy simulated attrib 0 impl will probably pass 0x7FFFFFF0 to glBufferData and then not check that it failed"); +shouldBe("context.drawArrays(context.TRIANGLES, 0, 0x7ffffff);", "undefined"); +debug("") +debug("NOTE!: You may not see any manifestation here. Check your impl for these issues"); +</script> +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/slow-shader-example.html b/dom/canvas/test/webgl-conf/checkout/extra/slow-shader-example.html new file mode 100644 index 000000000..0970a3842 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/slow-shader-example.html @@ -0,0 +1,133 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Slow Shader example.</title> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"> </script> +</head> +<body> +<canvas id="example" width="1024" height="1024" style="width: 40px; height: 40px;"> +</canvas> +<div id="description"></div> +<div id="console"></div> +<script id="slow" type="text/something-not-javascript"> +precision mediump float; +uniform sampler2D tex; +varying vec2 texCoord; +void main() { + gl_FragColor = texture2D(tex, texture2D(tex, texture2D(tex, texCoord).xy).xy); +} +</script> +<script> +"use strict"; +window.onload = main; + +debug("Tests drawing a very slow shader."); +var wtu = WebGLTestUtils; +var canvas = document.getElementById("example"); +canvas.addEventListener("webglcontextlost", function(e) { e.preventDefault(); }, false); +canvas.addEventListener("webglcontextrestored", function(e) { }, false); +var gl = wtu.create3DContext(canvas); +var maxTexSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); +var texSize = Math.min(maxTexSize, 4096); +debug("Max Texture size: " + maxTexSize); +debug("Texture size: " + texSize); +var shaderSource = + document.getElementById("slow").text.replace(/\$size/g, texSize + ".0"); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting a context"); +var program = wtu.setupProgram( + gl, + [wtu.simpleTextureVertexShader, shaderSource], + ['vPosition', 'texCoord0'], + [0, 1]); +wtu.setupUnitQuad(gl, 0, 1); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after program setup"); +var tex = gl.createTexture(); +gl.enable(gl.BLEND); +gl.disable(gl.DEPTH_TEST); + +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture"); +debug("preparing..."); +var numBytes = texSize * texSize * 4; +var pixelBuf = new ArrayBuffer(numBytes); +var pixels = new Uint8Array(pixelBuf); +for (var ii = 0; ii < numBytes; ++ii) { + pixels[ii] = Math.random() * 255; +} +gl.bindTexture(gl.TEXTURE_2D, tex); +gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, + gl.RGBA, gl.UNSIGNED_BYTE, pixels); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture setup"); + +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture param setting"); + +var loc = gl.getUniformLocation(program, "tex"); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting tex location"); +gl.uniform1i(loc, 0); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting tex uniform"); + +var numQuads = 1000; +var indexBuf = new ArrayBuffer(numQuads * 6); +var indices = new Uint8Array(indexBuf); +for (var ii = 0; ii < numQuads; ++ii) { + var offset = ii * 6; + indices[offset + 0] = 0; + indices[offset + 1] = 1; + indices[offset + 2] = 2; + indices[offset + 3] = 3; + indices[offset + 4] = 4; + indices[offset + 5] = 5; +} +var indexBuffer = gl.createBuffer(); +gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); +gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices"); + +function main () { + if (confirm( + "After clicking OK your machine may become unresponsive or crash.")) { + gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing"); + } else { + debug("cancelled"); + } +} + +var successfullyParsed = true; +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.html b/dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.html new file mode 100644 index 000000000..3a20ad236 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.html @@ -0,0 +1,48 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../resources/js-test-style.css"/> +<script src="../js/js-test-pre.js"></script> +<script src="../js/webgl-test-utils.js"></script> +<script src="tex-image-with-video-test.js"></script> +<script> +"use strict"; +function testPrologue(gl) { + return true; +} +</script> +</head> +<body onload='generateTest("RGBA", "UNSIGNED_BYTE", testPrologue)()'> +<canvas id="example" width="32" height="32"></canvas> +<div id="description"></div> +<div id="console"></div> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.js b/dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.js new file mode 100644 index 000000000..e6dd62c9a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.js @@ -0,0 +1,174 @@ +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +// This block needs to be outside the onload handler in order for this +// test to run reliably in WebKit's test harness (at least the +// Chromium port). https://bugs.webkit.org/show_bug.cgi?id=87448 +initTestingHarness(); + +var old = debug; +var debug = function(msg) { + console.log(msg); + old(msg); +}; + +function generateTest(pixelFormat, pixelType, prologue) { + var wtu = WebGLTestUtils; + var gl = null; + var textureLoc = null; + var successfullyParsed = false; + + // Test each format separately because many browsers implement each + // differently. Some might be GPU accelerated, some might not. Etc... + var videos = [ + { src: "../resources/red-green.mp4" , type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', }, + { src: "../resources/red-green.webmvp8.webm", type: 'video/webm; codecs="vp8, vorbis"', }, + { src: "../resources/red-green.webmvp9.webm", type: 'video/webm; codecs="vp9"', }, + { src: "../resources/red-green.theora.ogv", type: 'video/ogg; codecs="theora, vorbis"', }, + ]; + + var videoNdx = 0; + var video; + + function runNextVideo() { + if (video) { + video.pause(); + } + + if (videoNdx == videos.length) { + finishTest(); + return; + } + + var info = videos[videoNdx++]; + debug(""); + debug("testing: " + info.type); + video = document.createElement("video"); + var canPlay = true; + if (!video.canPlayType) { + testFailed("video.canPlayType required method missing"); + runNextVideo(); + return; + } + + if(!video.canPlayType(info.type).replace(/no/, '')) { + debug(info.type + " unsupported"); + runNextVideo(); + return; + }; + + document.body.appendChild(video); + video.type = info.type; + video.crossOrigin = 'anonymous'; + video.src = info.src; + wtu.startPlayingAndWaitForVideo(video, runTest); + } + + var init = function() + { + description('Verify texImage2D and texSubImage2D code paths taking video elements (' + pixelFormat + '/' + pixelType + ')'); + + gl = wtu.create3DContext("example"); + + if (!prologue(gl)) { + finishTest(); + return; + } + + var program = wtu.setupTexturedQuad(gl); + + gl.clearColor(0,0,0,1); + gl.clearDepth(1); + + textureLoc = gl.getUniformLocation(program, "tex"); + runNextVideo(); + } + + function runOneIteration(videoElement, useTexSubImage2D, flipY, topColor, bottomColor) + { + debug('Testing ' + (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') + + ' with flipY=' + flipY); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + // Disable any writes to the alpha channel + gl.colorMask(1, 1, 1, 0); + var texture = gl.createTexture(); + // Bind the texture to texture unit 0 + gl.bindTexture(gl.TEXTURE_2D, texture); + // Set up texture parameters + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + 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); + // Set up pixel store parameters + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + // Upload the videoElement into the texture + if (useTexSubImage2D) { + // Initialize the texture to black first + gl.texImage2D(gl.TEXTURE_2D, 0, gl[pixelFormat], + videoElement.videoWidth, videoElement.videoHeight, 0, + gl[pixelFormat], gl[pixelType], null); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl[pixelFormat], gl[pixelType], videoElement); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl[pixelFormat], gl[pixelFormat], gl[pixelType], videoElement); + } + + var c = document.createElement("canvas"); + c.width = 16; + c.height = 16; + c.style.border = "1px solid black"; + var ctx = c.getContext("2d"); + ctx.drawImage(videoElement, 0, 0, 16, 16); + document.body.appendChild(c); + + // Point the uniform sampler to texture unit 0 + gl.uniform1i(textureLoc, 0); + // Draw the triangles + wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); + // Check a few pixels near the top and bottom and make sure they have + // the right color. + var tolerance = 5; + debug("Checking lower left corner"); + wtu.checkCanvasRect(gl, 4, 4, 2, 2, bottomColor, + "shouldBe " + bottomColor, tolerance); + debug("Checking upper left corner"); + wtu.checkCanvasRect(gl, 4, gl.canvas.height - 8, 2, 2, topColor, + "shouldBe " + topColor, tolerance); + } + + function runTest(videoElement) + { + var red = [255, 0, 0]; + var green = [0, 255, 0]; + runOneIteration(videoElement, false, true, red, green); + runOneIteration(videoElement, false, false, green, red); + runOneIteration(videoElement, true, true, red, green); + runOneIteration(videoElement, true, false, green, red); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors"); + + runNextVideo(); + } + + return init; +} diff --git a/dom/canvas/test/webgl-conf/checkout/extra/texture-allocation-stress-test.html b/dom/canvas/test/webgl-conf/checkout/extra/texture-allocation-stress-test.html new file mode 100644 index 000000000..2c423e02a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/texture-allocation-stress-test.html @@ -0,0 +1,68 @@ +<!-- + +/* +** Copyright (c) 2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Tests that resources allocated by a WebGL context are freed in a reasonable timeframe.</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="32" height="32"> +</canvas> +<script> +"use strict"; +description(); + +debug("Creates a WebGL context and textures consuming ~80 MB of video memory, then reloads the page and does it over again.") +debug("GPU memory usage should be capped. It should not grow unboundedly.") + +var wtu = WebGLTestUtils; + +var gl = wtu.create3DContext(document.getElementById("canvas")); +var textures = []; + +for (var ii = 0; ii < 20; ++ii) { + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1024, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE, + null); + textures.push(tex); +} + +setTimeout(function() { debug("Reloading..."); window.location.reload(); }, 500); + +var successfullyParsed = true; +</script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/texture-sizing.html b/dom/canvas/test/webgl-conf/checkout/extra/texture-sizing.html new file mode 100644 index 000000000..4cdcf64a1 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/texture-sizing.html @@ -0,0 +1,250 @@ +<!-- + +/* +** Copyright (c) 2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> +<!DOCTYPE html> +<html> +<head> +<title>Testing resolution of texture uploads</title> +<style> + +.result { + margin-bottom: 20px; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; +} + +.description, .element, .render, .log { + border: 1px solid black; + margin: 5px; + width: 200px; + height: 200px; + max-width: 200px; + max-height: 200px; +} + +.render canvas { + width: 200px; + height: 200px; +} + +p { + margin: 0; + padding: 5px 10px; +} +.viacss { + width: 200px; + height: 200px; +} +</style> +<script src="../js/webgl-test-utils.js"> </script> +<script> + +var outOfPageSVG = new Image(); +outOfPageSVG.src = "sample.svg"; + +function runTest() { + var wtu = WebGLTestUtils; + var results = document.querySelectorAll(".result"); + for (var i = 0; i < results.length; i++) { + var result = results[i]; + var img = result.querySelector("img"); + if (result.classList.contains("out-of-page")) { + img = outOfPageSVG; + } + if (result.classList.contains("set-dimensions")) { + img.width = 200; + img.height = 200; + } + var out = result.querySelector(".output"); + out.innerHTML = "img.width = " + img.width + "<br>img.height = " + img.height + "<br>img.naturalWidth = " + img.naturalWidth + "<br>img.naturalHeight = " + img.naturalHeight; + + var canvas = document.createElement("canvas"); + canvas.width = 200 * window.devicePixelRatio; + canvas.height = 200 * window.devicePixelRatio; + result.querySelector(".render").appendChild(canvas); + var gl = wtu.create3DContext(canvas); + gl.enable(gl.BLEND); + gl.disable(gl.DEPTH_TEST); + + var program = wtu.setupSimpleTextureProgram(gl, 0, 1); + var buffers = wtu.setupUnitQuad(gl, 0, 1); + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + 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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); + var loc = gl.getUniformLocation(program, "tex"); + gl.uniform1i(loc, 0); + + wtu.clearAndDrawUnitQuad(gl, [0, 255, 0, 255]); + } +} + +window.addEventListener("load", function () { + runTest(); +}, false); +</script> +</head> +<body> +<div class="result"> + <div class="description"> + <p>IMG to SVG with 200x200 attributes</p> + </div> + <div class="element"> + <img src="sample.svg" width="200" height="200"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p>IMG to 100x100 PNG with 200x200 attributes</p> + </div> + <div class="element"> + <img src="sample-100.png" width="200" height="200"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p>IMG to 200x200 PNG with 200x200 attributes</p> + </div> + <div class="element"> + <img src="sample-200.png" width="200" height="200"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p>IMG to 400x400 PNG with 200x200 attributes</p> + </div> + <div class="element"> + <img src="sample-400.png" width="200" height="200"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p>IMG SRCSET to multiple PNGs with 200x200 attributes</p> + </div> + <div class="element"> + <img src="sample-100.png" srcset="sample-200.png 1x, sample-400.png 2x" width="200" height="200"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p>IMG to SVG with no attributes - 200x200 sizing via CSS</p> + </div> + <div class="element"> + <img src="sample.svg" class="viacss"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p>IMG to 400x400 PNG with no attributes - 200x200 sizing via CSS</p> + </div> + <div class="element"> + <img src="sample-400.png" class="viacss"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result"> + <div class="description"> + <p> + IMG to SVG with no attributes and no sizing via CSS<br> + (although the width and height of the container set a size) + </p> + </div> + <div class="element"> + <img src="sample.svg"> + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result out-of-page"> + <div class="description"> + <p>Out of page SVG with no dimensions</p> + </div> + <div class="element"> + Not a child of document + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> +<div class="result out-of-page set-dimensions"> + <div class="description"> + <p>Out of page SVG with 200x200 specified</p> + </div> + <div class="element"> + Not a child of document + </div> + <div class="render"> + </div> + <div class="log"> + <p class="output"></p> + </div> +</div> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/webgl-drawelements-validation.html b/dom/canvas/test/webgl-conf/checkout/extra/webgl-drawelements-validation.html new file mode 100644 index 000000000..74f15608a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/webgl-drawelements-validation.html @@ -0,0 +1,163 @@ +<!-- + +/* +** Copyright (c) 2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<title>Micro-benchmark for WebGL drawElements index validation</title> +<style> +canvas { + border: 1px solid #000; +} +</style> +<script src="../js/webgl-test-utils.js"></script> +<script type="application/javascript"> +"use strict"; + +var wtu = WebGLTestUtils; + +var totalTimeTest1 = 0; +var totalTimeTest2 = 0; +var totalTimeTest3 = 0; +var iterationsLeft = 10; // How many times to run the full test. +var indexCount = 500001; // Divisible by 3. + +var indices = []; +for (var i = 0; i < indexCount - 1; ++i) { + indices.push(0); + indices.push(1); + indices.push(2); + indices.push(3); +} +indices.push(4); + +var fullIndicesArray = new Uint16Array(indices); + +var drawIterations = 50; + +var errorsCorrect = true; + +var log = function(msg) { + console.log(msg); + var p = document.createElement('p'); + p.textContent = msg; + document.body.appendChild(p); +}; + +var runTestIteration = function() { + var canvas = document.createElement('canvas'); + canvas.width = 10; + canvas.height = 10; + var gl = wtu.create3DContext(canvas); + document.body.appendChild(canvas); + + var location = 0; + wtu.setupSimpleColorProgram(gl, location); + + var verts = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, verts); + var vertData = new Float32Array([-1, -1, + -1, 1, + 1, -1, + 1, 1]); + gl.bufferData(gl.ARRAY_BUFFER, vertData, gl.STATIC_DRAW); + gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(location); + + var indexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, fullIndicesArray, gl.DYNAMIC_DRAW); + gl.finish(); + + var measureTime = function(f) { + var startTime = new Date().getTime(); + f(); + var error = gl.getError(); + var endTime = new Date().getTime(); + errorsCorrect = errorsCorrect && error == gl.INVALID_OPERATION; + return endTime - startTime; + }; + + // The buffer has at least one out-of-range index from the start, + // so only validation will happen, not drawing. + + totalTimeTest1 += measureTime(function() { + for (var i = 0; i < drawIterations; ++i) { + // Change all data, which will cause complete revalidation of the index buffer. + gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, fullIndicesArray); + gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); + } + }); + + totalTimeTest2 += measureTime(function() { + for (var i = 0; i < drawIterations; ++i) { + // Change only one index and vary the amount of referenced indices. + // These should not be a big problem to a smart implementation. + gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, Math.floor(indices.length / 2), new Uint16Array([i + 5])); + gl.drawElements(gl.TRIANGLES, indices.length - i * 3, gl.UNSIGNED_SHORT, 0); + } + }); + + totalTimeTest3 += measureTime(function() { + for (var i = 0; i < drawIterations; ++i) { + // Change data at two indices to cause completely revalidating the index buffer in + // current implementations in Chrome and Firefox (as of March 17th 2014). + gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([i + 5])); + gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, indices.length - 1, new Uint16Array([i + 5])); + gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); + } + }); + + setTimeout(function() { + var lose = gl.getExtension('WEBGL_lose_context'); + lose.loseContext(); + }, 40); +}; + +var runTest = function() { + if (iterationsLeft > 0) { + runTestIteration(); + --iterationsLeft; + setTimeout(runTest, 500); + } else { + log("Validation returned correct results: " + errorsCorrect); + log('1. Time spent on full buffer updates: ' + totalTimeTest1 + ' ms'); + log('Indices uploaded and referenced by draw calls processed: ' + Math.round(indices.length * drawIterations / totalTimeTest1) + ' / ms'); + log('2. Time spent on validating single index updates while range referenced also changes on every draw call: ' + totalTimeTest2 + ' ms'); + log('Indices referenced by draw calls handled: ' + Math.round(indices.length * drawIterations / totalTimeTest2) + ' / ms'); + log('3. Time spent on validating single index updates at each end of the buffer (worst case for Firefox implementation as of March 2014, not reflective of real world performance): ' + totalTimeTest3 + ' ms'); + log('Indices referenced by draw calls handled: ' + Math.round(indices.length * drawIterations / totalTimeTest3) + ' / ms'); + } +}; +</script> +</head> +<body onload="setTimeout(runTest, 100)"> +<h1>Micro-benchmark for WebGL drawElements index validation</h1> +<p>Note that these test cases are completely artificial, and their results only very rough indicators of the performance of a specific part of the system.</p> +<p>The benchmark does not perform any drawing, but rather measures the time the browser takes to upload indices and to check if there are out-of-range indices.</p> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/extra/webgl-info.html b/dom/canvas/test/webgl-conf/checkout/extra/webgl-info.html new file mode 100644 index 000000000..86b4d0c05 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/webgl-info.html @@ -0,0 +1,296 @@ +<!-- + +/* +** Copyright (c) 2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Information</title> +<style type="text/css"> +th, td { + padding: 4pt; +} +th { + text-align: right; + min-width: 22em; +} +</style> +<script src="../js/webgl-test-utils.js"> </script> +<script> +"use strict"; +window.onload = main; + +function createCell(txt, isTh) { + var str = txt.toString(); + if (typeof txt != 'string') { + if (txt.length !== undefined) { + str = ""; + for (var ii = 0; ii < txt.length; ++ii) { + str += (ii == 0 ? "" : ", ") + txt[ii]; + } + } + } + var t = document.createTextNode(str); + var d = document.createElement("div"); + var td; + if (isTh) { + td = document.createElement("th"); + } else { + td = document.createElement("td"); + } + d.appendChild(t); + td.appendChild(d); + return td; +} + +function createRow(values) { + var tr = document.createElement("tr"); + for (var i = 0; i < values.length; ++i) { + var td = createCell(values[i], i == 0); + tr.appendChild(td); + } + return tr; +} + +function main() { + var wtu = WebGLTestUtils; + + var canvas = document.getElementById("example"); + var gl = wtu.create3DContext(canvas); + if (!gl) { + return; + } + + var debugRendererInfoRows = function() { + var rows = []; + var debugExt = wtu.getExtensionWithKnownPrefixes(gl, 'WEBGL_debug_renderer_info'); + if (debugExt) { + var extPnames = [ + 'UNMASKED_VENDOR_WEBGL', + 'UNMASKED_RENDERER_WEBGL' + ]; + for (var ii = 0; ii < extPnames.length; ++ii) { + var pname = extPnames[ii]; + var value = gl.getParameter(debugExt[pname]); + rows.push([pname, value]); + } + } + return rows; + }; + + var precisionRows = function() { + var rows = []; + + var addPrecisionRow = function(shaderType, precision) { + var typeStr = shaderType === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex'; + var precisionStr = 'highp'; + if (precision == gl.MEDIUM_FLOAT) { + precisionStr = 'mediump'; + } else if (precision == gl.LOW_FLOAT) { + precisionStr = 'lowp'; + } + rows.push([typeStr + ' shader ' + precisionStr + ' float', gl.getShaderPrecisionFormat(shaderType, precision).precision + ' mantissa bits']); + }; + + var fSource = 'precision highp float; uniform float r; void main() { gl_FragColor = vec4(r, 0.0, 0.0, 1.0); }' + var f = wtu.loadShader(gl, fSource, gl.FRAGMENT_SHADER); + if (!f) { + rows.push(['fragment shader highp float', 'not supported']); + } else { + addPrecisionRow(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); + } + addPrecisionRow(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT); + addPrecisionRow(gl.FRAGMENT_SHADER, gl.LOW_FLOAT); + addPrecisionRow(gl.VERTEX_SHADER, gl.HIGH_FLOAT); + addPrecisionRow(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT); + addPrecisionRow(gl.VERTEX_SHADER, gl.LOW_FLOAT); + return rows; + }; + + var renderTargetRows = function() { + var rows = []; + var oesTextureFloat = wtu.getExtensionWithKnownPrefixes(gl, 'OES_texture_float'); + var oesTextureHalfFloat = wtu.getExtensionWithKnownPrefixes(gl, 'OES_texture_half_float'); + var formatsToTest = [ + { + description: 'RGBA UNSIGNED_BYTE', + format: gl.RGBA, + type: gl.UNSIGNED_BYTE + }, + { + description: 'RGB UNSIGNED_BYTE', + format: gl.RGB, + type: gl.UNSIGNED_BYTE + } + ]; + if (oesTextureFloat) { + formatsToTest.push({ + description: 'RGBA FLOAT', + format: gl.RGBA, + type: gl.FLOAT + }); + formatsToTest.push({ + description: 'RGB FLOAT (deprecated)', + format: gl.RGB, + type: gl.FLOAT + }); + } + if (oesTextureHalfFloat) { + formatsToTest.push({ + description: 'RGBA HALF_FLOAT_OES', + format: gl.RGBA, + type: oesTextureHalfFloat.HALF_FLOAT_OES + }); + formatsToTest.push({ + description: 'RGB HALF_FLOAT_OES', + format: gl.RGB, + type: oesTextureHalfFloat.HALF_FLOAT_OES + }); + } + for (var ii = 0; ii < formatsToTest.length; ++ii) { + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + var format = formatsToTest[ii]; + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + 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.texImage2D(gl.TEXTURE_2D, 0, format.format, 256, 256, 0, format.format, format.type, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { + rows.push([format.description, 'supported']); + } else { + rows.push([format.description, 'not supported']); + } + gl.deleteFramebuffer(fb); + gl.deleteTexture(tex); + } + return rows; + }; + + var info = [ + { + title: 'Renderer', + pnames: [ + 'VERSION', + 'VENDOR', + 'RENDERER' + ], + genRows: debugRendererInfoRows + }, + { + title: 'Textures and Viewport', + pnames: [ + 'MAX_TEXTURE_SIZE', + 'MAX_CUBE_MAP_TEXTURE_SIZE', + 'MAX_RENDERBUFFER_SIZE', + 'MAX_VIEWPORT_DIMS' + ] + }, + { + title: 'Shader Variables', + pnames: [ + 'MAX_VARYING_VECTORS', + 'MAX_VERTEX_ATTRIBS', + 'MAX_VERTEX_UNIFORM_VECTORS', + 'MAX_FRAGMENT_UNIFORM_VECTORS', + 'MAX_VERTEX_TEXTURE_IMAGE_UNITS', + 'MAX_TEXTURE_IMAGE_UNITS', + 'MAX_COMBINED_TEXTURE_IMAGE_UNITS' + ] + }, + { + title: 'Shader Precision', + genRows: precisionRows + }, + { + title: 'Framebuffer Texture Attachment Support', + genRows: renderTargetRows + } + ]; + + // TODO: max anisotropy, framebuffer depth bits, MSAA samples, max multiple render targets buffers, point size, line width + + for (var jj = 0; jj < info.length; ++jj) { + var table = document.createElement("table"); + var tb = document.createElement("tbody"); + if (info[jj].pnames) { + var pnames = info[jj].pnames; + for (var ii = 0; ii < pnames.length; ++ii) { + var pname = pnames[ii]; + var value = gl.getParameter(gl[pname]); + tb.appendChild(createRow([pname, value])); + } + } + if (info[jj].genRows) { + var genRows = info[jj].genRows(); + for (var ii = 0; ii < genRows.length; ++ii) { + tb.appendChild(createRow(genRows[ii])); + } + } + table.appendChild(tb); + var header = document.createElement("h2"); + header.textContent = info[jj].title; + document.getElementById("info").appendChild(header); + document.getElementById("info").appendChild(table); + } + var extensionList = document.createElement('ul'); + var exts = gl.getSupportedExtensions(); + var extsWithPrefixes = []; + while (exts.length > 0) { + var prefixedNames = wtu.getExtensionPrefixedNames(exts[0]); + var supportedPrefixedNames = []; + for (var ii = 0; ii < prefixedNames.length; ++ii) { + var index = exts.indexOf(prefixedNames[ii]); + if (index >= 0) { + supportedPrefixedNames.push(exts[index]); + exts.splice(index, 1); + } + } + extsWithPrefixes.push(supportedPrefixedNames.join(" / ")); + } + extsWithPrefixes.sort(); + for (var ii = 0; ii < extsWithPrefixes.length; ++ii) { + var li = document.createElement('li'); + li.appendChild(document.createTextNode(extsWithPrefixes[ii])); + extensionList.appendChild(li); + } + document.getElementById('extensions').appendChild(extensionList); +} +</script> +</head> +<body> +<h1>WebGL Info</h1> +<div id="info"></div> +<h2>WebGL Extensions</h2> +<div id="extensions"></div> +<canvas id="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas> +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/extra/webgl-translate-shader.html b/dom/canvas/test/webgl-conf/checkout/extra/webgl-translate-shader.html new file mode 100644 index 000000000..2cccd47ea --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/extra/webgl-translate-shader.html @@ -0,0 +1,171 @@ +<!-- + +/* +** Copyright (c) 2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Shader Translator</title> +<style> +textarea { + min-width: 70%; + min-height: 200px; + font-family: monospace; + background: #def; +} +#disabled { + color: red; + font-weight: bold; +} +</style> +<script> +// Needed by wtu.create3DContext(): +var testFailed = function() {}; +</script> +<script src="../js/webgl-test-utils.js"> </script> +<script> +"use strict"; +window.onload = main; + +var gl; +var debugShaders; +var enabledExtensions = []; + +var translateButton; +var extButton; + +function main() { + translateButton = document.getElementById('translate'); + extButton = document.getElementById('getExts'); + + var canvas = document.getElementById("example"); + var wtu = WebGLTestUtils; + gl = wtu.create3DContext(canvas); + if (!gl) { + disable(); + return; + } + + debugShaders = gl.getExtension('WEBGL_debug_shaders'); + if (!debugShaders) { + disable(); + } +} + +function disable() { + translateButton.disabled = true; + extButton.disabled = true; + document.getElementById('disabled').style.display = 'block'; +} + +function getExtensions() { + getExtensionSet([ + 'EXT_frag_depth', + 'EXT_shader_texture_lod', + 'OES_standard_derivatives', + 'WEBGL_draw_buffers' + ]); +} + +function getExtensionSet(shaderExtensions) { + for (var i = 0; i < shaderExtensions.length; ++i) { + if (enabledExtensions.indexOf(shaderExtensions[i]) < 0) { + var ext = gl.getExtension(shaderExtensions[i]); + if (ext) { + enabledExtensions.push(shaderExtensions[i]); + } + } + } + if (enabledExtensions.length > 0) { + document.getElementById('enabled-extensions').textContent = enabledExtensions.join(', '); + } +} + +function translateShader() { + var sourceElement = document.getElementById('original-shader'); + var source = sourceElement.value; + + var output = document.getElementById('translated-shader'); + var infoLog = document.getElementById('info-log'); + var shaderType = document.getElementById('shader-type'); + infoLog.value = ''; + + // Try compiling the source as both vertex and fragment shader and see if either one works + var tryCompile = function(type) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + var shaderTypeStr; + if (type == gl.FRAGMENT_SHADER) { + shaderTypeStr = 'Fragment shader'; + } else { + shaderTypeStr = 'Vertex shader'; + } + if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + shaderType.textContent = shaderTypeStr; + var translatedSource = debugShaders.getTranslatedShaderSource(shader); + output.value = translatedSource; + infoLog.value = gl.getShaderInfoLog(shader); + return true; + } else { + infoLog.value += 'Info log when compiling as ' + shaderTypeStr + ':\n' + gl.getShaderInfoLog(shader) + '\n'; + return false; + } + } + + if (!tryCompile(gl.FRAGMENT_SHADER) && !tryCompile(gl.VERTEX_SHADER)) { + output.value = 'Invalid shader, compilation failed as both fragment and vertex shader.'; + shaderType.textContent = 'Shader not'; + } +} +</script> +</head> +<body> +<h1>WebGL Shader Translator</h1> +<p>This page uses the browser's built-in shader translation facilities to show how a shader +is changed before being passed on to the underlying platform's graphics driver.</p> +<p id="disabled" style="display: none;"> + WebGL or WEBGL_debug_shaders extension is not available on this browser configuration. + Use a different browser or look for other alternatives to enable the extension to be able to use this page. + The extension might be behind a runtime flag for privacy considerations. +</p> +<h2>WebGL GLSL shader</h2> +<textarea id="original-shader"></textarea> +<p> +<input type="button" id="translate" value="Translate" onclick="translateShader()"></input> +<input type="button" id="getExts" value="Enable supported GLSL extensions" onclick="getExtensions()"></input> +</p> +<h2><span id="shader-type">Shader</span> translated for graphics driver</h2> +<textarea id="translated-shader"></textarea> +<h2>Enabled shader extensions</h2> +<p id="enabled-extensions">None</p> +<h2>Shader info log</h2> +<textarea id="info-log"></textarea> +<canvas id="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas> +</body> +</html> + |