diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html new file mode 100644 index 0000000000..31d07a94a9 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html @@ -0,0 +1,379 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<script> +"use strict"; +var wtu; +var canvas; +var gl; +var shouldGenerateGLError; +var extensionName; +var extension; + +var buffer; +var framebuffer; +var program; +var renderbuffer; +var shader; +var texture; +var uniformLocation; +var arrayBuffer; +var arrayBufferView +var image; +var video; +var canvas2d; +var ctx2d; +var imageData; +var float32array; +var int32array; +var OES_vertex_array_object; +var vertexArrayObject; + +var secondCanvas; +var secondGL; + +function init() +{ + wtu = WebGLTestUtils; + canvas = document.getElementById("canvas"); + gl = wtu.create3DContext(canvas); + secondCanvas = document.getElementById("canvas2"); + secondGL = wtu.create3DContext(secondCanvas); + shouldGenerateGLError = wtu.shouldGenerateGLError; + + description("Tests behavior under a lost context"); + + // call testValidContext() before checking for the extension, because this is where we check + // for the isContextLost() method, which we want to do regardless of the extension's presence. + testValidContext(); + + extensionName = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_lose_context"); + if (!extensionName) { + debug("Could not find WEBGL_lose_context extension"); + finishTest(); + return false; + } + extension = gl.getExtension(extensionName); + + // need an extension that exposes new API methods. + OES_vertex_array_object = wtu.getExtensionWithKnownPrefixes(gl, "OES_vertex_array_object"); + + canvas.addEventListener("webglcontextlost", testLostContext, false); + + // We need to initialize |uniformLocation| before losing context. + // Otherwise gl.getUniform() when context is lost will throw. + uniformLocation = gl.getUniformLocation(program, "tex"); + loseContext(); +} + +function loseContext() +{ + debug(""); + debug("Lose context"); + + // Note: this will cause the context to be lost, but the + // webglcontextlost event listener to be queued. + extension.loseContext(); + debug(""); +} + +function testValidContext() +{ + debug("Test valid context"); + + shouldBeFalse("gl.isContextLost()"); + + arrayBuffer = new ArrayBuffer(4); + arrayBufferView = new Int8Array(arrayBuffer); + + // Generate resources for testing. + buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + program = wtu.setupSimpleTextureProgram(gl); + renderbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); + shader = gl.createShader(gl.VERTEX_SHADER); + texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + shouldBe("gl.getError()", "gl.NO_ERROR"); + + // Test is queries that will later be false + shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enable(gl.BLEND)"); + shouldBeTrue("gl.isBuffer(buffer)"); + shouldBeTrue("gl.isEnabled(gl.BLEND)"); + shouldBeTrue("gl.isFramebuffer(framebuffer)"); + shouldBeTrue("gl.isProgram(program)"); + shouldBeTrue("gl.isRenderbuffer(renderbuffer)"); + shouldBeTrue("gl.isShader(shader)"); + shouldBeTrue("gl.isTexture(texture)"); + + if (OES_vertex_array_object) { + vertexArrayObject = OES_vertex_array_object.createVertexArrayOES(); + shouldBe("gl.getError()", "gl.NO_ERROR"); + shouldBeTrue("OES_vertex_array_object.isVertexArrayOES(vertexArrayObject)"); + } +} + +function testGLNOErrorFunctions(tests) { + tests.forEach(function(test) { + shouldGenerateGLError(gl, gl.NO_ERROR, test); + }); +} + +function testFunctionsThatReturnNULL(tests) { + tests.forEach(function(test) { + shouldBeNull(test); + }); +} + +function testUploadingLostContextToTexture() { + debug("Testing uploading a canvas with a lost WebGL context to a texture"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at beginning"); + let texture = secondGL.createTexture(); + secondGL.bindTexture(secondGL.TEXTURE_2D, texture); + secondGL.texImage2D(secondGL.TEXTURE_2D, 0, secondGL.RGBA, secondGL.RGBA, secondGL.UNSIGNED_BYTE, canvas); + wtu.glErrorShouldBe(secondGL, [secondGL.INVALID_OPERATION, secondGL.NO_ERROR], "Should not crash when uploading canvas with lost WebGL context to a texture"); +} + +function testLostContext() +{ + debug("Test lost context"); + + // Functions with special return values. + shouldBeTrue("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED"); + shouldBe("gl.getAttribLocation(program, 'u_modelViewProjMatrix')", "-1"); + shouldBe("gl.getVertexAttribOffset(0, gl.VERTEX_ATTRIB_ARRAY_POINTER)", "0"); + + // Attempt resize of lost context should succeed, still lost. + gl.canvas.width = gl.canvas.width; // Try to hit any same-size resize path. + shouldBeTrue("gl.isContextLost()"); + + const newSize = gl.canvas.width + 1; + gl.canvas.width = newSize; + shouldBe("gl.canvas.width", newSize); + shouldBeTrue("gl.isContextLost()"); + + // Test the extension itself. + shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.loseContext()"); + + image = document.createElement("img"); + video = document.createElement("video"); + canvas2d = document.createElement("canvas"); + ctx2d = canvas2d.getContext("2d"); + imageData = ctx2d.createImageData(1, 1); + float32array = new Float32Array(1); + int32array = new Int32Array(1); + + // Functions returning void should return immediately. + // This is untestable, but we can at least be sure they cause no errors + // and the codepaths are exercised. + var voidTests = [ + "gl.activeTexture(gl.TEXTURE0)", + "gl.attachShader(program, shader)", + "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)", + "gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)", + "gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer)", + "gl.bindTexture(gl.TEXTURE_2D, texture)", + "gl.blendColor(1.0, 1.0, 1.0, 1.0)", + "gl.blendEquation(gl.FUNC_ADD)", + "gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD)", + "gl.blendFunc(gl.ONE, gl.ONE)", + "gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE)", + "gl.bufferData(gl.ARRAY_BUFFER, 0, gl.STATIC_DRAW)", + "gl.bufferData(gl.ARRAY_BUFFER, arrayBufferView, gl.STATIC_DRAW)", + "gl.bufferData(gl.ARRAY_BUFFER, arrayBuffer, gl.STATIC_DRAW)", + "gl.bufferSubData(gl.ARRAY_BUFFRE, 0, arrayBufferView)", + "gl.bufferSubData(gl.ARRAY_BUFFRE, 0, arrayBuffer)", + "gl.clear(gl.COLOR_BUFFER_BIT)", + "gl.clearColor(1, 1, 1, 1)", + "gl.clearDepth(1)", + "gl.clearStencil(0)", + "gl.colorMask(1, 1, 1, 1)", + "gl.compileShader(shader)", + "gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, 0, 0)", + "gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 0, 0)", + "gl.cullFace(gl.FRONT)", + "gl.deleteBuffer(buffer)", + "gl.deleteFramebuffer(framebuffer)", + "gl.deleteProgram(program)", + "gl.deleteRenderbuffer(renderbuffer)", + "gl.deleteShader(shader)", + "gl.deleteTexture(texture)", + "gl.depthFunc(gl.NEVER)", + "gl.depthMask(0)", + "gl.depthRange(0, 1)", + "gl.detachShader(program, shader)", + "gl.disable(gl.BLEND)", + "gl.disableVertexAttribArray(0)", + "gl.drawArrays(gl.POINTS, 0, 0)", + "gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_SHORT, 0)", + "gl.enable(gl.BLEND)", + "gl.enableVertexAttribArray(0)", + "gl.finish()", + "gl.flush()", + "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer)", + "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)", + "gl.frontFace(gl.CW)", + "gl.generateMipmap(gl.TEXTURE_2D)", + "gl.hint(gl.GENERATE_MIPMAP_HINT, gl.FASTEST)", + "gl.lineWidth(0)", + "gl.linkProgram(program)", + "gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0)", + "gl.polygonOffset(0, 0)", + "gl.readPixels(0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)", + "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0)", + "gl.sampleCoverage(0, 0)", + "gl.scissor(0, 0, 0, 0)", + "gl.shaderSource(shader, '')", + "gl.stencilFunc(gl.NEVER, 0, 0)", + "gl.stencilFuncSeparate(gl.FRONT, gl.NEVER, 0, 0)", + "gl.stencilMask(0)", + "gl.stencilMaskSeparate(gl.FRONT, 0)", + "gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP)", + "gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.KEEP)", + "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)", + "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageData)", + "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)", + "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d)", + "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video)", + "gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)", + "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)", + "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)", + "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData)", + "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image)", + "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d)", + "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video)", + "gl.uniform1f(uniformLocation, 0)", + "gl.uniform1fv(uniformLocation, float32array)", + "gl.uniform1fv(uniformLocation, [0])", + "gl.uniform1i(uniformLocation, 0)", + "gl.uniform1iv(uniformLocation, int32array)", + "gl.uniform1iv(uniformLocation, [0])", + "gl.uniform2f(uniformLocation, 0, 0)", + "gl.uniform2fv(uniformLocation, float32array)", + "gl.uniform2fv(uniformLocation, [0, 0])", + "gl.uniform2i(uniformLocation, 0, 0)", + "gl.uniform2iv(uniformLocation, int32array)", + "gl.uniform2iv(uniformLocation, [0, 0])", + "gl.uniform3f(uniformLocation, 0, 0, 0)", + "gl.uniform3fv(uniformLocation, float32array)", + "gl.uniform3fv(uniformLocation, [0, 0, 0])", + "gl.uniform3i(uniformLocation, 0, 0, 0)", + "gl.uniform3iv(uniformLocation, int32array)", + "gl.uniform3iv(uniformLocation, [0, 0, 0])", + "gl.uniform4f(uniformLocation, 0, 0, 0, 0)", + "gl.uniform4fv(uniformLocation, float32array)", + "gl.uniform4fv(uniformLocation, [0, 0, 0, 0])", + "gl.uniform4i(uniformLocation, 0, 0, 0, 0)", + "gl.uniform4iv(uniformLocation, int32array)", + "gl.uniform4iv(uniformLocation, [0, 0, 0, 0])", + "gl.uniformMatrix2fv(uniformLocation, false, float32array)", + "gl.uniformMatrix2fv(uniformLocation, false, [0, 0, 0, 0])", + "gl.uniformMatrix3fv(uniformLocation, false, float32array)", + "gl.uniformMatrix3fv(uniformLocation, false, [0, 0, 0, 0, 0, 0, 0, 0, 0])", + "gl.uniformMatrix4fv(uniformLocation, false, float32array)", + "gl.uniformMatrix4fv(uniformLocation, false, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])", + "gl.useProgram(program)", + "gl.validateProgram(program)", + "gl.vertexAttrib1f(0, 0)", + "gl.vertexAttrib1fv(0, float32array)", + "gl.vertexAttrib1fv(0, [0])", + "gl.vertexAttrib2f(0, 0, 0)", + "gl.vertexAttrib2fv(0, float32array)", + "gl.vertexAttrib2fv(0, [0, 0])", + "gl.vertexAttrib3f(0, 0, 0, 0)", + "gl.vertexAttrib3fv(0, float32array)", + "gl.vertexAttrib3fv(0, [0, 0, 0])", + "gl.vertexAttrib4f(0, 0, 0, 0, 0)", + "gl.vertexAttrib4fv(0, float32array)", + "gl.vertexAttrib4fv(0, [0, 0, 0, 0])", + "gl.vertexAttribPointer(0, 0, gl.FLOAT, false, 0, 0)", + "gl.viewport(0, 0, 0, 0)", + ]; + testGLNOErrorFunctions(voidTests); + + // Functions return nullable values should all return null. + var nullTests = [ + "gl.createBuffer()", + "gl.createFramebuffer()", + "gl.createProgram()", + "gl.createRenderbuffer()", + "gl.createShader(gl.GL_VERTEX_SHADER)", + "gl.createTexture()", + "gl.getActiveAttrib(program, 0)", + "gl.getActiveUniform(program, 0)", + "gl.getAttachedShaders(program)", + "gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE)", + "gl.getContextAttributes()", + "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", + "gl.getParameter(gl.CURRENT_PROGRAM)", + "gl.getProgramInfoLog(program)", + "gl.getProgramParameter(program, gl.LINK_STATUS)", + "gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH)", + "gl.getShaderInfoLog(shader)", + "gl.getShaderParameter(shader, gl.SHADER_TYPE)", + "gl.getShaderSource(shader)", + "gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S)", + "gl.getUniform(program, uniformLocation)", + "gl.getUniformLocation(program, 'vPosition')", + "gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", + "gl.getSupportedExtensions()", + "gl.getExtension('" + extensionName + "')", + ]; + testFunctionsThatReturnNULL(nullTests); + + // "Is" queries should all return false. + shouldBeFalse("gl.isBuffer(buffer)"); + shouldBeFalse("gl.isEnabled(gl.BLEND)"); + shouldBeFalse("gl.isFramebuffer(framebuffer)"); + shouldBeFalse("gl.isProgram(program)"); + shouldBeFalse("gl.isRenderbuffer(renderbuffer)"); + shouldBeFalse("gl.isShader(shader)"); + shouldBeFalse("gl.isTexture(texture)"); + + shouldBe("gl.getError()", "gl.NO_ERROR"); + + // test extensions + if (OES_vertex_array_object) { + testGLNOErrorFunctions( + [ + "OES_vertex_array_object.bindVertexArrayOES(vertexArrayObject)", + "OES_vertex_array_object.isVertexArrayOES(vertexArrayObject)", + "OES_vertex_array_object.deleteVertexArrayOES(vertexArrayObject)", + ]); + testFunctionsThatReturnNULL( + [ + "OES_vertex_array_object.createVertexArrayOES()", + ]); + } + + testUploadingLostContextToTexture(); + + debug(""); + + finishTest(); +} + +</script> +</head> +<body onload="init()"> +<div id="description"></div> +<div id="console"></div> +<canvas id="canvas"> +<canvas id="canvas2"> +</body> +</html> |