diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html new file mode 100644 index 0000000000..b80b01c69a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html @@ -0,0 +1,499 @@ +<!-- +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>WebGL2 texture unpack parameters with FLIP_Y / PREMULTIPLY_ALPHA 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="4" height="4"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; + +var wtu = WebGLTestUtils; +var __verbose__ = false; + +// Some drivers (for example, NVIDIA Linux) incorrectly require padding for +// the last row. The below flag is only for testing convenience. Browsers should +// work around the bug. +var __apply_alignment_workaround__ = false; + +function setupArrayBuffer(size, initData) { + var array = new Uint8Array(size); + if (initData) { + for (var ii = 0; ii < size; ++ii) { + array[ii] = ii % 255; + } + } + return array; +} + +function calculatePaddingBytes(bytesPerPixel, alignment, width) { + var padding = 0; + switch (alignment) { + case 1: + case 2: + case 4: + case 8: + padding = (bytesPerPixel * width) % alignment; + if (padding > 0) + padding = alignment - padding; + return padding; + default: + testFailed("should not reach here"); + return; + } +} + +function computeImageSizes2D(width, height, testCase) { + // Assume RGBA8/UNSIGNED_BYTE + var bytesPerPixel = 4; + var actualWidth = testCase.rowLength == 0 ? width : testCase.rowLength; + var padding = calculatePaddingBytes(bytesPerPixel, testCase.alignment, actualWidth); + var bytesPerRow = actualWidth * bytesPerPixel + padding; + var bytesLastRow = bytesPerPixel * width; + var size = bytesPerRow * (height - 1) + bytesLastRow; + var skipSize = 0; + if (testCase.skipPixels > 0) + skipSize += bytesPerPixel * testCase.skipPixels; + if (testCase.skipRows > 0) + skipSize += bytesPerRow * testCase.skipRows; + return {size: size, + bytesPerRow: bytesPerRow, + bytesLastRow: bytesLastRow, + padding: padding, + skipSize: skipSize, + totalSize: size + skipSize}; +} + +function copyData(srcData, srcIndex, dstData, dstIndex, size, premultiply_alpha) { + for (var ii = 0; ii < size / 4; ++ii) { + var factor = 1.0; + if (premultiply_alpha) + factor = srcData[srcIndex + ii * 4 + 3] / 255.0; + dstData[dstIndex + ii * 4] = srcData[srcIndex + ii * 4] * factor; + dstData[dstIndex + ii * 4 + 1] = srcData[srcIndex + ii * 4 + 1] * factor; + dstData[dstIndex + ii * 4 + 2] = srcData[srcIndex + ii * 4 + 2] * factor; + dstData[dstIndex + ii * 4 + 3] = srcData[srcIndex + ii * 4 + 3]; + } +} + +function unpackPixels(srcData, width, height, imageSizes, flip_y, premultiply_alpha) { + var bytesPerPixel = 4; + var unpackedSize = width * height * bytesPerPixel; + var dstData = setupArrayBuffer(unpackedSize, false); + var srcIndex = imageSizes.skipSize; + var dstIndex = 0; + var inc = width * bytesPerPixel; + if (flip_y) + dstIndex += (height - 1) * inc; + for (var y = 0; y < height; ++y) { + copyData(srcData, srcIndex, dstData, dstIndex, width * bytesPerPixel, premultiply_alpha); + srcIndex += imageSizes.bytesPerRow; + if (flip_y) + dstIndex -= inc; + else + dstIndex += inc; + } + if (flip_y) + dstIndex += height * inc; + return dstData; +} + +function getPixelsFromTexture2D(gl, tex, xoffset, yoffset, width, height) { + var fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); + var bytesPerReadbackPixel = 4; + var readbackBuffer = setupArrayBuffer(width * height * bytesPerReadbackPixel, false); + gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readbackBuffer); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "read back texture pixels should succeed"); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(fbo); + return readbackBuffer; +} + +function comparePixels(buffer1, buffer2, tolerance) { + if (buffer1.length != buffer2.length || buffer1.length % 4 != 0) { + testFailed("compare pixels: invalid buffer size"); + return; + } + var count = 0; + for (var ii = 0; ii < buffer1.length / 4; ++ii) { + var distance = 0; + for (var jj = 0; jj < 4; ++jj) { + var diff = buffer1[ii * 4 + jj] - buffer2[ii * 4 + jj]; + distance += diff * diff; + } + if (Math.sqrt(diff) > tolerance) { + if (__verbose__) { + debug("Pixel " + ii + ": expected (" + + [buffer1[ii * 4], buffer1[ii * 4 + 1], buffer1[ii * 4 + 2], buffer1[ii * 4 + 3]] + "), got (" + + [buffer2[ii * 4], buffer2[ii * 4 + 1], buffer2[ii * 4 + 2], buffer2[ii * 4 + 3]] + ")"); + } + count++; + } + } + if (count > 0) { + testFailed("compare pixels: " + count + " pixels differ"); + } else { + testPassed("compare pixels: as expected"); + } +} + +function runTestIteration2D(gl, testCase, flip_y, premultiply_alpha) { + debug(""); + debug("Texture upload with : flip_y = " + flip_y + ", premultiply_alpha = " + premultiply_alpha + + ", alignment = " + testCase.alignment + ", rowLength = " + testCase.rowLength + + ", skipPixels = " + testCase.skipPixels + ", skipRows = " + testCase.skipRows); + debug("TexImage2D : size = (" + testCase.width + ", " + testCase.height + ")"); + gl.pixelStorei(gl.UNPACK_ALIGNMENT, testCase.alignment); + gl.pixelStorei(gl.UNPACK_ROW_LENGTH, testCase.rowLength); + gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, testCase.skipPixels); + gl.pixelStorei(gl.UNPACK_SKIP_ROWS, testCase.skipRows); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip_y); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiply_alpha); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up pixel store parameters should succeed"); + + var tol = 3; + + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + + var imageSizes = computeImageSizes2D(testCase.width, testCase.height, testCase); + var bufferSize = imageSizes.totalSize; + var array; + + // Verify buffer with less than enough size will fail. + array = setupArrayBuffer(bufferSize - 1, false); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0, + gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small"); + + if (__apply_alignment_workaround__) + bufferSize += imageSizes.padding; + array = setupArrayBuffer(bufferSize, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0, + gl.RGBA, gl.UNSIGNED_BYTE, array); + if (testCase.validUnpackParams2D) { + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D with correct buffer size should succeed"); + } else { + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination"); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0, + gl.RGBA, gl.UNSIGNED_BYTE, null); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "unpack param constraints do not apply if no data are uploaded."); + return; + } + + var buffer1 = unpackPixels(array, testCase.width, testCase.height, imageSizes, flip_y, premultiply_alpha); + var buffer2 = getPixelsFromTexture2D(gl, tex, 0, 0, testCase.width, testCase.height); + comparePixels(buffer1, buffer2, tol); + + var subWidth = testCase.width - testCase.xoffset; + var subHeight = testCase.height - testCase.yoffset; + debug("TexSubImage2D : offset = (" + testCase.xoffset + ", " + testCase.yoffset + + "), size = (" + subWidth + ", " + subHeight + ")"); + imageSizes = computeImageSizes2D(subWidth, subHeight, testCase); + bufferSize = imageSizes.totalSize; + + array = setupArrayBuffer(bufferSize - 1, false); + gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset, + subWidth, subHeight, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small"); + + if (__apply_alignment_workaround__) + bufferSize += imageSizes.padding; + array = setupArrayBuffer(bufferSize, true); + gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset, subWidth, subHeight, + gl.RGBA, gl.UNSIGNED_BYTE, array); + if (testCase.validUnpackParamsForSub2D) { + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D with correct buffer size should succeed"); + } else { + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination"); + return; + } + + var buffer1 = unpackPixels(array, subWidth, subHeight, imageSizes, flip_y, premultiply_alpha); + var buffer2 = getPixelsFromTexture2D( + gl, tex, testCase.xoffset, testCase.yoffset, subWidth, subHeight); + comparePixels(buffer1, buffer2, tol); + + gl.bindTexture(gl.TEXTURE_2D, null); + gl.deleteTexture(tex); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error"); +} + +function runTests(gl) { + var testCases = [ + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 6, height: 7, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 8, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + + // ROW_LENGTH == width + { width: 10, height: 9, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 10, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + + // ROW_LENGTH < width + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 4, skipPixels: 0, skipRows: 0, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 2, rowLength: 4, skipPixels: 0, skipRows: 0, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 4, skipPixels: 0, skipRows: 0, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 4, skipPixels: 0, skipRows: 0, + validUnpackParams2D: false }, + + // ROW_LENGTH > width + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 6, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 2, rowLength: 7, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 8, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 9, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + + // IMAGE_HEIGHT == height + { width: 6, height: 7, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + + // IMAGE_HEIGHT < height + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + + // IMAGE_HEIGHT > height + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 6, height: 7, xoffset: 2, yoffset: 2, + alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 7, height: 7, xoffset: 2, yoffset: 4, + alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 8, height: 7, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + + // SKIP parameters + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 0, skipPixels: 10, skipRows: 0, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 2, rowLength: 0, skipPixels: 2, skipRows: 8, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 0, skipPixels: 3, skipRows: 5, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 8, rowLength: 0, skipPixels: 7, skipRows: 0, + validUnpackParams2D: false }, + + // all mixed. + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 1, rowLength: 6, skipPixels: 3, skipRows: 5, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 2, rowLength: 4, skipPixels: 7, skipRows: 2, + validUnpackParams2D: false }, + { width: 5, height: 7, xoffset: 2, yoffset: 3, + alignment: 4, rowLength: 10, skipPixels: 0, skipRows: 3, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + { width: 1, height: 1, xoffset: 0, yoffset: 0, + alignment: 2, rowLength: 3, skipPixels: 3, skipRows: 5, + validUnpackParams2D: false }, + { width: 17, height: 6, xoffset: 12, yoffset: 3, + alignment: 2, rowLength: 4, skipPixels: 1, skipRows: 4, + validUnpackParams2D: false }, + { width: 8, height: 17, xoffset: 2, yoffset: 13, + alignment: 4, rowLength: 9, skipPixels: 0, skipRows: 3, + validUnpackParams2D: true, validUnpackParamsForSub2D: true }, + ]; + + var groups = [ + // { flip_y: false, premultiply_alpha: false }, + { flip_y: true, premultiply_alpha: false }, + { flip_y: false, premultiply_alpha: true }, + { flip_y: true, premultiply_alpha: true }, + ]; + + for (var jj = 0; jj < groups.length; ++jj) { + var group = groups[jj]; + for (var ii = 0; ii < testCases.length; ++ii) { + var testCase = testCases[ii]; + runTestIteration2D(gl, testCase, group.flip_y, group.premultiply_alpha); + } + } +} + +function runNegativeTests(gl) { + debug(""); + debug("Test tex{Sub}Image2D from pbo fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true"); + + var width = 16, height = 16, depth = 2; + + // Restore default values. + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + + var bufferSize = width * height * 4; // RGBA8 + var buffer = gl.createBuffer(); + gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer); + gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize, gl.DYNAMIC_DRAW); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D from pbo works with default pixel store settings"); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D from pbo works with default pixel store settings"); + + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D from pbo with FLIP_Y=true should fail"); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D from pbo with FLIP_Y=true should fail"); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D from pbo with PREMULTIPLY_ALPHA=true should fail"); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D from pbo with PREMULTIPLY_ALPHA=true should fail"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + + debug(""); + debug("Test tex{Sub}Image3D from pbo fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true"); + + gl.deleteTexture(tex); + tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_3D, tex); + + bufferSize = width * height * depth * 4; // RGBA8 + gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer); + gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize, gl.DYNAMIC_DRAW); + + gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D from pbo works with default pixel store settings"); + gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D from pbo works with default pixel store settings"); + + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with FLIP_Y=true should fail"); + gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with FLIP_Y=true should fail"); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with PREMULTIPLY_ALPHA=true should fail"); + gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with PREMULTIPLY_ALPHA=true should fail"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + + debug(""); + debug("Test tex{Sub}Image3D from client array fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true"); + + gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null); + gl.deleteBuffer(buffer); + buffer = null; + var array = setupArrayBuffer(bufferSize, false); + + gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D from client array works with default pixel store settings"); + gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D from client array works with default pixel store settings"); + + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from client array with FLIP_Y=true should fail"); + gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from client array with FLIP_Y=true should fail"); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with PREMULTIPLY_ALPHA=true should fail"); + gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with PREMULTIPLY_ALPHA=true should fail"); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); +} + +function runRegressionTests(gl) { + debug(""); + debug("The following test serves as a regression test for crbug.com/774174"); + var array = new Uint16Array(32); + gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 4); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 6); + var tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texSubImage2D(gl.TEXTURE_2D, 4, 7, 5, 8, 5, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, array); + // At this point, the Chrome ASAN build used to crash. + testPassed("The regression test for crbug.com/774174 doesn't crash"); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Calling texSubImage2D without initializing the texture is illegal"); + gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); +} + +var gl = wtu.create3DContext("example", undefined, 2); +if (!gl) { + testFailed("Fail to get a WebGL context"); +} else { + runTests(gl); + runNegativeTests(gl); + runRegressionTests(gl); +} + +debug(""); +var successfullyParsed = true; +</script> +<script src="../../../js/js-test-post.js"></script> +</body> +</html> |