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 | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/context')
25 files changed, 3485 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/context/00_test_list.txt new file mode 100644 index 0000000000..f1acae5dfa --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/00_test_list.txt @@ -0,0 +1,21 @@ +--max-version 1.9.9 constants-and-properties.html +--min-version 1.0.2 context-attribute-preserve-drawing-buffer.html +--min-version 1.0.4 context-attribute-preserve-drawing-buffer-antialias.html +context-attributes-alpha-depth-stencil-antialias.html +--min-version 1.0.4 context-size-change.html +--min-version 1.0.4 context-no-alpha-fbo-with-alpha.html +--min-version 1.0.2 --slow context-creation-and-destruction.html +--min-version 1.0.3 --slow context-creation.html +--min-version 1.0.3 --slow context-eviction-with-garbage-collection.html +--min-version 1.0.3 context-hidden-alpha.html +--min-version 1.0.2 context-release-upon-reload.html +--min-version 1.0.2 context-release-with-workers.html +context-lost-restored.html +context-lost.html +--max-version 1.9.9 context-type-test.html +--min-version 1.0.4 deleted-object-behavior.html +incorrect-context-object-behaviour.html +--max-version 1.9.9 methods.html +premultiplyalpha-test.html +--min-version 1.0.4 user-defined-properties-on-context.html +--min-version 1.0.4 zero-sized-canvas.html diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/constants-and-properties.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/constants-and-properties.html new file mode 100644 index 0000000000..ccf128e11b --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/constants-and-properties.html @@ -0,0 +1,546 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Constants and Properties 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" style="width: 50px; height: 50px;"> </canvas> +<script> +"use strict"; +description("This test ensures that the WebGL context has all the constants and (non-function) properties in the specification."); + +var constants = { + /* ClearBufferMask */ +DEPTH_BUFFER_BIT : 0x00000100, +STENCIL_BUFFER_BIT : 0x00000400, +COLOR_BUFFER_BIT : 0x00004000, + + /* BeginMode */ +POINTS : 0x0000, +LINES : 0x0001, +LINE_LOOP : 0x0002, +LINE_STRIP : 0x0003, +TRIANGLES : 0x0004, +TRIANGLE_STRIP : 0x0005, +TRIANGLE_FAN : 0x0006, + + /* AlphaFunction (not supported in ES20) */ + /* NEVER */ + /* LESS */ + /* EQUAL */ + /* LEQUAL */ + /* GREATER */ + /* NOTEQUAL */ + /* GEQUAL */ + /* ALWAYS */ + + /* BlendingFactorDest */ +ZERO : 0, +ONE : 1, +SRC_COLOR : 0x0300, +ONE_MINUS_SRC_COLOR : 0x0301, +SRC_ALPHA : 0x0302, +ONE_MINUS_SRC_ALPHA : 0x0303, +DST_ALPHA : 0x0304, +ONE_MINUS_DST_ALPHA : 0x0305, + + /* BlendingFactorSrc */ + /* ZERO */ + /* ONE */ +DST_COLOR : 0x0306, +ONE_MINUS_DST_COLOR : 0x0307, +SRC_ALPHA_SATURATE : 0x0308, + /* SRC_ALPHA */ + /* ONE_MINUS_SRC_ALPHA */ + /* DST_ALPHA */ + /* ONE_MINUS_DST_ALPHA */ + + /* BlendEquationSeparate */ +FUNC_ADD : 0x8006, +BLEND_EQUATION : 0x8009, +BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */ +BLEND_EQUATION_ALPHA : 0x883D, + + /* BlendSubtract */ +FUNC_SUBTRACT : 0x800A, +FUNC_REVERSE_SUBTRACT : 0x800B, + + /* Separate Blend Functions */ +BLEND_DST_RGB : 0x80C8, +BLEND_SRC_RGB : 0x80C9, +BLEND_DST_ALPHA : 0x80CA, +BLEND_SRC_ALPHA : 0x80CB, +CONSTANT_COLOR : 0x8001, +ONE_MINUS_CONSTANT_COLOR : 0x8002, +CONSTANT_ALPHA : 0x8003, +ONE_MINUS_CONSTANT_ALPHA : 0x8004, +BLEND_COLOR : 0x8005, + + /* Buffer Objects */ +ARRAY_BUFFER : 0x8892, +ELEMENT_ARRAY_BUFFER : 0x8893, +ARRAY_BUFFER_BINDING : 0x8894, +ELEMENT_ARRAY_BUFFER_BINDING : 0x8895, + +STREAM_DRAW : 0x88E0, +STATIC_DRAW : 0x88E4, +DYNAMIC_DRAW : 0x88E8, + +BUFFER_SIZE : 0x8764, +BUFFER_USAGE : 0x8765, + +CURRENT_VERTEX_ATTRIB : 0x8626, + + /* CullFaceMode */ +FRONT : 0x0404, +BACK : 0x0405, +FRONT_AND_BACK : 0x0408, + + /* DepthFunction */ + /* NEVER */ + /* LESS */ + /* EQUAL */ + /* LEQUAL */ + /* GREATER */ + /* NOTEQUAL */ + /* GEQUAL */ + /* ALWAYS */ + + /* EnableCap */ + /* TEXTURE_2D */ +CULL_FACE : 0x0B44, +BLEND : 0x0BE2, +DITHER : 0x0BD0, +STENCIL_TEST : 0x0B90, +DEPTH_TEST : 0x0B71, +SCISSOR_TEST : 0x0C11, +POLYGON_OFFSET_FILL : 0x8037, +SAMPLE_ALPHA_TO_COVERAGE : 0x809E, +SAMPLE_COVERAGE : 0x80A0, + + /* ErrorCode */ +NO_ERROR : 0, +INVALID_ENUM : 0x0500, +INVALID_VALUE : 0x0501, +INVALID_OPERATION : 0x0502, +OUT_OF_MEMORY : 0x0505, + + /* FrontFaceDirection */ +CW : 0x0900, +CCW : 0x0901, + + /* GetPName */ +LINE_WIDTH : 0x0B21, +ALIASED_POINT_SIZE_RANGE : 0x846D, +ALIASED_LINE_WIDTH_RANGE : 0x846E, +CULL_FACE_MODE : 0x0B45, +FRONT_FACE : 0x0B46, +DEPTH_RANGE : 0x0B70, +DEPTH_WRITEMASK : 0x0B72, +DEPTH_CLEAR_VALUE : 0x0B73, +DEPTH_FUNC : 0x0B74, +STENCIL_CLEAR_VALUE : 0x0B91, +STENCIL_FUNC : 0x0B92, +STENCIL_FAIL : 0x0B94, +STENCIL_PASS_DEPTH_FAIL : 0x0B95, +STENCIL_PASS_DEPTH_PASS : 0x0B96, +STENCIL_REF : 0x0B97, +STENCIL_VALUE_MASK : 0x0B93, +STENCIL_WRITEMASK : 0x0B98, +STENCIL_BACK_FUNC : 0x8800, +STENCIL_BACK_FAIL : 0x8801, +STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802, +STENCIL_BACK_PASS_DEPTH_PASS : 0x8803, +STENCIL_BACK_REF : 0x8CA3, +STENCIL_BACK_VALUE_MASK : 0x8CA4, +STENCIL_BACK_WRITEMASK : 0x8CA5, +VIEWPORT : 0x0BA2, +SCISSOR_BOX : 0x0C10, + /* SCISSOR_TEST */ +COLOR_CLEAR_VALUE : 0x0C22, +COLOR_WRITEMASK : 0x0C23, +UNPACK_ALIGNMENT : 0x0CF5, +PACK_ALIGNMENT : 0x0D05, +MAX_TEXTURE_SIZE : 0x0D33, +MAX_VIEWPORT_DIMS : 0x0D3A, +SUBPIXEL_BITS : 0x0D50, +RED_BITS : 0x0D52, +GREEN_BITS : 0x0D53, +BLUE_BITS : 0x0D54, +ALPHA_BITS : 0x0D55, +DEPTH_BITS : 0x0D56, +STENCIL_BITS : 0x0D57, +POLYGON_OFFSET_UNITS : 0x2A00, + /* POLYGON_OFFSET_FILL */ +POLYGON_OFFSET_FACTOR : 0x8038, +TEXTURE_BINDING_2D : 0x8069, +SAMPLE_BUFFERS : 0x80A8, +SAMPLES : 0x80A9, +SAMPLE_COVERAGE_VALUE : 0x80AA, +SAMPLE_COVERAGE_INVERT : 0x80AB, + + /* GetTextureParameter */ + /* TEXTURE_MAG_FILTER */ + /* TEXTURE_MIN_FILTER */ + /* TEXTURE_WRAP_S */ + /* TEXTURE_WRAP_T */ + +COMPRESSED_TEXTURE_FORMATS : 0x86A3, + + /* HintMode */ +DONT_CARE : 0x1100, +FASTEST : 0x1101, +NICEST : 0x1102, + + /* HintTarget */ +GENERATE_MIPMAP_HINT : 0x8192, + + /* DataType */ +BYTE : 0x1400, +UNSIGNED_BYTE : 0x1401, +SHORT : 0x1402, +UNSIGNED_SHORT : 0x1403, +INT : 0x1404, +UNSIGNED_INT : 0x1405, +FLOAT : 0x1406, + + /* PixelFormat */ +DEPTH_COMPONENT : 0x1902, +ALPHA : 0x1906, +RGB : 0x1907, +RGBA : 0x1908, +LUMINANCE : 0x1909, +LUMINANCE_ALPHA : 0x190A, + + /* PixelType */ + /* UNSIGNED_BYTE */ +UNSIGNED_SHORT_4_4_4_4 : 0x8033, +UNSIGNED_SHORT_5_5_5_1 : 0x8034, +UNSIGNED_SHORT_5_6_5 : 0x8363, + + /* Shaders */ +FRAGMENT_SHADER : 0x8B30, +VERTEX_SHADER : 0x8B31, +MAX_VERTEX_ATTRIBS : 0x8869, +MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB, +MAX_VARYING_VECTORS : 0x8DFC, +MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D, +MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C, +MAX_TEXTURE_IMAGE_UNITS : 0x8872, +MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD, +SHADER_TYPE : 0x8B4F, +DELETE_STATUS : 0x8B80, +LINK_STATUS : 0x8B82, +VALIDATE_STATUS : 0x8B83, +ATTACHED_SHADERS : 0x8B85, +ACTIVE_UNIFORMS : 0x8B86, +ACTIVE_ATTRIBUTES : 0x8B89, +SHADING_LANGUAGE_VERSION : 0x8B8C, +CURRENT_PROGRAM : 0x8B8D, + + /* StencilFunction */ +NEVER : 0x0200, +LESS : 0x0201, +EQUAL : 0x0202, +LEQUAL : 0x0203, +GREATER : 0x0204, +NOTEQUAL : 0x0205, +GEQUAL : 0x0206, +ALWAYS : 0x0207, + + /* StencilOp */ + /* ZERO */ +KEEP : 0x1E00, +REPLACE : 0x1E01, +INCR : 0x1E02, +DECR : 0x1E03, +INVERT : 0x150A, +INCR_WRAP : 0x8507, +DECR_WRAP : 0x8508, + + /* StringName */ +VENDOR : 0x1F00, +RENDERER : 0x1F01, +VERSION : 0x1F02, + + /* TextureMagFilter */ +NEAREST : 0x2600, +LINEAR : 0x2601, + + /* TextureMinFilter */ + /* NEAREST */ + /* LINEAR */ +NEAREST_MIPMAP_NEAREST : 0x2700, +LINEAR_MIPMAP_NEAREST : 0x2701, +NEAREST_MIPMAP_LINEAR : 0x2702, +LINEAR_MIPMAP_LINEAR : 0x2703, + + /* TextureParameterName */ +TEXTURE_MAG_FILTER : 0x2800, +TEXTURE_MIN_FILTER : 0x2801, +TEXTURE_WRAP_S : 0x2802, +TEXTURE_WRAP_T : 0x2803, + + /* TextureTarget */ +TEXTURE_2D : 0x0DE1, +TEXTURE : 0x1702, + +TEXTURE_CUBE_MAP : 0x8513, +TEXTURE_BINDING_CUBE_MAP : 0x8514, +TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515, +TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516, +TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517, +TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518, +TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519, +TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A, +MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C, + + /* TextureUnit */ +TEXTURE0 : 0x84C0, +TEXTURE1 : 0x84C1, +TEXTURE2 : 0x84C2, +TEXTURE3 : 0x84C3, +TEXTURE4 : 0x84C4, +TEXTURE5 : 0x84C5, +TEXTURE6 : 0x84C6, +TEXTURE7 : 0x84C7, +TEXTURE8 : 0x84C8, +TEXTURE9 : 0x84C9, +TEXTURE10 : 0x84CA, +TEXTURE11 : 0x84CB, +TEXTURE12 : 0x84CC, +TEXTURE13 : 0x84CD, +TEXTURE14 : 0x84CE, +TEXTURE15 : 0x84CF, +TEXTURE16 : 0x84D0, +TEXTURE17 : 0x84D1, +TEXTURE18 : 0x84D2, +TEXTURE19 : 0x84D3, +TEXTURE20 : 0x84D4, +TEXTURE21 : 0x84D5, +TEXTURE22 : 0x84D6, +TEXTURE23 : 0x84D7, +TEXTURE24 : 0x84D8, +TEXTURE25 : 0x84D9, +TEXTURE26 : 0x84DA, +TEXTURE27 : 0x84DB, +TEXTURE28 : 0x84DC, +TEXTURE29 : 0x84DD, +TEXTURE30 : 0x84DE, +TEXTURE31 : 0x84DF, +ACTIVE_TEXTURE : 0x84E0, + + /* TextureWrapMode */ +REPEAT : 0x2901, +CLAMP_TO_EDGE : 0x812F, +MIRRORED_REPEAT : 0x8370, + + /* Uniform Types */ +FLOAT_VEC2 : 0x8B50, +FLOAT_VEC3 : 0x8B51, +FLOAT_VEC4 : 0x8B52, +INT_VEC2 : 0x8B53, +INT_VEC3 : 0x8B54, +INT_VEC4 : 0x8B55, +BOOL : 0x8B56, +BOOL_VEC2 : 0x8B57, +BOOL_VEC3 : 0x8B58, +BOOL_VEC4 : 0x8B59, +FLOAT_MAT2 : 0x8B5A, +FLOAT_MAT3 : 0x8B5B, +FLOAT_MAT4 : 0x8B5C, +SAMPLER_2D : 0x8B5E, +SAMPLER_CUBE : 0x8B60, + + /* Vertex Arrays */ +VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622, +VERTEX_ATTRIB_ARRAY_SIZE : 0x8623, +VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624, +VERTEX_ATTRIB_ARRAY_TYPE : 0x8625, +VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A, +VERTEX_ATTRIB_ARRAY_POINTER : 0x8645, +VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F, + + /* Read Format */ +IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A, +IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B, + + /* Shader Source */ +COMPILE_STATUS : 0x8B81, + + /* Shader Precision-Specified Types */ +LOW_FLOAT : 0x8DF0, +MEDIUM_FLOAT : 0x8DF1, +HIGH_FLOAT : 0x8DF2, +LOW_INT : 0x8DF3, +MEDIUM_INT : 0x8DF4, +HIGH_INT : 0x8DF5, + + /* Framebuffer Object. */ +FRAMEBUFFER : 0x8D40, +RENDERBUFFER : 0x8D41, + +RGBA4 : 0x8056, +RGB5_A1 : 0x8057, +RGB565 : 0x8D62, +DEPTH_COMPONENT16 : 0x81A5, +STENCIL_INDEX8 : 0x8D48, +DEPTH_STENCIL : 0x84F9, + +RENDERBUFFER_WIDTH : 0x8D42, +RENDERBUFFER_HEIGHT : 0x8D43, +RENDERBUFFER_INTERNAL_FORMAT : 0x8D44, +RENDERBUFFER_RED_SIZE : 0x8D50, +RENDERBUFFER_GREEN_SIZE : 0x8D51, +RENDERBUFFER_BLUE_SIZE : 0x8D52, +RENDERBUFFER_ALPHA_SIZE : 0x8D53, +RENDERBUFFER_DEPTH_SIZE : 0x8D54, +RENDERBUFFER_STENCIL_SIZE : 0x8D55, + +FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0, +FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1, +FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2, +FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3, + +COLOR_ATTACHMENT0 : 0x8CE0, +DEPTH_ATTACHMENT : 0x8D00, +STENCIL_ATTACHMENT : 0x8D20, +DEPTH_STENCIL_ATTACHMENT : 0x821A, + +NONE : 0, + +FRAMEBUFFER_COMPLETE : 0x8CD5, +FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6, +FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7, +FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9, +FRAMEBUFFER_UNSUPPORTED : 0x8CDD, + +FRAMEBUFFER_BINDING : 0x8CA6, +RENDERBUFFER_BINDING : 0x8CA7, +MAX_RENDERBUFFER_SIZE : 0x84E8, + +INVALID_FRAMEBUFFER_OPERATION : 0x0506, + +/* WebGL-specific enums */ +UNPACK_FLIP_Y_WEBGL : 0x9240, +UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241, +CONTEXT_LOST_WEBGL : 0x9242, +UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243, +BROWSER_DEFAULT_WEBGL : 0x9244 +}; + +// Other non-function properties on the WebGL object +var otherProperties = { +drawingBufferWidth : "number", +drawingBufferHeight : "number", +drawingBufferColorSpace : "string", +unpackColorSpace : "string", +canvas : "implementation-dependent" +}; + +// Properties to be ignored (as a list of strings) because they were +// added in versions of the spec that are backward-compatible with +// this version +var ignoredProperties = [ +]; + +// Constants removed from the WebGL spec compared to ES 2.0 +var removedConstants = { +NUM_COMPRESSED_TEXTURE_FORMATS : 0x86A2, +FIXED : 0x140C, +ACTIVE_UNIFORM_MAX_LENGTH : 0x8B87, +ACTIVE_ATTRIBUTE_MAX_LENGTH : 0x8B8A, +EXTENSIONS : 0x1F03, +INFO_LOG_LENGTH : 0x8B84, +SHADER_SOURCE_LENGTH : 0x8B88, +SHADER_COMPILER : 0x8DFA, +SHADER_BINARY_FORMATS : 0x8DF8, +NUM_SHADER_BINARY_FORMATS : 0x8DF9, +}; + +function assertProperty(v, p) { + if (p in v) { + return true; + } else { + testFailed("Property does not exist: " + p) + return false; + } +} + +function assertNoProperty(v, p) { + if (p in v) { + testFailed("Property is defined and should not be: " + p) + return false; + } else { + return true; + } +} + +function assertMsg_(bool, msg) { + if (!bool) // show only failures to avoid spamming result list + assertMsg(bool, msg); + return bool; +} + +debug(""); +debug("Canvas.getContext"); + +var canvas = document.getElementById("canvas"); +var wtu = WebGLTestUtils; +var gl = wtu.create3DContext(canvas); +var passed = true; +for (var i in constants) { + var r = assertProperty(gl, i) && assertMsg_(gl[i] == constants[i], "Property "+i+" value test "+gl[i]+" == "+constants[i]); + passed = passed && r; +} +if (passed) { + testPassed("All WebGL constants found to have correct values."); +} +passed = true; +for (var i in removedConstants) { + var r = assertNoProperty(gl, i); + passed = passed && r; +} +if (passed) { + testPassed("All constants removed from WebGL spec were absent from WebGL context."); +} +var extended = false; +for (var i in gl) { + if (constants[i] !== undefined) { + // OK; known constant + } else if (ignoredProperties.indexOf(i) != -1) { + // OK; constant that should be ignored because it was added in a later version of the spec + } else if (otherProperties[i] !== undefined && + (otherProperties[i] == "implementation-dependent" || typeof gl[i] == otherProperties[i])) { + // OK; known property of known type + } else if (typeof gl[i] != "function" && removedConstants[i] === undefined) { + if (!extended) { + extended = true; + testFailed("Also found the following extra properties:"); + } + testFailed(i); + } +} + +if (!extended) { + testPassed("No extra properties found on WebGL context."); +} + +debug(""); +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer-antialias.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer-antialias.html new file mode 100644 index 0000000000..fa8d9937db --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer-antialias.html @@ -0,0 +1,143 @@ +<!-- +Copyright (c) 2022 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<canvas id="canvas" width="128" height="64" style="width: 32px; height: 32px;"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; + +const wtu = WebGLTestUtils; +description(' Test drawingbuffer is preserved when drawing'); + +const waitForComposite = () => new Promise(resolve => wtu.waitForComposite(resolve)); +const gl = wtu.create3DContext("canvas", { + preserveDrawingBuffer: true, + antialias: true, +}); +console.log(gl.getContextAttributes()); +const w = 128; +const h = 64; + +if (!gl) { + testFailed('canvas.getContext() failed'); +} else { + gl.viewport(0, 0, w, h); + runTest(gl, 4); +} + +async function runTest(gl, sampleCount) { + const vs = ` + attribute vec4 position; + uniform mat4 mat; + + void main() { + gl_Position = mat * position; + } + `; + + const fs = ` + precision mediump float; + uniform vec4 color; + void main() { + gl_FragColor = color; + } + `; + + const positionLoc = 0; // hard coded in shaders so they match + const buf = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buf); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ + 0, 0, + 1, 0, + 0, 1, + 0, 1, + 1, 0, + 1, 1, + ]), gl.STATIC_DRAW); + gl.enableVertexAttribArray(positionLoc); + gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0); + + const program = wtu.setupProgram(gl, [vs, fs]); + + const colorLoc = gl.getUniformLocation(program, 'color'); + const matLoc = gl.getUniformLocation(program, 'mat'); + + gl.useProgram(program); + + const draw = (color, mat) => { + gl.uniform4fv(colorLoc, color); + gl.uniformMatrix4fv(matLoc, false, mat); + gl.drawArrays(gl.TRIANGLES, 0, 6); + }; + + const f32Red = [1, 0, 0, 1]; + const f32Green = [0, 1, 0, 1]; + const f32Gray = [0.5, 0.5, 0.5, 1]; + + const u8Red = [255, 0, 0, 255]; + const u8Green = [ 0, 255, 0, 255]; + const u8LightRed = [255, 128, 128, 255]; + const u8LightGreen = [128, 255, 128, 255]; + + draw(f32Red, [ + 2, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 1, 0, + -1, -1, 0, 1, + ]); + await waitForComposite(); + + draw(f32Green, [ + 1, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 1, 0, + 0, -1, 0, 1, + ]); + await waitForComposite(); + + gl.enable(gl.BLEND); + gl.blendFunc(gl.ONE, gl.ONE); + draw(f32Gray, [ + 1, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 1, 0, + -0.5, -1, 0, 1, + ]); + gl.disable(gl.BLEND); + await waitForComposite(); + + /* + expected + +-----+-------+---------+--------+ + | red | ltRed | ltGreen | green | + +-----+-------+---------+--------+ + 0,0 + */ + + const tolerance = 2; // For multisampling resolution differences between GPUs + wtu.checkCanvasRect(gl, 0, 0, w / 4, h , u8Red, 'left edge', tolerance) + wtu.checkCanvasRect(gl, w * 3 / 4, 0, w / 4, h, u8Green, 'right edge', tolerance); + wtu.checkCanvasRect(gl, w / 4, 0, w / 4, h, u8LightRed, 'left of center', tolerance); + wtu.checkCanvasRect(gl, w / 2, 0, w / 4, h, u8LightGreen, 'right of center', tolerance); + + finishTest(); +} + +var successfullyParsed = true; +shouldBeTrue("successfullyParsed"); +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer.html new file mode 100644 index 0000000000..7a023996fb --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer.html @@ -0,0 +1,117 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<style> +.pattern { + white-space: nowrap; + display: inline-block; +} +canvas { + width:10px; + height:10px; +} +.square { + display:inline-block; + width:10px; + height:10px; + background-color:red; +} +</style> +<script> +"use strict"; +var wtu = WebGLTestUtils; +function checkResult(ctx1, ctx2, preserve) { + var imgData1 = ctx1.getImageData(0,0,1,1); + var imgData2 = ctx2.getImageData(0,0,1,1); + var correct1 = [255,0,0,255]; + var correct2 = preserve ? [255,0,0,255] : [0,0,0,255]; + var ok1 = true; + var ok2 = true; + for (var p = 0; p < 4; ++p) { + if (imgData1.data[p] != correct1[p]) + ok1 = false; + if (imgData2.data[p] != correct2[p]) + ok2 = false; + } + if (ok1 && ok2) + testPassed('Rendered ok with preserveDrawingBuffer ' + preserve +'.'); + else + testFailed('Did not render ok with preserveDrawingBuffer ' + preserve + '.'); + if (preserve) { + finishTest() + } else { + runTest(true); + } +} + +function runTest(preserve) { + var c1 = document.getElementById('c' + (preserve * 3 + 1)); + var c2 = document.getElementById('c' + (preserve * 3 + 2)); + var c3 = document.getElementById('c' + (preserve * 3 + 3)); + var ctx1 = c1.getContext('2d'); + var ctx2 = c2.getContext('2d'); + var gl = wtu.create3DContext(c3, { alpha:false, preserveDrawingBuffer:preserve }); + if (!gl) { + testFailed("context does not exist"); + if (preserve) { + finishTest() + } else { + runTest(true); + } + return; + } + gl.clearColor(1, 0, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + ctx1.drawImage(c3, 0, 0); + wtu.waitForComposite(function() { + ctx2.drawImage(c3, 0, 0); + checkResult(ctx1, ctx2, preserve); + }); +} +</script> +</head> +<body> +<div class="pattern"> + <canvas id='c1'></canvas> + <canvas id='c2'></canvas> + <canvas id='c3'></canvas> +</div> +<span>should look like</span> +<div class="pattern"> + <div class='square'></div> + <div class='square' style='background-color:black'></div> + <div class='square'></div> +</div> +<hr /> +<div class="pattern"> + <canvas id='c4'></canvas> + <canvas id='c5'></canvas> + <canvas id='c6'></canvas> +</div> +<span>should look like</span> +<div class="pattern"> + <div class='square'></div> + <div class='square'></div> + <div class='square'></div> +</div> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +description('Verify that preserveDrawingBuffer attribute is honored.'); +runTest(false); +var successfullyParsed = true; +shouldBeTrue("successfullyParsed"); +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attributes-alpha-depth-stencil-antialias.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attributes-alpha-depth-stencil-antialias.html new file mode 100644 index 0000000000..40f46a744a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-attributes-alpha-depth-stencil-antialias.html @@ -0,0 +1,281 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<script id="vshader" type="x-shader/x-vertex"> +attribute vec3 pos; +attribute vec4 colorIn; +varying vec4 color; + +void main() +{ + color = colorIn; + gl_Position = vec4(pos.xyz, 1.0); +} +</script> + +<script id="fshader" type="x-shader/x-fragment"> +precision mediump float; + +varying vec4 color; + +void main() +{ + gl_FragColor = color; +} +</script> + +<script> +"use strict"; + +// These four declarations need to be global for "shouldBe" to see them +var wtu = WebGLTestUtils; +var gl; +var contextAttribs = null; +var redChannels = [0, 0, 0]; +var correctColor = null; +var framebuffer; +var fbHasColor; +var fbHasDepth; +var fbHasStencil; +var contextVersion = wtu.getDefault3DContextVersion(); + +function init() +{ + description('Verify WebGLContextAttributes are working as specified, including alpha, depth, stencil, antialias, but not premultipliedAlpha'); + + runTest(); +} + +var vertices = new Float32Array([ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + -1.0, -1.0, 0.0, + 1.0, 1.0, 0.0, + -1.0, -1.0, 0.0, + 1.0, -1.0, 0.0]); + +var colors = new Uint8Array([ + 255, 0, 0, 255, + 255, 0, 0, 255, + 255, 0, 0, 255, + 255, 0, 0, 255, + 255, 0, 0, 255, + 255, 0, 0, 255]); + + +function getWebGL(canvasWidth, canvasHeight, contextAttribs, clearColor, clearDepth, clearStencil) +{ + var canvas = document.createElement("canvas"); + if (!canvas) + return null; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + + gl = wtu.create3DContext(canvas, contextAttribs, contextVersion); + if (!gl) + return null; + + var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["pos", "colorIn"]); + if (!program) + return null; + + gl.enable(gl.DEPTH_TEST); + gl.enable(gl.STENCIL_TEST); + + gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + gl.clearDepth(clearDepth); + gl.clearStencil(clearStencil); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + + framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + var texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.canvas.width, gl.canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + fbHasStencil = false; + fbHasDepth = false; + fbHasColor = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE; + if (fbHasColor) { + var depthStencil = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencil); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, gl.canvas.width, gl.canvas.height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencil); + fbHasDepth = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE; + if (!fbHasDepth) { + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null); + shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); + } else { + fbHasStencil = true; + } + } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + var colorOffset = vertices.byteLength; + var vbo = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vbo); + gl.bufferData(gl.ARRAY_BUFFER, colorOffset + colors.byteLength, gl.STATIC_DRAW); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); + gl.bufferSubData(gl.ARRAY_BUFFER, colorOffset, colors); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, colorOffset); + gl.enableVertexAttribArray(1); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors"); + return gl; +} + +function draw(gl, verticesCount) +{ + verticesCount = verticesCount || vertices.length / 3; + gl.drawArrays(gl.TRIANGLES, 0, verticesCount); +} + +function checkDraw(hasAlpha, hasStencil, hasDepth, hasAntialias) +{ + let red = [255, 0, 0, 255 ]; + let black = [0, 0, 0, hasAlpha ? 0 : 255 ]; + debug(`Testing that stencil ${ hasStencil ? 'affects': 'does not affect'} the rendering.`); + gl.stencilFunc(gl.NEVER, 1, 1); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); + draw(gl); + correctColor = hasStencil ? black : red; + wtu.checkCanvas(gl, correctColor) + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + wtu.checkCanvas(gl, black); + gl.stencilFunc(gl.ALWAYS, 1, 1); + + debug(`Testing that depth ${ hasDepth ? 'affects': 'does not affect'} the rendering.`); + gl.depthFunc(gl.NEVER); + draw(gl); + correctColor = hasDepth ? black : red; + wtu.checkCanvas(gl, correctColor); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + wtu.checkCanvas(gl, black); + gl.depthFunc(gl.ALWAYS); + + debug(`Testing that rendering is ${hasAntialias ? 'antialiased' : 'aliased'}.`); + draw(gl, 3); + let N = 2; + let buf = new Uint8Array(N * N * 4); + gl.readPixels(0, 0, N, N, gl.RGBA, gl.UNSIGNED_BYTE, buf); + redChannels[0] = buf[4 * (N + 1)]; // (1, 1) + redChannels[1] = buf[4 * N * (N - 1)]; // left top + redChannels[2] = buf[4 * (N - 1)]; // right bottom + shouldBe("redChannels[1]", "255"); + shouldBe("redChannels[2]", "0"); + if (hasAntialias) { + shouldNotBe("redChannels[0]", "255"); + shouldNotBe("redChannels[0]", "0"); + } else { + shouldBeTrue("redChannels[0] == 255 || redChannels[0] == 0"); + } + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + wtu.checkCanvas(gl, black); + + debug("Testing that rendering works."); + draw(gl); + wtu.checkCanvas(gl, red); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + wtu.checkCanvas(gl, black); +} + +function testDefault() +{ + debug("Testing default attributes: { stencil:false }"); + shouldBeNonNull("gl = getWebGL(1, 1, null, [ 0, 0, 0, 0 ], 1, 0)"); + shouldBeFalse("gl.getContextAttributes().stencil"); + shouldBe("gl.getParameter(gl.STENCIL_BITS)", "0"); +} + +function testAttributesAffectContext(alpha, stencil, depth, antialias) +{ + shouldBeNonNull(`gl = getWebGL(2, 2, { depth: ${depth}, stencil: ${stencil}, antialias: ${antialias}, alpha: ${alpha} }, [ 0, 0, 0, 0 ], 1, 0)`); + shouldBeNonNull("contextAttribs = gl.getContextAttributes()"); + + shouldBeGreaterThanOrEqual("gl.getParameter(gl.RED_BITS)", "8"); + shouldBeGreaterThanOrEqual("gl.getParameter(gl.GREEN_BITS)", "8"); + shouldBeGreaterThanOrEqual("gl.getParameter(gl.BLUE_BITS)", "8"); + + shouldBe("contextAttribs.alpha", "" + alpha); + if (contextVersion < 2) { + if (!stencil) + shouldBeFalse("contextAttribs.stencil"); + else + stencil = contextAttribs.stencil; + if (!depth) + shouldBeFalse("contextAttribs.depth"); + else + depth = contextAttribs.depth; + if (!antialias) + shouldBeFalse("contextAttribs.antialias"); + else + antialias = contextAttribs.antialias; + } else { + shouldBe("contextAttribs.stencil", "" + stencil); + shouldBe("contextAttribs.depth", "" + depth); + shouldBe("contextAttribs.antialias", "" + antialias); + } + + if (alpha) + shouldBeGreaterThanOrEqual("gl.getParameter(gl.ALPHA_BITS)", "8"); + else + shouldBe("gl.getParameter(gl.ALPHA_BITS)", "0"); + if (stencil) + shouldBeGreaterThanOrEqual("gl.getParameter(gl.STENCIL_BITS)", "8"); + else + shouldBe("gl.getParameter(gl.STENCIL_BITS)", "0"); + if (depth) + shouldBeGreaterThanOrEqual("gl.getParameter(gl.DEPTH_BITS)", "16"); + else + shouldBe("gl.getParameter(gl.DEPTH_BITS)", "0"); + + var correctColor = alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]; + wtu.checkCanvas(gl, correctColor); + + debug("Testing default framebuffer."); + checkDraw(alpha, stencil, depth, antialias); + + if (fbHasColor) { + debug("Testing bound framebuffer object."); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + checkDraw(true, fbHasStencil, fbHasDepth, false); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } +} + +function runTest() +{ + testDefault(); + let cases = [false, true]; + for (let alpha of cases) { + for (let stencil of cases) { + for (let depth of cases) { + for (let antialias of cases) { + testAttributesAffectContext(alpha, stencil, depth, antialias); + } + } + } + } + finishTest(); +} +</script> +</head> +<body onload="init()"> +<div id="description"></div> +<div id="console"></div> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation-and-destruction.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation-and-destruction.html new file mode 100644 index 0000000000..72324b5f17 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation-and-destruction.html @@ -0,0 +1,35 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>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) || 50; +IterableTest.run(test, iterations); + +var successfullyParsed = true; +</script> + +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation.html new file mode 100644 index 0000000000..ceeb5b092b --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation.html @@ -0,0 +1,35 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test that you can create large numbers of WebGL contexts.</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.createContextCreationTest(); +var iterations = parseInt(wtu.getUrlOptions().iterations, 10) || 50; +IterableTest.run(test, iterations); + +var successfullyParsed = true; +</script> + +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-eviction-with-garbage-collection.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-eviction-with-garbage-collection.html new file mode 100644 index 0000000000..1898e73520 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-eviction-with-garbage-collection.html @@ -0,0 +1,57 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test that context eviction and garbage collection do not interfere with each other</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"> </script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +// See http://crbug.com/374086 for original failing case. +description("Test that context eviction and garbage collection do not interfere with each other."); +var wtu = WebGLTestUtils; + +var total_iteration = 50; +var array_count = 10; + +var bank = []; +for (var i = 0; i < array_count; i++) + bank[i] = []; + +for (var iter = 0; iter < total_iteration; ++iter) { + for (var i = 0; i < array_count; i++) + bank[i][iter * i] = iter; + + var canvas = document.createElement('canvas'); + var gl = wtu.create3DContext(canvas); + canvas.width = 50; + canvas.height = 50; + var program = wtu.setupTexturedQuad(gl); + shouldBeTrue("program != null"); + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + var pixel = new Uint8Array([0, 255, 0, 255]); + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixel); + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from iteration " + iter); +} + +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> + diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-hidden-alpha.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-hidden-alpha.html new file mode 100644 index 0000000000..ed67fc0093 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-hidden-alpha.html @@ -0,0 +1,166 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<script id='vs' type='x-shader/x-vertex'> + attribute vec2 aPosCoord; + + void main(void) { + gl_Position = vec4(aPosCoord, 0.0, 1.0); + } +</script> + +<script id='fs' type='x-shader/x-fragment'> + precision mediump float; + + void main(void) { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } +</script> +<script> +"use strict"; + +var posCoords_arr = new Float32Array(2 * 4); +var posCoords_buff = null; +function DrawQuad(gl, prog, x0, y0, x1, y1) { + gl.useProgram(prog); + + if (!posCoords_buff) { + posCoords_buff = gl.createBuffer(); + } + gl.bindBuffer(gl.ARRAY_BUFFER, posCoords_buff); + posCoords_arr[0] = x0; + posCoords_arr[1] = y0; + + posCoords_arr[2] = x1; + posCoords_arr[3] = y0; + + posCoords_arr[4] = x0; + posCoords_arr[5] = y1; + + posCoords_arr[6] = x1; + posCoords_arr[7] = y1; + gl.bufferData(gl.ARRAY_BUFFER, posCoords_arr, gl.STREAM_DRAW); + + gl.enableVertexAttribArray(prog.aPosCoord); + gl.vertexAttribPointer(prog.aPosCoord, 2, gl.FLOAT, false, 0, 0); + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); +} + +function DrawSquare(gl, prog, size) { + DrawQuad(gl, prog, -size, -size, size, size); +} + +function Reset(gl) { + gl.canvas.width += 1; + gl.canvas.width -= 1; +} + +var iColor; +var pixel; +var dataURL_pre; +var dataURL_post; + +function Test(gl, prog, shouldFinish) { + gl.enable(gl.BLEND); + gl.blendFunc(gl.ZERO, gl.DST_ALPHA); + + iColor = 64; + var fColor = iColor / 255.0; + + ////////////////// + + debug('clear(R,G,B,0)'); + + Reset(gl); + + gl.clearColor(fColor, fColor, fColor, 0.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + dataURL_pre = gl.canvas.toDataURL(); + //console.log('Before blending: ' + dataURL_pre); + + DrawSquare(gl, prog, 0.7); + + WebGLTestUtils.checkCanvasRect(gl, gl.drawingBufferWidth/2, + gl.drawingBufferHeight/2, 1, 1, + [iColor, iColor, iColor, 255], + 'Should blend as if alpha is 1.0.'); + + dataURL_post = gl.canvas.toDataURL(); + //console.log('After blending: ' + dataURL_post); + shouldBe("dataURL_post", "dataURL_pre"); + + ////////////////// + + debug('mask(R,G,B,0), clear(R,G,B,1)'); + + Reset(gl); + + gl.colorMask(true, true, true, false); + gl.clearColor(fColor, fColor, fColor, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.colorMask(true, true, true, true); + + dataURL_pre = gl.canvas.toDataURL(); + //console.log('Before blending: ' + dataURL_pre); + + DrawSquare(gl, prog, 0.7); + + WebGLTestUtils.checkCanvasRect(gl, gl.drawingBufferWidth/2, + gl.drawingBufferHeight/2, 1, 1, + [iColor, iColor, iColor, 255], + 'Should blend as if alpha is 1.0.'); + + dataURL_post = gl.canvas.toDataURL(); + //console.log('After blending: ' + dataURL_post); + shouldBe("dataURL_post", "dataURL_pre"); + + //////////////// + + WebGLTestUtils.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors"); + + if (shouldFinish) + finishTest(); +} + +var gl; +function init() { + var canvas = document.getElementById('canvas'); + var attribs = { + alpha: false, + antialias: false, + premultipliedAlpha: false, + }; + gl = canvas.getContext('experimental-webgl', attribs); + shouldBeNonNull(gl); + shouldBe("gl.getParameter(gl.ALPHA_BITS)", "0"); + + var prog = WebGLTestUtils.setupProgram(gl, ['vs', 'fs']); + shouldBeNonNull(prog); + prog.aPosCoord = gl.getAttribLocation(prog, 'aPosCoord'); + + Test(gl, prog, false); + + requestAnimationFrame(function(){ Test(gl, prog, true); }); +} + +</script> +</head> +<body onload="init()"> +<canvas id='canvas'></canvas> +<br/> +<div id="description"></div> +<div id="console"></div> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html new file mode 100644 index 0000000000..6942e3d1ce --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html @@ -0,0 +1,287 @@ +<!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 = WebGLTestUtils; +var canvas; +var gl; +var shouldGenerateGLError; +var WEBGL_lose_context; +var new_WEBGL_lose_context; +var bufferObjects; +var program; +var texture; +var texColor = [255, 10, 20, 255]; +var allowRestore; +var contextLostEventFired; +var contextRestoredEventFired; +var OES_vertex_array_object; +var old_OES_vertex_array_object; +var vertexArrayObject; +var OES_texture_float; +var newExtension; + +function init() +{ + enableJSTestPreVerboseLogging(); + description("Tests behavior under a restored context."); + + shouldGenerateGLError = wtu.shouldGenerateGLError; + testLosingContext(); +} + +function setupTest() +{ + canvas = document.createElement("canvas"); + canvas.width = 1; + canvas.height = 1; + gl = wtu.create3DContext(canvas); + WEBGL_lose_context = getExtensionAndAddProperty(gl, "WEBGL_lose_context"); + if (!WEBGL_lose_context) { + debug("Could not find WEBGL_lose_context extension"); + return false; + } + + // Try to get a few extensions + OES_vertex_array_object = getExtensionAndAddProperty(gl, "OES_vertex_array_object"); + OES_texture_float = getExtensionAndAddProperty(gl, "OES_texture_float"); + + return true; +} + +function getExtensionAndAddProperty(gl, name) { + var ext = wtu.getExtensionWithKnownPrefixes(gl, name); + if (ext) { + ext.webglTestProperty = true; + } + return ext; +} + +function reGetExtensionAndTestForProperty(gl, name, expectProperty) { + newExtension = wtu.getExtensionWithKnownPrefixes(gl, name); + // NOTE: while getting a extension after context lost/restored is allowed to fail + // for the purpose the conformance tests it is not. + // + // Hypothetically the user can switch GPUs live. For example on Windows, install 2 GPUs, + // then in the control panen enable 1, disable the others and visa versa. Since the GPUs + // have different capabilities one or the other may not support a particlar extension. + // + // But, for the purpose of the conformance tests the context is expected to restore + // on the same GPU and therefore the extensions that succeeded previously should + // succeed on restore. + shouldBeTrue("newExtension != null"); + if (expectProperty) { + shouldBeTrue("newExtension.webglTestProperty === true"); + } else { + shouldBeTrue("newExtension.webglTestProperty === undefined"); + } + return newExtension; +} + +function testLosingContext() +{ + if (!setupTest()) { + finishTest(); + return; + } + + debug("Test losing a context and inability to restore it."); + + canvas.addEventListener("webglcontextlost", function(e) { + testLostContext(e); + // restore the context after this event has exited. + setTimeout(function() { + // we didn't call prevent default so we should not be able to restore the context + shouldGenerateGLError(gl, gl.INVALID_OPERATION, "WEBGL_lose_context.restoreContext()"); + testLosingAndRestoringContext(); + }, 0); + }); + canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext); + allowRestore = false; + contextLostEventFired = false; + contextRestoredEventFired = false; + + testOriginalContext(); + WEBGL_lose_context.loseContext(); + // The context should be lost immediately. + shouldBeTrue("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + // gl methods should be no-ops + shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)"); + // but the event should not have been fired. + shouldBeFalse("contextLostEventFired"); +} + +function testLosingAndRestoringContext() +{ + if (!setupTest()) + finishTest(); + + debug(""); + debug("Test losing and restoring a context."); + + canvas.addEventListener("webglcontextlost", function(e) { + testLostContext(e); + // restore the context after this event has exited. + setTimeout(function() { + shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()"); + // Calling restoreContext() twice should not cause error or crash + shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()"); + // The context should still be lost. It will not get restored until the + // webglrestorecontext event is fired. + shouldBeTrue("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + // gl methods should still be no-ops + shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)"); + }, 0); + }); + canvas.addEventListener("webglcontextrestored", function() { + testRestoredContext(); + finishTest(); + }); + allowRestore = true; + contextLostEventFired = false; + contextRestoredEventFired = false; + + testOriginalContext(); + WEBGL_lose_context.loseContext(); + // The context should be lost immediately. + shouldBeTrue("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + // gl methods should be no-ops + shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)"); + // but the event should not have been fired. + shouldBeFalse("contextLostEventFired"); +} + +function testRendering() +{ + gl.clearColor(0, 0, 0, 255); + gl.colorMask(1, 1, 1, 0); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + program = wtu.setupSimpleTextureProgram(gl); + bufferObjects = wtu.setupUnitQuad(gl); + texture = wtu.createColoredTexture(gl, canvas.width, canvas.height, texColor); + + gl.uniform1i(gl.getUniformLocation(program, "tex"), 0); + wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); + + var compare = texColor.slice(0, 3); + wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, compare, "shouldBe " + compare); + + shouldBe("gl.getError()", "gl.NO_ERROR"); +} + +function testOriginalContext() +{ + debug("Test valid context"); + shouldBeFalse("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + testRendering(); + debug(""); +} + +function testLostContext(e) +{ + debug("Test lost context"); + shouldBeFalse("contextLostEventFired"); + contextLostEventFired = true; + shouldBeTrue("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + debug(""); + if (allowRestore) + e.preventDefault(); +} + +function testShouldNotRestoreContext(e) +{ + testFailed("Should not restore the context unless preventDefault is called on the context lost event"); + debug(""); +} + +function testResources(expected) +{ + var tests = [ + "gl.bindTexture(gl.TEXTURE_2D, texture)", + "gl.useProgram(program)", + "gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0])", + ]; + + for (var i = 0; i < tests.length; ++i) + shouldGenerateGLError(gl, expected, tests[i]); +} + +function testOESTextureFloat() { + if (OES_texture_float) { + // Extension must still be lost. + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)"); + // Try re-enabling extension + OES_texture_float = reGetExtensionAndTestForProperty(gl, "OES_texture_float", false); + shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)"); + } +} + +function testOESVertexArrayObject() { + if (OES_vertex_array_object) { + // Extension must still be lost. + shouldBeNull("OES_vertex_array_object.createVertexArrayOES()"); + // Try re-enabling extension + + old_OES_vertex_array_object = OES_vertex_array_object; + OES_vertex_array_object = reGetExtensionAndTestForProperty(gl, "OES_vertex_array_object", false); + shouldBeTrue("OES_vertex_array_object.createVertexArrayOES() != null"); + shouldBeTrue("old_OES_vertex_array_object.createVertexArrayOES() == null"); + } +} + +function testExtensions() { + testOESTextureFloat(); + testOESVertexArrayObject(); + // Only the WEBGL_lose_context extension should be the same object after context lost. + new_WEBGL_lose_context = reGetExtensionAndTestForProperty(gl, "WEBGL_lose_context", true); +} + +function testRestoredContext() +{ + debug("Test restored context"); + shouldBeFalse("contextRestoredEventFired"); + contextRestoredEventFired = true; + shouldBeFalse("gl.isContextLost()"); + shouldBe("gl.getError()", "gl.NO_ERROR"); + + // Validate that using old resources fails. + testResources(gl.INVALID_OPERATION); + + testRendering(); + + // Validate new resources created in testRendering(). + testResources(gl.NO_ERROR); + + testExtensions(); + + debug(""); +} + + +</script> +</head> +<body onload="init()"> +<div id="description"></div> +<div id="console"></div> +</body> +</html> 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> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-no-alpha-fbo-with-alpha.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-no-alpha-fbo-with-alpha.html new file mode 100644 index 0000000000..81fc80ee5f --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-no-alpha-fbo-with-alpha.html @@ -0,0 +1,77 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> + +<script> +"use strict"; + +var wtu = WebGLTestUtils; + +// This declaration needs to be global for "shouldBe" to see it +var gl; + +function init() +{ + description('Verify that a WebGL context with alpha:false still works correctly after handling textures with an alpha channel.'); + + runTest(); +} + +function getWebGL(contextAttribs) +{ + return wtu.create3DContext("c", contextAttribs); +} + +function runTest() +{ + var buf = new Uint8Array(1 * 1 * 4); + shouldBeNonNull("gl = getWebGL({ alpha: false, antialias: false })"); + + // Clear to black. Alpha channel of clearColor() is ignored. + gl.clearColor(0.0, 0.0, 0.0, 0.7); + gl.clear(gl.COLOR_BUFFER_BIT); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255], + "Alpha channel of clearColor should be ignored"); + + wtu.waitForComposite(function() { + // Make a new framebuffer and attach a texture with an alpha channel. + var fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + var texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + + // Clear texture. Note that alpha channel is not 1.0. + gl.clearColor(1.0, 0.0, 0.0, 0.5); + gl.clear(gl.COLOR_BUFFER_BIT); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 0, 128], + "Alpha channel of clearColor should be obeyed for FBO with alpha channel", + 1); + + // Bind back buffer and check that its alpha channel is still 1.0. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255], + "Alpha channel of back buffer should still be 255"); + finishTest(); + }); +} + +</script> +</head> +<body onload="init()"> +<div id="description"></div> +<div id="console"></div> +<canvas width="20" height="20" style="border: 1px solid blue;" id="c"></canvas> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-upon-reload.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-upon-reload.html new file mode 100644 index 0000000000..fbd3a61741 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-upon-reload.html @@ -0,0 +1,72 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Context Release 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> +<iframe id="host" style="width: 256px; height: 256px; border: 0;"></iframe> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +description("This test ensures that WebGL contexts are released properly upon page reload"); + +var wtu = WebGLTestUtils; + +var host = document.getElementById("host"); +var testIterations = 25; +var currentIteration = 0; + +function refreshFrame() { + if(currentIteration < testIterations) { + currentIteration++; + debug(""); + debug("Test " + currentIteration + " of " + testIterations); + host.src = "resources/context-release-upon-reload-child.html"; + } else { + finishTest(); + } +} + +function testContext() { + var gl = host.contentWindow.glContext; + assertMsg(gl != null, "context was created properly"); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors"); + + if(gl.canvas.width != gl.drawingBufferWidth || + gl.canvas.height != gl.drawingBufferHeight) { + testFailed("Buffer was the wrong size: " + + gl.drawingBufferWidth + "x" + gl.drawingBufferHeight); + } else { + testPassed("Buffer was the correct size: " + + gl.drawingBufferWidth + "x" + gl.drawingBufferHeight); + refreshFrame(); + } + + gl = null; +} + +window.addEventListener("message", function(event) { + if(event.data == "Ready") { + testContext(); + } +}); + +refreshFrame(); + +var successfullyParsed = true; +</script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-with-workers.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-with-workers.html new file mode 100644 index 0000000000..23037fd3c1 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-with-workers.html @@ -0,0 +1,72 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Context Release 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> +<iframe id="host" style="width: 256px; height: 256px; border: 0;"></iframe> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +description("This test ensures that WebGL contexts are released properly when a worker is used"); + +var wtu = WebGLTestUtils; + +var host = document.getElementById("host"); +var testIterations = 25; +var currentIteration = 0; + +function refreshFrame() { + if(currentIteration < testIterations) { + currentIteration++; + debug(""); + debug("Test " + currentIteration + " of " + testIterations); + host.src = "resources/context-release-child-with-worker.html"; + } else { + finishTest(); + } +} + +function testContext() { + var gl = host.contentWindow.glContext; + assertMsg(gl != null, "context was created properly"); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors"); + + if(gl.canvas.width != gl.drawingBufferWidth || + gl.canvas.height != gl.drawingBufferHeight) { + testFailed("Buffer was the wrong size: " + + gl.drawingBufferWidth + "x" + gl.drawingBufferHeight); + } else { + testPassed("Buffer was the correct size: " + + gl.drawingBufferWidth + "x" + gl.drawingBufferHeight); + refreshFrame(); + } + + gl = null; +} + +window.addEventListener("message", function(event) { + if(event.data == "Ready") { + testContext(); + } +}); + +refreshFrame(); + +var successfullyParsed = true; +</script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-size-change.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-size-change.html new file mode 100644 index 0000000000..638d7a7099 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-size-change.html @@ -0,0 +1,92 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> + +<script> +"use strict"; + +// These declarations need to be global for "shouldBe" to see them +var gl; +var pixel = [0, 0, 0, 1]; +var canvas; + +function init() +{ + description('Verify that changing the size of an antialiased WebGL context does not cause it to stop working.'); + + runTest(); +} + +function getWebGL(canvasWidth, canvasHeight, contextAttribs) +{ + canvas = document.createElement("canvas"); + if (!canvas) + return null; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + + gl = WebGLTestUtils.create3DContext(canvas, contextAttribs); + if (!gl) + return null; + + return gl; +} + +function runTest() +{ + shouldBeNonNull("gl = getWebGL(1, 1, { alpha: false, antialias: true })"); + + // Clear to black. + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + // Check that the pixel's R channel is 0. + var buf = new Uint8Array(1 * 1 * 4); + gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf); + pixel[0] = buf[0]; + shouldBeTrue("pixel[0] == 0"); + + // Change the size of the canvas. + canvas.width = 3; + canvas.height = 3; + + // Clear to black. + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + // Clear the top-left pixel to white. + gl.enable(gl.SCISSOR_TEST); + gl.scissor(0, 0, 1, 1); + gl.clearColor(1.0, 1.0, 1.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + // Check that the top-left pixel has R channel 255. + gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf); + pixel[0] = buf[0]; + shouldBeTrue("pixel[0] == 255"); + + // Check that the bottom-right pixel has R channel 0. + gl.readPixels(2, 2, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf); + pixel[0] = buf[0]; + shouldBeTrue("pixel[0] == 0"); + + finishTest(); +} + +</script> +</head> +<body onload="init()"> +<div id="description"></div> +<div id="console"></div> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-type-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-type-test.html new file mode 100644 index 0000000000..1aa315219a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-type-test.html @@ -0,0 +1,53 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Canvas Conformance Tests</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> +<canvas id="canvas2d" width="40" height="40"> </canvas> +<script> +"use strict"; +description("This test ensures WebGL implementations interact correctly with the canvas tag."); + +debug(""); +debug("Canvas.getContext"); + +assertMsg(window.WebGLRenderingContext, + "WebGLRenderingContext should be a member of window"); +assertMsg('WebGLRenderingContext' in window, + "WebGLRenderingContext should be 'in' window"); +assertMsg(Object.getPrototypeOf(WebGLRenderingContext.prototype) === Object.prototype, + "WebGLRenderingContext should only have Object in it's prototype chain"); + +var wtu = WebGLTestUtils; +var canvas = document.getElementById("canvas"); +var gl = wtu.create3DContext(canvas); +if (!gl) { + testFailed("context does not exist"); +} else { + testPassed("context exists"); + + debug("Checking context type"); + assertMsg(gl instanceof WebGLRenderingContext, + "context type should be WebGLRenderingContext"); +} +debug(""); +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/deleted-object-behavior.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/deleted-object-behavior.html new file mode 100644 index 0000000000..525f399678 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/deleted-object-behavior.html @@ -0,0 +1,237 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Deleted Object Behavior</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="canvases"> +<canvas id="canvas1"> +</div> +<div id="console"></div> + +<script> +"use strict"; +description("Verifies behavior of deleted objects"); + +const wtu = WebGLTestUtils; +const canvas1 = document.getElementById("canvas1"); +const sz = 64; +canvas1.width = sz; +canvas1.height = sz; +const gl = wtu.create3DContext("canvas1"); +let tex, rb; // for shouldBe + +function testBoundFBOTexture() { + debug("Verifies that a texture attached to a bound framebuffer and then deleted is automatically detached"); + + let fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sz, sz, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup"); + // The WebGL 1.0 spec guarantees that this combination of attachments results + // in a complete framebuffer. + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE", + "Framebuffer should be complete after setup"); + debug("Texture should still be bound to the context"); + shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex"); + // Delete the texture. + gl.deleteTexture(tex); + debug("Texture should have been unbound from the context"); + shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)"); + debug("Framebuffer should report that the texture was detached"); + shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE"); + debug("Framebuffer should be incomplete after texture was deleted"); + shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + debug("Texture should not report that it's still a texture after deletion"); + shouldBe("gl.isTexture(tex)", "false"); + // Framebuffer should not function. + gl.clearColor(0.0, 1.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "Framebuffer should not work after deleting its only attachment"); + // Default framebuffer shouldn't have been touched. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying default framebuffer's contents"); + // Attempt to bind deleted texture should fail. + gl.bindTexture(gl.TEXTURE_2D, tex); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted texture"); + debug(""); + gl.deleteFramebuffer(fb); +} + +function testUnboundFBOTexture() { + debug("Verifies that a texture attached to an unbound framebuffer and then deleted remains usable until detached"); + + let fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sz, sz, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup"); + // The WebGL 1.0 spec guarantees that this combination of attachments results + // in a complete framebuffer. + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE", + "Framebuffer should be complete after setup"); + // Unbind the framebuffer from the context so that deleting the texture + // doesn't automatically unbind it from the framebuffer. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + debug("Texture should still be bound to the context"); + shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex"); + // Delete the texture. + gl.deleteTexture(tex); + debug("Texture should have been unbound from the context"); + shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)"); + // Framebuffer should still be complete. + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + debug("Framebuffer should still be complete after texture was deleted"); + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + debug("Framebuffer should report that the texture is still attached"); + shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex"); + debug("Texture should not report that it's still a texture after deletion"); + shouldBe("gl.isTexture(tex)", "false"); + // Framebuffer should still function. + gl.clearColor(0.0, 1.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 255, 0, 255], "framebuffer should be green"); + // Deleting texture a second time should not unbind it from the framebuffer. + gl.deleteTexture(tex); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "deleting an object twice is not an error"); + debug("Framebuffer should still report that the texture is attached"); + shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex"); + // Default framebuffer shouldn't have been touched. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying framebuffers' contents"); + // Attempt to bind deleted texture should fail. + gl.bindTexture(gl.TEXTURE_2D, tex); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted texture"); + debug(""); + gl.deleteFramebuffer(fb); +} + +function testBoundFBORenderbuffer() { + debug("Verifies that a renderbuffer attached to a bound framebuffer and then deleted is automatically detached"); + + let fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + rb = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rb); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, sz, sz) + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup"); + // The WebGL 1.0 spec doesn't guarantee that this framebuffer configuration + // will be complete. + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { + debug("Framebuffer with GL_RGBA4 renderbuffer was incomplete; skipping test"); + return; + } + debug("Renderbuffer should still be bound to the context"); + shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rb"); + // Delete the renderbuffer. + gl.deleteRenderbuffer(rb); + debug("Renderbuffer should have been unbound from the context"); + shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)"); + debug("Framebuffer should report that the texture was detached"); + shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE"); + debug("Framebuffer should be incomplete after renderbuffer was deleted"); + shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + debug("Renderbuffer should not report that it's still a renderbuffer after deletion"); + shouldBe("gl.isRenderbuffer(rb)", "false"); + // Framebuffer should not function. + gl.clearColor(0.0, 1.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "Framebuffer should not work after deleting its only attachment"); + // Default framebuffer shouldn't have been touched. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying framebuffers' contents"); + // Attempt to bind deleted renderbuffer should fail. + gl.bindRenderbuffer(gl.RENDERBUFFER, rb); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted renderbuffer"); + debug(""); + gl.deleteFramebuffer(fb); +} + +function testUnboundFBORenderbuffer() { + debug("Verifies that a renderbuffer attached to an unbound framebuffer and then deleted remains usable until detached"); + + let fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + rb = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rb); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, sz, sz) + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup"); + // The WebGL 1.0 spec doesn't guarantee that this framebuffer configuration + // will be complete. + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { + debug("Framebuffer with GL_RGBA4 renderbuffer was incomplete; skipping test"); + return; + } + // Unbind the framebuffer from the context so that deleting the renderbuffer + // doesn't automatically unbind it from the framebuffer. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + debug("Renderbuffer should still be bound to the context"); + shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rb"); + // Delete the renderbuffer. + gl.deleteRenderbuffer(rb); + debug("Renderbuffer should have been unbound from the context"); + shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)"); + // Framebuffer should still be complete. + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + debug("Framebuffer should still be complete after renderbuffer was deleted"); + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + debug("Framebuffer should report that the renderbuffer is still attached"); + shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rb"); + debug("Renderbuffer should not report that it's still a renderbuffer after deletion"); + shouldBe("gl.isRenderbuffer(rb)", "false"); + // Framebuffer should still function. + gl.clearColor(0.0, 1.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + // Use a high tolerance to accommodate low bit depth precision. + wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 255, 0, 255], "framebuffer should be green", 20); + // Deleting renderbuffer a second time should not unbind it from the framebuffer. + gl.deleteRenderbuffer(rb); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "deleting an object twice is not an error"); + debug("Framebuffer should still report that the renderbuffer is attached"); + shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rb"); + // Default framebuffer shouldn't have been touched. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying framebuffers' contents"); + // Attempt to bind deleted renderbuffer should fail. + gl.bindRenderbuffer(gl.RENDERBUFFER, rb); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted renderbuffer"); + debug(""); + gl.deleteFramebuffer(fb); +} + +function runTests() { + testBoundFBOTexture(); + testUnboundFBOTexture(); + testBoundFBORenderbuffer(); + testUnboundFBORenderbuffer(); + finishTest(); +} + +requestAnimationFrame(runTests); + +var successfullyParsed = true; +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/incorrect-context-object-behaviour.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/incorrect-context-object-behaviour.html new file mode 100644 index 0000000000..30d9b04708 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/incorrect-context-object-behaviour.html @@ -0,0 +1,165 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> + +<script> +"use strict"; +description("Tests calling WebGL APIs with objects from other contexts"); + +var wtu = WebGLTestUtils; +var contextA = wtu.create3DContext(); +var contextB = wtu.create3DContext(); +var bufferA = contextA.createBuffer(); +var bufferB = contextB.createBuffer(); +var frameBufferA = contextA.createFramebuffer(); +var frameBufferB = contextB.createFramebuffer(); +var programA = wtu.loadStandardProgram(contextA); +var programB = wtu.loadStandardProgram(contextB); +var renderBufferA = contextA.createRenderbuffer(); +var renderBufferB = contextB.createRenderbuffer(); +var shaderA = wtu.loadStandardVertexShader(contextA); +var shaderB = wtu.loadStandardVertexShader(contextB); +var textureA = contextA.createTexture(); +var textureB = contextB.createTexture(); +var locationA = contextA.getUniformLocation(programA, 'u_modelViewProjMatrix'); +var locationB = contextB.getUniformLocation(programB, 'u_modelViewProjMatrix'); +var uniformData = []; + +function generateFloat32Array(length) { + uniformData = new Float32Array(length); +} + +function generateFloatArray(length) { + uniformData = new Array(length); + for (var i = 0; i < length; i++) { + uniformData[i] = 0.0; + } +} + +function generateInt32Array(length) { + uniformData = new Int32Array(length); +} + +function generateIntArray(length) { + uniformData = new Array(length); + for (var i = 0; i < length; i++) { + uniformData[i] = 0; + } +} + +// Make the bindable objects valid in both contexts first. +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindBuffer(contextA.ARRAY_BUFFER, bufferA)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindBuffer(contextA.ARRAY_BUFFER, null)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindBuffer(contextB.ARRAY_BUFFER, bufferB)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindBuffer(contextB.ARRAY_BUFFER, null)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferA)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, null)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindFramebuffer(contextB.FRAMEBUFFER, frameBufferB)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindFramebuffer(contextB.FRAMEBUFFER, null)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferA)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, null)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindRenderbuffer(contextB.RENDERBUFFER, renderBufferB)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindRenderbuffer(contextB.RENDERBUFFER, null)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindTexture(contextA.TEXTURE_2D, textureA)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindTexture(contextA.TEXTURE_2D, null)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindTexture(contextB.TEXTURE_2D, textureB)"); +wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindTexture(contextB.TEXTURE_2D, null)"); + +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programA, shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programB, shaderA)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programB, shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindAttribLocation(programB, 0, 'foo')"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindBuffer(contextA.ARRAY_BUFFER, bufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindTexture(contextA.TEXTURE_2D, textureB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.compileShader(shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteBuffer(bufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteFramebuffer(frameBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteProgram(programB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteRenderbuffer(renderBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteShader(shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteShader(shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteTexture(textureB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programA, shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programB, shaderA)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programB, shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferRenderbuffer(contextA.FRAMEBUFFER, contextA.DEPTH_ATTACHMENT, contextA.RENDERBUFFER, renderBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferTexture2D(contextA.FRAMEBUFFER, contextA.COLOR_ATTACHMENT0, contextA.TEXTURE_2D, textureB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveAttrib(programB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveUniform(programB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getAttachedShaders(programB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getAttribLocation(programB, 'a_vertex')"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getProgramParameter(programB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getProgramInfoLog(programB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderParameter(shaderB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderInfoLog(shaderB, 0)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderSource(shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniform(programB, locationA)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniform(programA, locationB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniformLocation(programB, 'u_modelViewProjMatrix')"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isBuffer(bufferB)"); +shouldBeFalse("contextA.isBuffer(bufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isFramebuffer(frameBufferB)"); +shouldBeFalse("contextA.isFramebuffer(frameBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isProgram(programB)"); +shouldBeFalse("contextA.isProgram(programB)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isRenderbuffer(renderBufferB)"); +shouldBeFalse("contextA.isRenderbuffer(renderBufferB)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isShader(shaderB)"); +shouldBeFalse("contextA.isShader(shaderB)"); +wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isTexture(textureB)"); +shouldBeFalse("contextA.isTexture(textureB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.linkProgram(programB)"); +wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.shaderSource(shaderB, 'foo')"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1f(locationB, 0.0)"); +generateFloat32Array(1); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1fv(locationB, uniformData)"); +generateFloatArray(1); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1fv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1i(locationB, 0)"); +generateInt32Array(1); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1iv(locationB, uniformData)"); +generateIntArray(1); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1iv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2f(locationB, 0.0, 0.0)"); +generateFloat32Array(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2fv(locationB, uniformData)"); +generateFloatArray(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2fv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2i(locationB, 0, 0)"); +generateInt32Array(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2iv(locationB, uniformData)"); +generateIntArray(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2iv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3f(locationB, 0.0, 0.0, 0.0)"); +generateFloat32Array(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3fv(locationB, uniformData)"); +generateFloatArray(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3fv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3i(locationB, 0, 0, 0)"); +generateInt32Array(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3iv(locationB, uniformData)"); +generateIntArray(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3iv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4f(locationB, 0.0, 0.0, 0.0, 0.0)"); +generateFloat32Array(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4fv(locationB, uniformData)"); +generateFloatArray(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4fv(locationB, uniformData)"); + wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4i(locationB, 0, 0, 0, 0)"); +generateInt32Array(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4iv(locationB, uniformData)"); +generateIntArray(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4iv(locationB, uniformData)"); +generateFloat32Array(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2fv(locationB, false, uniformData)"); +generateFloatArray(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2fv(locationB, false, uniformData)"); +generateFloat32Array(9); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3fv(locationB, false, uniformData)"); +generateFloatArray(9); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3fv(locationB, false, uniformData)"); +generateFloat32Array(16); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4fv(locationB, false, uniformData)"); +generateFloatArray(16); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4fv(locationB, false, uniformData)"); + +var successfullyParsed = true; +</script> + +<script src="../../js/js-test-post.js"></script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/methods.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/methods.html new file mode 100644 index 0000000000..d1e47f32a3 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/methods.html @@ -0,0 +1,178 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL Methods 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/tests/context-methods.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> +<script> +"use strict"; +description("This test ensures that the WebGL context has all the methods in the specification."); + +const methods = [ + "getContextAttributes", + "activeTexture", + "attachShader", + "bindAttribLocation", + "bindBuffer", + "bindFramebuffer", + "bindRenderbuffer", + "bindTexture", + "blendColor", + "blendEquation", + "blendEquationSeparate", + "blendFunc", + "blendFuncSeparate", + "bufferData", + "bufferSubData", + "checkFramebufferStatus", + "clear", + "clearColor", + "clearDepth", + "clearStencil", + "colorMask", + "compileShader", + "compressedTexImage2D", + "compressedTexSubImage2D", + "copyTexImage2D", + "copyTexSubImage2D", + "createBuffer", + "createFramebuffer", + "createProgram", + "createRenderbuffer", + "createShader", + "createTexture", + "cullFace", + "deleteBuffer", + "deleteFramebuffer", + "deleteProgram", + "deleteRenderbuffer", + "deleteShader", + "deleteTexture", + "depthFunc", + "depthMask", + "depthRange", + "detachShader", + "disable", + "disableVertexAttribArray", + "drawArrays", + "drawElements", + "enable", + "enableVertexAttribArray", + "finish", + "flush", + "framebufferRenderbuffer", + "framebufferTexture2D", + "frontFace", + "generateMipmap", + "getActiveAttrib", + "getActiveUniform", + "getAttachedShaders", + "getAttribLocation", + "getParameter", + "getBufferParameter", + "getError", + "getExtension", + "getFramebufferAttachmentParameter", + "getProgramParameter", + "getProgramInfoLog", + "getRenderbufferParameter", + "getShaderParameter", + "getShaderInfoLog", + "getShaderPrecisionFormat", + "getShaderSource", + "getSupportedExtensions", + "getTexParameter", + "getUniform", + "getUniformLocation", + "getVertexAttrib", + "getVertexAttribOffset", + "hint", + "isBuffer", + "isContextLost", + "isEnabled", + "isFramebuffer", + "isProgram", + "isRenderbuffer", + "isShader", + "isTexture", + "lineWidth", + "linkProgram", + "pixelStorei", + "polygonOffset", + "readPixels", + "renderbufferStorage", + "sampleCoverage", + "scissor", + "shaderSource", + "stencilFunc", + "stencilFuncSeparate", + "stencilMask", + "stencilMaskSeparate", + "stencilOp", + "stencilOpSeparate", + "texImage2D", + "texParameterf", + "texParameteri", + "texSubImage2D", + "uniform1f", + "uniform1fv", + "uniform1i", + "uniform1iv", + "uniform2f", + "uniform2fv", + "uniform2i", + "uniform2iv", + "uniform3f", + "uniform3fv", + "uniform3i", + "uniform3iv", + "uniform4f", + "uniform4fv", + "uniform4i", + "uniform4iv", + "uniformMatrix2fv", + "uniformMatrix3fv", + "uniformMatrix4fv", + "useProgram", + "validateProgram", + "vertexAttrib1f", + "vertexAttrib1fv", + "vertexAttrib2f", + "vertexAttrib2fv", + "vertexAttrib3f", + "vertexAttrib3fv", + "vertexAttrib4f", + "vertexAttrib4fv", + "vertexAttribPointer", + "viewport" +]; + +debug(""); +debug("Canvas.getContext"); + +const wtu = WebGLTestUtils; +const canvas = document.getElementById("canvas"); +const gl = wtu.create3DContext(canvas); + +testContextMethods(gl, methods); + +debug(""); +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/premultiplyalpha-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/premultiplyalpha-test.html new file mode 100644 index 0000000000..ecbe251611 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/premultiplyalpha-test.html @@ -0,0 +1,251 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test the WebGL premultipliedAlpha context creation flag.</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"> </script> +</head> +<body> +<div id="description"></div><div id="console"></div> +<script> +"use strict"; +var wtu = WebGLTestUtils; + +// wtu.create3DContext(...) will set antialias to false by default +// if the antialias property is not set to true explicitly. +// To cover the antialias case, it needs to set antialias to true +// explicitly. +var tests = [ + // If premultipliedAlpha is true and antialias is false then + // [texture] [canvas] [dataURL] + // 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128 + { creationAttributes: {}, + sentColor: [32, 64, 128, 128], + expectedColor: [64, 128, 255, 128], + errorRange: 2, + imageFormat: "image/png" + }, + // If premultipliedAlpha is true and antialias is true then + // [texture] [canvas] [dataURL] + // 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128 + { creationAttributes: {antialias: true}, + sentColor: [32, 64, 128, 128], + expectedColor: [64, 128, 255, 128], + errorRange: 2, + imageFormat: "image/png" + }, + // If premultipliedAlpha is true and antialias is false then + // [texture] [canvas] [texture] + // 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128 + { creationAttributes: {}, + sentColor: [32, 64, 128, 128], + expectedColor: [64, 128, 255, 128], + errorRange: 2, + }, + // If premultipliedAlpha is true and antialias is true then + // [texture] [canvas] [texture] + // 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128 + { creationAttributes: {antialias: true}, + sentColor: [32, 64, 128, 128], + expectedColor: [64, 128, 255, 128], + errorRange: 2, + }, + // If premultipliedAlpha is false and antialias is false then + // [texture] [canvas] [dataURL] + // 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1 + { creationAttributes: {premultipliedAlpha: false}, + sentColor: [255, 192, 128, 1], + expectedColor: [255, 192, 128, 1], + errorRange: 0, + imageFormat: "image/png" + }, + // If premultipliedAlpha is false and antialias is true then + // [texture] [canvas] [dataURL] + // 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1 + { creationAttributes: {premultipliedAlpha: false, antialias: true}, + sentColor: [255, 192, 128, 1], + expectedColor: [255, 192, 128, 1], + errorRange: 0, + imageFormat: "image/png" + }, + // If premultipliedAlpha is false and antialias is false then + // [texture] [canvas] [texture] + // 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1 + { creationAttributes: {premultipliedAlpha: false}, + sentColor: [255, 192, 128, 1], + expectedColor: [255, 192, 128, 1], + errorRange: 0, + }, + // If premultipliedAlpha is false and antialias is true then + // [texture] [canvas] [texture] + // 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1 + { creationAttributes: {premultipliedAlpha: false, antialias: true}, + sentColor: [255, 192, 128, 1], + expectedColor: [255, 192, 128, 1], + errorRange: 0, + }, + // If premultipliedAlpha is false and antialias is false then + // [texture] [canvas] [dataURL] + // 255, 255, 255, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255 + { creationAttributes: {premultipliedAlpha: false}, + sentColor: [255, 255, 255, 128], + expectedColor: [128, 128, 128, 255], + errorRange: 2, + imageFormat: "image/jpeg" + }, + // If premultipliedAlpha is false and antialias is true then + // [texture] [canvas] [dataURL] + // 255, 255, 255, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255 + { creationAttributes: {premultipliedAlpha: false, antialias: true}, + sentColor: [255, 255, 255, 128], + expectedColor: [128, 128, 128, 255], + errorRange: 2, + imageFormat: "image/jpeg" + }, + // If premultipliedAlpha is true and antialias is false then + // [texture] [canvas] [dataURL] + // 128, 128, 128, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255 + { creationAttributes: {}, + sentColor: [128, 128, 128, 128], + expectedColor: [128, 128, 128, 255], + errorRange: 2, + imageFormat: "image/jpeg" + }, + // If premultipliedAlpha is true and antialias is true then + // [texture] [canvas] [dataURL] + // 128, 128, 128, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255 + { creationAttributes: {antialias: true}, + sentColor: [128, 128, 128, 128], + expectedColor: [128, 128, 128, 255], + errorRange: 2, + imageFormat: "image/jpeg" + } +]; + +var g_count = 0; +var gl; +var canvas; +var premultipliedAlpha; + +enableJSTestPreVerboseLogging(); +description("Test the WebGL premultipliedAlpha context creation flag."); +doNextTest(); +function doNextTest() { + if (g_count < tests.length) { + var test = tests[g_count++]; + canvas = document.createElement("canvas"); + // Need to preserve drawing buffer to load it in a callback + test.creationAttributes.preserveDrawingBuffer = true; + gl = wtu.create3DContext(canvas, test.creationAttributes); + var premultipliedAlpha = test.creationAttributes.premultipliedAlpha != false; + var antialias = test.creationAttributes.antialias == true; + debug("") + debug("testing: premultipliedAlpha: " + premultipliedAlpha + + ", antialias: " + antialias + + ", imageFormat: " + test.imageFormat); + + if (!gl) { + testFailed("context does not exist"); + doNextTest(); + return; + } + + shouldBe('gl.getContextAttributes().premultipliedAlpha', premultipliedAlpha.toString()); + shouldBeTrue('gl.getContextAttributes().preserveDrawingBuffer'); + + wtu.log(gl.getContextAttributes()); + var program = wtu.setupTexturedQuad(gl); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + var tex = gl.createTexture(); + wtu.fillTexture(gl, tex, 2, 2, test.sentColor, 0); + var loc = gl.getUniformLocation(program, "tex"); + gl.uniform1i(loc, 0); + 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); + + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from drawing."); + + var loadTexture = function() { + debug("loadTexture called"); + var pngTex = gl.createTexture(); + // not needed as it's the default + // gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);'); + gl.bindTexture(gl.TEXTURE_2D, pngTex); + if (test.imageFormat) { + // create texture from image + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this); + } else { + // create texture from canvas + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas); + } + 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); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from creating copy."); + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from 2nd drawing."); + wtu.checkCanvas( + gl, test.expectedColor, + "should draw with " + test.expectedColor, test.errorRange); + + doNextTest(); + } + + var loadTextureError = function() { + testFailed("Creating image from canvas failed. Image src: " + this.src); + finishTest(); + } + + var shrinkString = function(string) { + if (string.length < 63) { + return string; + } + return string.substr(0, 30) + "..." + string.substr(string.length - 30); + } + + if (test.imageFormat) { + // Load canvas into string using toDataURL + debug("Calling canvas.toDataURL('" + test.imageFormat + "')"); + var imageUrl = canvas.toDataURL(test.imageFormat); + debug("imageUrl = '" + shrinkString(imageUrl) + "'"); + if (test.imageFormat != "image/png" && + (imageUrl.indexOf("data:image/png,") == 0 || + imageUrl.indexOf("data:image/png;") == 0)) { + debug("Image format " + test.imageFormat + " not supported; skipping"); + setTimeout(doNextTest, 0); + } else { + // Load string into the texture + debug("Waiting for image.onload"); + var input = wtu.makeImage(imageUrl, loadTexture, loadTextureError); + } + } else { + // Load canvas into the texture asynchronously (to prevent unbounded stack consumption) + debug("Waiting for setTimeout"); + setTimeout(loadTexture, 0); + } + } else { + var successfullyParsed = true; + finishTest(); + } +} + +</script> + +</body> +</html> + + diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-child-with-worker.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-child-with-worker.html new file mode 100644 index 0000000000..66408c0ef2 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-child-with-worker.html @@ -0,0 +1,55 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html style="margin: 0; padding: 0;"> +<head> +<meta charset="utf-8"> +<title>Simple WebGL context with Worker</title> +<script src="../../../js/webgl-test-utils.js"> </script> +</head> +<body style="margin: 0; padding: 0; overflow: hidden;"> +<canvas id="c" width="1680" height="1050" style="width: 256px; height: 256px;"> <!-- scaled to fit page better --> +<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"; +var wtu = WebGLTestUtils; +var myWorker = new Worker("context-release-worker.js"); + +var gl = wtu.create3DContext("c", { antialias: false }); +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.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW); +gl.enableVertexAttribArray(0); +gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + +gl.clearColor(0.0, 0.0, 0.0, 1.0); +gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); +gl.drawArrays(gl.TRIANGLES, 0, 3); + +if (parent) { + window.glContext = gl; + parent.postMessage("Ready", "*"); +} +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-upon-reload-child.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-upon-reload-child.html new file mode 100644 index 0000000000..9f06c41d4e --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-upon-reload-child.html @@ -0,0 +1,54 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html style="margin: 0; padding: 0;"> +<head> +<meta charset="utf-8"> +<title>Simple WebGL context</title> +<script src="../../../js/webgl-test-utils.js"> </script> +</head> +<body style="margin: 0; padding: 0; overflow: hidden;"> +<canvas id="c" width="1680" height="1050" style="width: 256px; height: 256px;"> <!-- scaled to fit page better --> +<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"; +var wtu = WebGLTestUtils; + +var gl = wtu.create3DContext("c", { antialias: false }); +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.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW); +gl.enableVertexAttribArray(0); +gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); + +gl.clearColor(0.0, 0.0, 0.0, 1.0); +gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); +gl.drawArrays(gl.TRIANGLES, 0, 3); + +if (parent) { + window.glContext = gl; + parent.postMessage("Ready", "*"); +} +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-worker.js b/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-worker.js new file mode 100644 index 0000000000..3680117c25 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-worker.js @@ -0,0 +1,4 @@ +// Simple worker used to provoke WebGL context release bugs on Chrome + +postMessage("Hello World"); +close();
\ No newline at end of file diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/user-defined-properties-on-context.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/user-defined-properties-on-context.html new file mode 100644 index 0000000000..4029087c1f --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/user-defined-properties-on-context.html @@ -0,0 +1,49 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL User-Defined Properties 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 onload="initialize()"> +<div id="description"></div> +<div id="console"></div> +<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> +<script> +"use strict"; +description("This test ensures that if user-defined properties are set on the WebGL context object, that they don't disappear after garbage collection."); + +var gl2 = null; + +function initialize() { + var wtu = WebGLTestUtils; + var canvas = document.getElementById("canvas"); + var gl1 = wtu.create3DContext(canvas); + if (!gl1) { + testFailed("WebGL context does not exist"); + finishTest(); + } else { + testPassed("WebGL context exists"); + gl1.myProperty = 2; + wtu.requestAnimFrame(runTest); + } +} + +function runTest() { + webglHarnessCollectGarbage(); + var wtu = WebGLTestUtils; + var canvas = document.getElementById("canvas"); + gl2 = wtu.create3DContext(canvas); + shouldBe('gl2.myProperty', '2'); + finishTest(); +} +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/zero-sized-canvas.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/zero-sized-canvas.html new file mode 100644 index 0000000000..13e1338865 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/zero-sized-canvas.html @@ -0,0 +1,59 @@ +<!-- +Copyright (c) 2020 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; + +// Global declarations so that "shouldBe" can eval with them: +let gl; + +(function() { + description('Check that zero-sized canvases work with WebGL.'); + + testZero(); + + finishTest(); +})(); + +function testZero() { + const canvas = document.createElement('canvas'); + canvas.width = 0; + canvas.height = 0; + gl = WebGLTestUtils.create3DContext(canvas); + + expectTrue(gl, `Context creation with ${canvas.width}x${canvas.height} canvas should succeed.`); + shouldBe('gl.drawingBufferWidth', '1'); + shouldBe('gl.drawingBufferHeight', '1'); + shouldBeFalse('gl.isContextLost()'); + + const version = gl.getParameter(gl.VERSION); + expectTrue(version && version.length, `getParameter() should return something.`); + + debug('canvas.width = 2'); + canvas.width = 2; + shouldBe('gl.drawingBufferWidth', '2'); + shouldBeFalse('gl.isContextLost()'); + + debug('canvas.width = 0'); + canvas.width = 0; + shouldBe('gl.drawingBufferWidth', '1'); + shouldBeFalse('gl.isContextLost()'); +} + +</script> +</body> +</html> |