summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html353
1 files changed, 353 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html
new file mode 100644
index 0000000000..8d4559fb93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html
@@ -0,0 +1,353 @@
+<!--
+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>
+<canvas id="example" width="4" height="4"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict"
+
+var wtu = WebGLTestUtils;
+var initialColor = [1, 2, 3, 4];
+var expectedColor = [[249, 102, 0, 255],
+ [2, 200, 102, 255],
+ [134, 87, 234, 255],
+ [99, 5, 76, 255]];
+
+function calculatePaddingBytes(bytesPerPixel, packAlignment, width)
+{
+ var padding = 0;
+ switch (packAlignment) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ padding = (bytesPerPixel * width) % packAlignment;
+ if (padding > 0)
+ padding = packAlignment - padding;
+ return padding;
+ default:
+ testFailed("should not reach here");
+ return;
+ }
+}
+
+function paintWebGLCanvas(gl)
+{
+ var program = wtu.setupTexturedQuad(gl);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var data = new Uint8Array(4 * 4);
+ for (var ii = 0; ii < 4; ++ii) {
+ data[ii * 4] = expectedColor[ii][0];
+ data[ii * 4 + 1] = expectedColor[ii][1];
+ data[ii * 4 + 2] = expectedColor[ii][2];
+ data[ii * 4 + 3] = expectedColor[ii][3];
+ }
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ 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);
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ wtu.clearAndDrawUnitQuad(gl);
+}
+
+function samePixel(array, index, refPixel, row, pixelTag)
+{
+ for (var ii = 0; ii < refPixel.length; ++ii) {
+ if (array[index] == refPixel[ii][0] &&
+ array[index + 1] == refPixel[ii][1] &&
+ array[index + 2] == refPixel[ii][2] &&
+ array[index + 3] == refPixel[ii][3]) {
+ return true;
+ }
+ }
+ var refPixelText = "";
+ for (var ii = 0; ii < refPixel.length; ++ii) {
+ if (ii > 0)
+ refPixelText += " or ";
+ refPixelText += "[" + refPixel[ii] + "]";
+ }
+ testFailed(pixelTag + " pixel of row " + row + ": expected " + refPixelText + ", got [" +
+ [array[index], array[index + 1], array[index + 2], array[index + 3]] + "]");
+ return false;
+}
+
+function runTestIteration(xoffset, yoffset, width, height, packParams, usePixelPackBuffer, packParamsValid)
+{
+ if (!("alignment" in packParams))
+ packParams.alignment = 4;
+ if (!("rowLength" in packParams))
+ packParams.rowLength = 0;
+ if (!("skipPixels" in packParams))
+ packParams.skipPixels = 0;
+ if (!("skipRows" in packParams))
+ packParams.skipRows = 0;
+ debug("Testing xoffset = " + xoffset + ", yoffset " + yoffset +
+ ", width = " + width + ", height = " + height +
+ ", PACK_ALIGNMENT = " + packParams.alignment + ", PACK_ROW_LENGTH = " + packParams.rowLength +
+ ", PACK_SKIP_PIXELS = " + packParams.skipPixels + " , PACK_SKIP_ROWS = " + packParams.skipRows);
+ gl.pixelStorei(gl.PACK_ALIGNMENT, packParams.alignment);
+ gl.pixelStorei(gl.PACK_ROW_LENGTH, packParams.rowLength);
+ gl.pixelStorei(gl.PACK_SKIP_PIXELS, packParams.skipPixels);
+ gl.pixelStorei(gl.PACK_SKIP_ROWS, packParams.skipRows);
+
+ var actualWidth = packParams.rowLength > 0 ? packParams.rowLength : width;
+
+ var bytesPerPixel = 4; // see readPixels' parameters below, the format is gl.RGBA, type is gl.UNSIGNED_BYTE
+ var padding = calculatePaddingBytes(bytesPerPixel, packParams.alignment, actualWidth);
+ var bytesPerRow = actualWidth * bytesPerPixel + padding;
+
+ var size = bytesPerRow * (height - 1) + bytesPerPixel * width;
+ var skipSize = packParams.skipPixels * bytesPerPixel + packParams.skipRows * bytesPerRow;
+ var array = new Uint8Array(skipSize + size);
+ for (var ii = 0; ii < skipSize + size; ++ii) {
+ array[ii] = initialColor[ii % bytesPerPixel];
+ }
+ var arrayWrongSize = null;
+ if (size > 0)
+ arrayWrongSize = new Uint8Array(skipSize + size - 1);
+ if (usePixelPackBuffer) {
+ var offset = 0;
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer);
+ if (size > 0) {
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, arrayWrongSize, gl.STATIC_DRAW);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, offset);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+ }
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, array, gl.STATIC_DRAW);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, offset);
+ } else {
+ if (size > 0) {
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, arrayWrongSize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+ }
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ }
+ if (packParamsValid) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Invalid pack params combination");
+ return;
+ }
+
+ if (size == 0)
+ return;
+
+ if (usePixelPackBuffer) {
+ array = new Uint8Array(skipSize + size);
+ gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, array);
+ }
+
+ // Check skipped bytes are unchanged.
+ for (var ii = 0; ii < skipSize; ++ii) {
+ if (array[ii] != initialColor[ii % bytesPerPixel]) {
+ testFailed("skipped bytes changed at index " + ii + ": expected " +
+ initialColor[ii % bytesPerPixel] + " got " + array[ii]);
+ break;
+ }
+ }
+ // Check the first and last pixels of each row.
+ var canvasWidth = 4;
+ var canvasHeight = 4;
+ for (var row = 0; row < height; ++row) {
+ var refColor;
+ var yIndex = yoffset + row;
+ var xIndex;
+
+ // First pixel
+ var pos = skipSize + bytesPerRow * row;
+ xIndex = xoffset;
+ if (xIndex < 0 || xIndex >= canvasWidth || yIndex < 0 || yIndex >= canvasHeight) {
+ if (row > 0 && usePixelPackBuffer && packParams.rowLength > 0 && packParams.rowLength < width)
+ refColor = [initialColor, expectedColor[yIndex - 1]];
+ else
+ refColor = [initialColor];
+ } else {
+ refColor = [expectedColor[yIndex]];
+ }
+ samePixel(array, pos, refColor, row, "first");
+
+ // Last pixel
+ var xSpan;
+ if (row + 1 == height || packParams.rowLength > width)
+ xSpan = width;
+ else
+ xSpan = actualWidth;
+ xIndex = xoffset + xSpan - 1;
+ pos += (xSpan - 1) * bytesPerPixel;
+ if (xIndex < 0 || xIndex >= canvasWidth || yIndex < 0 || yIndex >= canvasHeight) {
+ if (row > 0 && usePixelPackBuffer && packParams.rowLength > 0 && packParams.rowLength < width)
+ refColor = [initialColor, expectedColor[yIndex - 1]];
+ else
+ refColor = [initialColor];
+ } else {
+ refColor = [expectedColor[yIndex]];
+ }
+ samePixel(array, pos, refColor, row, "last");
+
+ // Check padding bytes are unchanged and bytes beyond rowLength set correctly.
+ pos += bytesPerPixel;
+ if (row + 1 < height) {
+ // Beyond bytes filled for PACK_ROW_LENGTH, the row could have extra bytes due to
+ // padding. These extra bytes could be either filled with pixel data if
+ // PACK_ROW_LENGTH is set to be less than width, or they could be left unchanged
+ // if they are beyond |width| pixels.
+ if (packParams.rowLength > 0 && packParams.rowLength < width) {
+ var trailingBytes = Math.min((width - packParams.rowLength) * bytesPerPixel,
+ bytesPerRow - packParams.rowLength * bytesPerPixel);
+ for (var ii = 0; ii < trailingBytes; ++ii) {
+ if (array[pos + ii] != refColor[0][ii % bytesPerPixel]) {
+ testFailed("Trailing byte " + ii + " after rowLength of row " + row + " : expected " +
+ refColor[0][ii % bytesPerPixel] + ", got " + array[pos + ii]);
+ break;
+ }
+ }
+ pos += trailingBytes;
+ }
+ var paddingBytes = skipSize + bytesPerRow * (row + 1) - pos;
+ for (var ii = 0; ii < paddingBytes; ++ii) {
+ if (array[pos + ii] != initialColor[ii % bytesPerPixel]) {
+ testFailed("Padding byte " + ii + " of row " + row + " changed: expected " +
+ initialColor[ii % bytesPerPixel] + ", got " + array[pos + ii]);
+ break;
+ }
+ }
+ }
+ }
+}
+
+function testPackParameters(usePixelPackBuffer)
+{
+ debug("");
+ var destText = usePixelPackBuffer ? "PIXEL_PACK buffer" : "array buffer";
+ debug("Verify that reading pixels to " + destText + " works fine with various pack alignments.");
+ runTestIteration(0, 0, 1, 3, {alignment:1}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:2}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:8}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {alignment:8}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 3, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 3, 3, {alignment:8}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 0, 0, {alignment:1}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:8}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " is disallowed when PACK_ROW_LENGTH < width.");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:1}, usePixelPackBuffer, false);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH == width.");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH > width and with no padding");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH > width and with padding");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with pack skip parameters.");
+ runTestIteration(0, 0, 3, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 3, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 3, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 2, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {skipPixels:1, rowLength:4}, usePixelPackBuffer, true);
+}
+
+debug("");
+debug("Canvas.getContext");
+
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ description('ReadPixels into array buffer');
+ paintWebGLCanvas(gl);
+ var usePixelPackBuffer = false;
+ testPackParameters(usePixelPackBuffer);
+ usePixelPackBuffer = true;
+ testPackParameters(usePixelPackBuffer);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>