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/textures/misc/gl-teximage.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html new file mode 100644 index 0000000000..897377534c --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html @@ -0,0 +1,406 @@ +<!-- +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 texImage2D conformance test.</title> +<link rel="stylesheet" href="../../../resources/js-test-style.css"/> +<script src="../../../js/js-test-pre.js"></script> +<script src="../../../js/webgl-test-utils.js"> </script> +</head> +<body> +<canvas id="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +enableJSTestPreVerboseLogging(); +description("Test texImage2D conversions."); +var wtu = WebGLTestUtils; +var gl = wtu.create3DContext("example"); +gl.disable(gl.DITHER); +var program = wtu.setupTexturedQuad(gl); +var successfullyParsed; + +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + +var imgURLs = [ + '../../../resources/1-channel.jpg', + '../../../resources/gray-ramp-256-with-128-alpha.png', + '../../../resources/gray-ramp-256.png', + '../../../resources/gray-ramp-default-gamma.png', + '../../../resources/gray-ramp-gamma0.1.png', + '../../../resources/gray-ramp-gamma1.0.png', + '../../../resources/gray-ramp-gamma2.0.png', + '../../../resources/gray-ramp-gamma4.0.png', + '../../../resources/gray-ramp-gamma9.0.png', + '../../../resources/gray-ramp.png', + '../../../resources/zero-alpha.png', + '../../../resources/3x3.png', + '../../../resources/blue-1x1.jpg', + '../../../resources/red-indexed.png', + '../../../resources/transparent-on-left-indexed.png', + '../../../resources/green-2x2-16bit.png', + '../../../resources/small-square-with-colorspin-profile.jpg', + '../../../resources/small-square-with-colorspin-profile.png', + '../../../resources/small-square-with-cie-rgb-profile.png', + '../../../resources/small-square-with-colormatch-profile.png', + '../../../resources/small-square-with-e-srgb-profile.png', + '../../../resources/small-square-with-smpte-c-profile.png', + '../../../resources/small-square-with-srgb-iec61966-2.1-profile.png']; + + +wtu.loadImagesAsync(imgURLs, runTests); + +function runTests(imgs) { + var loc = gl.getUniformLocation(program, "tex"); + gl.uniform1i(loc, 0); + + gl.disable(gl.BLEND); + gl.disable(gl.DEPTH_TEST); + + var width = gl.canvas.width; + var height = gl.canvas.height; + + function checkPixel(x, y, color) { + wtu.checkCanvasRect(gl, x, y, 1, 1, color); + } + + function checkPixelRange(x, y, color, allowedRange) { + var msg = "pixel " + x + ", " + y + " should be within " + + allowedRange + " units of " + + color[0] + ", " + + color[1] + ", " + + color[2] + ", " + + color[3]; + wtu.checkCanvasRect(gl, x, y, 1, 1, color, msg, allowedRange); + } + + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + + var buf = new Uint8Array(width * height * 4); + + debug(""); + debug("check pixels are NOT pre-multiplied"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/zero-alpha.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + + var left = 0; + var middle = Math.floor(width / 2); + var right = width - 1; + var bottom = 0; + var center = Math.floor(height / 2); + var top = height - 1; + checkPixel(left, top, [ 0, 0, 0, 255]); + checkPixel(middle, top, [255, 0, 255, 255]); + checkPixel(right, top, [ 0, 0, 255, 255]); + checkPixel(left, center, [128, 128, 128, 255]); + checkPixel(middle, center, [255, 255, 255, 255]); + checkPixel(right, center, [ 0, 255, 255, 255]); + checkPixel(left, bottom, [255, 0, 0, 255]); + checkPixel(middle, bottom, [255, 255, 0, 255]); + checkPixel(right, bottom, [ 0, 255, 0, 255]); + + debug(""); + debug("check quantization"); + var quantInfo = [ + {format: gl.RGBA, type: gl.UNSIGNED_BYTE, counts: [256, 256, 256, 256]}, + {format: gl.RGBA, type: gl.UNSIGNED_SHORT_4_4_4_4, counts: [ 16, 16, 16, 16]}, + {format: gl.RGB, type: gl.UNSIGNED_SHORT_5_6_5, counts: [ 32, 64, 32, 1]}, + {format: gl.RGBA, type: gl.UNSIGNED_SHORT_5_5_5_1, counts: [ 32, 32, 32, 2]}]; + for (var qq = 0; qq < quantInfo.length; ++qq) { + var info = quantInfo[qq]; + gl.texImage2D( + gl.TEXTURE_2D, 0, info.format, info.format, info.type, + imgs['../../../resources/gray-ramp-256.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + wtu.clearAndDrawUnitQuad(gl); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); + var counts = [{ }, { }, { }, { }]; + var numUniqueValues = [0, 0, 0, 0]; + // Count the number of unique values in each channel. + for (var ii = 0; ii < width * height * 4; ii += 4) { + for (var jj = 0; jj < 4; ++jj) { + var v = buf[ii + jj]; + if (!counts[jj][v]) { + counts[jj][v] = 1; + ++numUniqueValues[jj]; + } else { + ++counts[jj][v]; + } + } + } + for (var ii = 0; ii < 4; ++ii) { + assertMsg(numUniqueValues[ii] == info.counts[ii], + "There should be " + info.counts[ii] + + " unique values in channel " + ii + ". Found " + + numUniqueValues[ii]); + } + } + + debug(""); + debug("Check that gamma settings don't effect 8bit pngs"); + wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);'); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/gray-ramp-default-gamma.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + wtu.clearAndDrawUnitQuad(gl); + var ref = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, ref); + + var gammaImages = [ + '../../../resources/gray-ramp-gamma0.1.png', + '../../../resources/gray-ramp-gamma1.0.png', + '../../../resources/gray-ramp-gamma2.0.png', + '../../../resources/gray-ramp-gamma4.0.png', + '../../../resources/gray-ramp-gamma9.0.png']; + for (var ii = 0; ii < gammaImages.length; ++ii) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs[gammaImages[ii]]); + wtu.clearAndDrawUnitQuad(gl); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); + var same = true; + for (var jj = 0; jj < width * height * 4; ++jj) { + if (buf[jj] != ref[jj]) { + same = false; + break; + } + } + assertMsg(same, "pixels should be same regardless of gamma settings."); + } + + debug(""); + debug("check pixels are UN pre-multiplied"); + for (var ii = 0; ii < 2; ++ii) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + if (ii == 0) { + var canvas2d = document.createElement("canvas"); + canvas2d.width = 256; + canvas2d.height = 1; + var ctx = canvas2d.getContext("2d"); + ctx.drawImage(imgs['../../../resources/gray-ramp-256-with-128-alpha.png'], 0, 0); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, canvas2d); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/gray-ramp-256-with-128-alpha.png']); + } + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + wtu.clearAndDrawUnitQuad(gl); + var buf = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); + var lt128Count = [0, 0, 0]; + var ge128Count = [0, 0, 0]; + for (var jj = 0; jj < width; ++jj) { + var off = jj * 4; + for (var cc = 0; cc < 3; ++cc) { + if (buf[off + cc] < 128) { + ++lt128Count[cc]; + } else { + ++ge128Count[cc]; + } + } + } + // Not sure the exact count here because gamma does effect drawing into the + // canvas but it should be close to 50% so I'll pass 45% + for (var jj = 0; jj < 3; ++jj) { + assertMsg(ge128Count[jj] > 256 * 0.45, + "Half the pixels in channel " + jj + + " should be >= 128,128,128. found " + + ((ge128Count[jj] / 256) * 100).toFixed() + "%"); + assertMsg(lt128Count[jj] > 256 * 0.45, + "Half the pixels in channel " + jj + + " should be < 128,128,128. found " + + ((lt128Count[jj] / 256) * 100).toFixed() + "%"); + } + } + + debug(""); + debug("check canvas pixels are UN pre-multiplied"); + var canvas2d = document.createElement("canvas"); + canvas2d.width = 1; + canvas2d.height = 1; + var ctx = canvas2d.getContext("2d"); + ctx.fillStyle ="rgba(255,255,255,0.5)"; + ctx.fillRect(0, 0, 256, 1); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d); + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + checkPixelRange(0, 0, [255, 255, 255, 127], 4); + + debug(""); + debug("check canvas pixels are pre-multiplied"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d); + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup."); + checkPixelRange(0, 0, [127, 127, 127, 127], 4); + + + debug(""); + debug("check pixels are pre-multiplied"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + // TODO(gman): use different texture that won't pass on failure + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, + imgs['../../../resources/zero-alpha.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); + + var same = true; + for (var jj = 0; jj < width * height * 4; ++jj) { + if (buf[jj] != 0) { + same = false; + break; + } + } + assertMsg(same, "pixels should all be 0."); + + debug(""); + debug("check pixels are flipped"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/3x3.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + + checkPixel(left, top, [255, 0, 0, 255]); + checkPixel(middle, top, [255, 255, 0, 255]); + checkPixel(right, top, [255, 0, 0, 255]); + checkPixel(left, center, [255, 0, 255, 255]); + checkPixel(middle, center, [255, 0, 0, 255]); + checkPixel(right, center, [ 0, 255, 0, 255]); + checkPixel(left, bottom, [ 0, 0, 0, 255]); + checkPixel(middle, bottom, [ 0, 0, 255, 255]); + checkPixel(right, bottom, [255, 0, 0, 255]); + + debug(""); + debug("check uploading of images with no alpha channel works"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/blue-1x1.jpg']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + checkPixelRange(middle, center, [ 0, 0, 255, 255], 10); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors"); + + debug(""); + debug("check uploading of 16-bit images"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/green-2x2-16bit.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + checkPixelRange(middle, center, [ 15, 121, 0, 255], 10); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors"); + + debug(""); + debug("check uploading of images with ICC profiles"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);'); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/small-square-with-colorspin-profile.jpg']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + // The image is red. However, if we ignore the color profile, it is blue. + checkPixelRange(middle, center, [ 0, 0, 255, 255], 10); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/small-square-with-colorspin-profile.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + // The image is red. However, if we ignore the color profile, it is blue. + checkPixelRange(middle, center, [ 0, 0, 255, 255], 10); + + var iccPNGs = [ + '../../../resources/small-square-with-cie-rgb-profile.png', + '../../../resources/small-square-with-colormatch-profile.png', + '../../../resources/small-square-with-e-srgb-profile.png', + '../../../resources/small-square-with-smpte-c-profile.png', + '../../../resources/small-square-with-srgb-iec61966-2.1-profile.png']; + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); + for (var ii = 0; ii < iccPNGs.length; ++ii) { + var buf2 = new Uint8Array(width * height * 4); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs[iccPNGs[ii]]); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf2); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors"); + var same = true; + for (var jj = 0; jj < buf.length; ++jj) { + if (buf[jj] != buf2[jj]) { + same = false; + break; + } + } + assertMsg(same, "uploading PNGs with same data but various ICC profiles should generate the same results"); + } + + debug(""); + debug("check uploading of indexed PNG images"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/red-indexed.png']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + // The image should be red. + checkPixelRange(middle, center, [ 255, 0, 0, 255 ], 10); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, + imgs['../../../resources/transparent-on-left-indexed.png']); + wtu.clearAndDrawUnitQuad(gl); + wtu.checkCanvasRect(gl, 0, 0, 128, 16, [255, 0, 255, 0], "should be transparent purple"); + wtu.checkCanvasRect(gl, 128, 0,128, 16, [255, 255, 0, 255], "should be yellow"); + + debug(""); + debug("check uploading of 1-channel JPG images"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, + imgs['../../../resources/1-channel.jpg']); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + // The image should be gray. + checkPixelRange(middle, center, [ 128, 128, 128, 255 ], 28); + + debug("") + debug("check calling texImage2D with NULL clears the texture"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, + imgs['../../../resources/red-indexed.png'].width, + imgs['../../../resources/red-indexed.png'].height, + 0, gl.RGB, gl.UNSIGNED_BYTE, null); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup"); + wtu.clearAndDrawUnitQuad(gl); + // The image should be white. + checkPixelRange(middle, center, [ 0, 0, 0, 255 ], 10); + + debug(""); + debug("check zero size cases"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, 2, 0, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, new Uint8Array()); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from zero sized textures"); + + debug(""); + successfullyParsed = true; + shouldBeTrue("successfullyParsed"); + debug('<br /><span class="pass">TEST COMPLETE</span>'); + notifyFinishedToHarness(); +} +</script> +</body> +</html> + |