Index: third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost.html |
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost.html b/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f83bc54903bf7a0853d11db325ef63dce8c5ac39 |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/offscreenCanvas-context-lost.html |
@@ -0,0 +1,310 @@ |
+<!DOCTYPE html> |
+<html> |
+<head> |
+<script src="../../../resources/testharness.js"></script> |
+<script src="../../../resources/testharnessreport.js"></script> |
+<script src="./resources/webgl-test-utils-full.js"></script> |
+</head> |
+ |
+<body> |
+<script> |
+var wtu; |
+var canvas; |
+var gl; |
+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; |
+ |
+async_test(function(t) { |
+ wtu = WebGLTestUtils; |
+ canvas = new OffscreenCanvas(10, 10); |
+ gl = canvas.getContext('webgl'); |
+ |
+ // 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) { |
+ assert_true(false, "Could not find WEBGL_lose_context extension"); |
+ } |
+ 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", t.step_func_done(function() { |
+ testLostContext(); |
+ })); |
+ |
+ // We need to initialize |uniformLocation| before losing context. |
+ // Otherwise gl.getUniform() when context is lost will throw. |
+ uniformLocation = gl.getUniformLocation(program, "tex"); |
+ loseContext(); |
+}, 'Test that WebGL context loss events can be handled with OffscreenCanvas'); |
+ |
+function loseContext() |
+{ |
+ // Note: this will cause the context to be lost, but the |
+ // webglcontextlost event listener to be queued. |
+ extension.loseContext(); |
+} |
+ |
+function compareGLError(glError, evalStr) |
+{ |
+ var exception; |
+ try { |
+ eval(evalStr); |
+ } catch (e) { |
+ exception = e; |
+ } |
+ if (exception) { |
+ assert_true(false, evalStr + " threw exception " + exception); |
+ } else { |
+ assert_equals(gl.getError(), glError); |
+ } |
+} |
+ |
+function testValidContext() |
+{ |
+ assert_false(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); |
+ assert_equals(gl.getError(), gl.NO_ERROR); |
+ |
+ // Test is queries that will later be false |
+ compareGLError(gl.NO_ERROR, "gl.enable(gl.BLEND)"); |
+ assert_true(gl.isBuffer(buffer)); |
+ assert_true(gl.isEnabled(gl.BLEND)); |
+ assert_true(gl.isFramebuffer(framebuffer)); |
+ assert_true(gl.isProgram(program)); |
+ assert_true(gl.isRenderbuffer(renderbuffer)); |
+ assert_true(gl.isShader(shader)); |
+ assert_true(gl.isTexture(texture)); |
+} |
+ |
+function testLostContext() |
+{ |
+ // Functions with special return values. |
+ assert_true(gl.isContextLost()); |
+ assert_equals(gl.getError(), gl.CONTEXT_LOST_WEBGL); |
+ assert_equals(gl.getError(), gl.NO_ERROR); |
+ assert_equals(gl.checkFramebufferStatus(gl.FRAMEBUFFER), gl.FRAMEBUFFER_UNSUPPORTED); |
+ assert_equals(gl.getAttribLocation(program, 'u_modelViewProjMatrix'), -1); |
+ assert_equals(gl.getVertexAttribOffset(0, gl.VERTEX_ATTRIB_ARRAY_POINTER), 0); |
+ |
+ // Test the extension itself. |
+ compareGLError(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); |
+ |
+ // Test a set of functions that should not generate any GL error |
+ compareGLError(gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)"); |
+ compareGLError(gl.NO_ERROR, "gl.attachShader(program, shader)"); |
+ compareGLError(gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, texture)"); |
+ compareGLError(gl.NO_ERROR, "gl.blendColor(1.0, 1.0, 1.0, 1.0)"); |
+ compareGLError(gl.NO_ERROR, "gl.blendEquation(gl.FUNC_ADD)"); |
+ compareGLError(gl.NO_ERROR, "gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD)"); |
+ compareGLError(gl.NO_ERROR, "gl.blendFunc(gl.ONE, gl.ONE)"); |
+ compareGLError(gl.NO_ERROR, "gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE)"); |
+ compareGLError(gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, 0, gl.STATIC_DRAW)"); |
+ compareGLError(gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, arrayBufferView, gl.STATIC_DRAW)"); |
+ compareGLError(gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, arrayBuffer, gl.STATIC_DRAW)"); |
+ compareGLError(gl.NO_ERROR, "gl.bufferSubData(gl.ARRAY_BUFFRE, 0, arrayBufferView)"); |
+ compareGLError(gl.NO_ERROR, "gl.bufferSubData(gl.ARRAY_BUFFRE, 0, arrayBuffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)"); |
+ compareGLError(gl.NO_ERROR, "gl.clearColor(1, 1, 1, 1)"); |
+ compareGLError(gl.NO_ERROR, "gl.clearDepth(1)"); |
+ compareGLError(gl.NO_ERROR, "gl.clearStencil(0)"); |
+ compareGLError(gl.NO_ERROR, "gl.colorMask(1, 1, 1, 1)"); |
+ compareGLError(gl.NO_ERROR, "gl.compileShader(shader)"); |
+ compareGLError(gl.NO_ERROR, "gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.cullFace(gl.FRONT)"); |
+ compareGLError(gl.NO_ERROR, "gl.deleteBuffer(buffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.deleteFramebuffer(framebuffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.deleteProgram(program)"); |
+ compareGLError(gl.NO_ERROR, "gl.deleteRenderbuffer(renderbuffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.deleteShader(shader)"); |
+ compareGLError(gl.NO_ERROR, "gl.deleteTexture(texture)"); |
+ compareGLError(gl.NO_ERROR, "gl.depthFunc(gl.NEVER)"); |
+ compareGLError(gl.NO_ERROR, "gl.depthMask(0)"); |
+ compareGLError(gl.NO_ERROR, "gl.depthRange(0, 1)"); |
+ compareGLError(gl.NO_ERROR, "gl.detachShader(program, shader)"); |
+ compareGLError(gl.NO_ERROR, "gl.disable(gl.BLEND)"); |
+ compareGLError(gl.NO_ERROR, "gl.disableVertexAttribArray(0)"); |
+ compareGLError(gl.NO_ERROR, "gl.drawArrays(gl.POINTS, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_SHORT, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.enable(gl.BLEND)"); |
+ compareGLError(gl.NO_ERROR, "gl.enableVertexAttribArray(0)"); |
+ compareGLError(gl.NO_ERROR, "gl.finish()"); |
+ compareGLError(gl.NO_ERROR, "gl.flush()"); |
+ compareGLError(gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer)"); |
+ compareGLError(gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.frontFace(gl.CW)"); |
+ compareGLError(gl.NO_ERROR, "gl.generateMipmap(gl.TEXTURE_2D)"); |
+ compareGLError(gl.NO_ERROR, "gl.hint(gl.GENERATE_MIPMAP_HINT, gl.FASTEST)"); |
+ compareGLError(gl.NO_ERROR, "gl.lineWidth(0)"); |
+ compareGLError(gl.NO_ERROR, "gl.linkProgram(program)"); |
+ compareGLError(gl.NO_ERROR, "gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.polygonOffset(0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.readPixels(0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)"); |
+ compareGLError(gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.sampleCoverage(0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.scissor(0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.shaderSource(shader, '')"); |
+ compareGLError(gl.NO_ERROR, "gl.stencilFunc(gl.NEVER, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.stencilFuncSeparate(gl.FRONT, gl.NEVER, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.stencilMask(0)"); |
+ compareGLError(gl.NO_ERROR, "gl.stencilMaskSeparate(gl.FRONT, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP)"); |
+ compareGLError(gl.NO_ERROR, "gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.KEEP)"); |
+ compareGLError(gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)"); |
+ compareGLError(gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageData)"); |
+ compareGLError(gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)"); |
+ compareGLError(gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d)"); |
+ compareGLError(gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video)"); |
+ compareGLError(gl.NO_ERROR, "gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)"); |
+ compareGLError(gl.NO_ERROR, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)"); |
+ compareGLError(gl.NO_ERROR, "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)"); |
+ compareGLError(gl.NO_ERROR, "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData)"); |
+ compareGLError(gl.NO_ERROR, "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image)"); |
+ compareGLError(gl.NO_ERROR, "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d)"); |
+ compareGLError(gl.NO_ERROR, "gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform1f(uniformLocation, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform1fv(uniformLocation, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform1fv(uniformLocation, [0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform1i(uniformLocation, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform1iv(uniformLocation, int32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform1iv(uniformLocation, [0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform2f(uniformLocation, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform2fv(uniformLocation, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform2fv(uniformLocation, [0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform2i(uniformLocation, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform2iv(uniformLocation, int32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform2iv(uniformLocation, [0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform3f(uniformLocation, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform3fv(uniformLocation, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform3fv(uniformLocation, [0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform3i(uniformLocation, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform3iv(uniformLocation, int32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform3iv(uniformLocation, [0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform4f(uniformLocation, 0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform4fv(uniformLocation, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform4fv(uniformLocation, [0, 0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform4i(uniformLocation, 0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform4iv(uniformLocation, int32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniform4iv(uniformLocation, [0, 0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniformMatrix2fv(uniformLocation, false, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniformMatrix2fv(uniformLocation, false, [0, 0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniformMatrix3fv(uniformLocation, false, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniformMatrix3fv(uniformLocation, false, [0, 0, 0, 0, 0, 0, 0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.uniformMatrix4fv(uniformLocation, false, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.uniformMatrix4fv(uniformLocation, false, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.useProgram(program)"); |
+ compareGLError(gl.NO_ERROR, "gl.validateProgram(program)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib1f(0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib1fv(0, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib1fv(0, [0])"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib2f(0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib2fv(0, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib2fv(0, [0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib3f(0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib3fv(0, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib3fv(0, [0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib4f(0, 0, 0, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib4fv(0, float32array)"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttrib4fv(0, [0, 0, 0, 0])"); |
+ compareGLError(gl.NO_ERROR, "gl.vertexAttribPointer(0, 0, gl.FLOAT, false, 0, 0)"); |
+ compareGLError(gl.NO_ERROR, "gl.viewport(0, 0, 0, 0)"); |
+ |
+ // Test a set of functions that should return null |
+ assert_equals(gl.createBuffer(), null); |
+ assert_equals(gl.createFramebuffer(), null); |
+ assert_equals(gl.createProgram(), null); |
+ assert_equals(gl.createRenderbuffer(), null); |
+ assert_equals(gl.createShader(gl.GL_VERTEX_SHADER), null); |
+ assert_equals(gl.createTexture(), null); |
+ assert_equals(gl.getActiveAttrib(program, 0), null); |
+ assert_equals(gl.getActiveUniform(program, 0), null); |
+ assert_equals(gl.getAttachedShaders(program), null); |
+ assert_equals(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE), null); |
+ assert_equals(gl.getContextAttributes(), null); |
+ assert_equals(gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME), null); |
+ assert_equals(gl.getParameter(gl.CURRENT_PROGRAM), null); |
+ assert_equals(gl.getProgramInfoLog(program), null); |
+ assert_equals(gl.getProgramParameter(program, gl.LINK_STATUS), null); |
+ assert_equals(gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH), null); |
+ assert_equals(gl.getShaderInfoLog(shader), null); |
+ assert_equals(gl.getShaderParameter(shader, gl.SHADER_TYPE), null); |
+ assert_equals(gl.getShaderSource(shader), null); |
+ assert_equals(gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S), null); |
+ assert_equals(gl.getUniform(program, uniformLocation), null); |
+ assert_equals(gl.getUniformLocation(program, 'vPosition'), null); |
+ assert_equals(gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING), null); |
+ assert_equals(gl.getSupportedExtensions(), null); |
+ assert_equals(eval("gl.getExtension('" + extensionName + "')"), null); |
+ |
+ // "Is" queries should all return false. |
+ assert_false(gl.isBuffer(buffer)); |
+ assert_false(gl.isEnabled(gl.BLEND)); |
+ assert_false(gl.isFramebuffer(framebuffer)); |
+ assert_false(gl.isProgram(program)); |
+ assert_false(gl.isRenderbuffer(renderbuffer)); |
+ assert_false(gl.isShader(shader)); |
+ assert_false(gl.isTexture(texture)); |
+ |
+ assert_equals(gl.getError(), gl.NO_ERROR); |
+ |
+ // test extensions |
+ if (OES_vertex_array_object) { |
+ compareGLError(gl.NO_ERROR, "OES_vertex_array_object.bindVertexArrayOES(vertexArrayObject)"); |
+ compareGLError(gl.NO_ERROR, "OES_vertex_array_object.isVertexArrayOES(vertexArrayObject)"); |
+ compareGLError(gl.NO_ERROR, "OES_vertex_array_object.deleteVertexArrayOES(vertexArrayObject)"); |
+ assert_equals(OES_vertex_array_object.createVertexArrayOES(), null); |
+ } |
+} |
+ |
+</script> |
+</body> |
+</html> |