| <!-- |
| 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> |
| |
| |