Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / reading / read-pixels-pack-parameters.html
blob8d4559fb935d2056133e4da28ee9e6b3a070334e
1 <!--
2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
12 <script src="../../js/js-test-pre.js"></script>
13 <script src="../../js/webgl-test-utils.js"></script>
14 </head>
15 <body>
16 <canvas id="example" width="4" height="4"></canvas>
17 <div id="description"></div>
18 <div id="console"></div>
19 <script>
20 "use strict"
22 var wtu = WebGLTestUtils;
23 var initialColor = [1, 2, 3, 4];
24 var expectedColor = [[249, 102, 0, 255],
25 [2, 200, 102, 255],
26 [134, 87, 234, 255],
27 [99, 5, 76, 255]];
29 function calculatePaddingBytes(bytesPerPixel, packAlignment, width)
31 var padding = 0;
32 switch (packAlignment) {
33 case 1:
34 case 2:
35 case 4:
36 case 8:
37 padding = (bytesPerPixel * width) % packAlignment;
38 if (padding > 0)
39 padding = packAlignment - padding;
40 return padding;
41 default:
42 testFailed("should not reach here");
43 return;
47 function paintWebGLCanvas(gl)
49 var program = wtu.setupTexturedQuad(gl);
50 gl.disable(gl.DEPTH_TEST);
51 gl.disable(gl.BLEND);
53 var data = new Uint8Array(4 * 4);
54 for (var ii = 0; ii < 4; ++ii) {
55 data[ii * 4] = expectedColor[ii][0];
56 data[ii * 4 + 1] = expectedColor[ii][1];
57 data[ii * 4 + 2] = expectedColor[ii][2];
58 data[ii * 4 + 3] = expectedColor[ii][3];
61 var tex = gl.createTexture();
62 gl.bindTexture(gl.TEXTURE_2D, tex);
63 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
65 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
66 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
67 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
68 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
70 var loc = gl.getUniformLocation(program, "tex");
71 gl.uniform1i(loc, 0);
73 wtu.clearAndDrawUnitQuad(gl);
76 function samePixel(array, index, refPixel, row, pixelTag)
78 for (var ii = 0; ii < refPixel.length; ++ii) {
79 if (array[index] == refPixel[ii][0] &&
80 array[index + 1] == refPixel[ii][1] &&
81 array[index + 2] == refPixel[ii][2] &&
82 array[index + 3] == refPixel[ii][3]) {
83 return true;
86 var refPixelText = "";
87 for (var ii = 0; ii < refPixel.length; ++ii) {
88 if (ii > 0)
89 refPixelText += " or ";
90 refPixelText += "[" + refPixel[ii] + "]";
92 testFailed(pixelTag + " pixel of row " + row + ": expected " + refPixelText + ", got [" +
93 [array[index], array[index + 1], array[index + 2], array[index + 3]] + "]");
94 return false;
97 function runTestIteration(xoffset, yoffset, width, height, packParams, usePixelPackBuffer, packParamsValid)
99 if (!("alignment" in packParams))
100 packParams.alignment = 4;
101 if (!("rowLength" in packParams))
102 packParams.rowLength = 0;
103 if (!("skipPixels" in packParams))
104 packParams.skipPixels = 0;
105 if (!("skipRows" in packParams))
106 packParams.skipRows = 0;
107 debug("Testing xoffset = " + xoffset + ", yoffset " + yoffset +
108 ", width = " + width + ", height = " + height +
109 ", PACK_ALIGNMENT = " + packParams.alignment + ", PACK_ROW_LENGTH = " + packParams.rowLength +
110 ", PACK_SKIP_PIXELS = " + packParams.skipPixels + " , PACK_SKIP_ROWS = " + packParams.skipRows);
111 gl.pixelStorei(gl.PACK_ALIGNMENT, packParams.alignment);
112 gl.pixelStorei(gl.PACK_ROW_LENGTH, packParams.rowLength);
113 gl.pixelStorei(gl.PACK_SKIP_PIXELS, packParams.skipPixels);
114 gl.pixelStorei(gl.PACK_SKIP_ROWS, packParams.skipRows);
116 var actualWidth = packParams.rowLength > 0 ? packParams.rowLength : width;
118 var bytesPerPixel = 4; // see readPixels' parameters below, the format is gl.RGBA, type is gl.UNSIGNED_BYTE
119 var padding = calculatePaddingBytes(bytesPerPixel, packParams.alignment, actualWidth);
120 var bytesPerRow = actualWidth * bytesPerPixel + padding;
122 var size = bytesPerRow * (height - 1) + bytesPerPixel * width;
123 var skipSize = packParams.skipPixels * bytesPerPixel + packParams.skipRows * bytesPerRow;
124 var array = new Uint8Array(skipSize + size);
125 for (var ii = 0; ii < skipSize + size; ++ii) {
126 array[ii] = initialColor[ii % bytesPerPixel];
128 var arrayWrongSize = null;
129 if (size > 0)
130 arrayWrongSize = new Uint8Array(skipSize + size - 1);
131 if (usePixelPackBuffer) {
132 var offset = 0;
134 var buffer = gl.createBuffer();
135 gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer);
136 if (size > 0) {
137 gl.bufferData(gl.PIXEL_PACK_BUFFER, arrayWrongSize, gl.STATIC_DRAW);
138 gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, offset);
139 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
141 gl.bufferData(gl.PIXEL_PACK_BUFFER, array, gl.STATIC_DRAW);
142 gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, offset);
143 } else {
144 if (size > 0) {
145 gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, arrayWrongSize);
146 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
148 gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
150 if (packParamsValid) {
151 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should succeed");
152 } else {
153 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Invalid pack params combination");
154 return;
157 if (size == 0)
158 return;
160 if (usePixelPackBuffer) {
161 array = new Uint8Array(skipSize + size);
162 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, array);
165 // Check skipped bytes are unchanged.
166 for (var ii = 0; ii < skipSize; ++ii) {
167 if (array[ii] != initialColor[ii % bytesPerPixel]) {
168 testFailed("skipped bytes changed at index " + ii + ": expected " +
169 initialColor[ii % bytesPerPixel] + " got " + array[ii]);
170 break;
173 // Check the first and last pixels of each row.
174 var canvasWidth = 4;
175 var canvasHeight = 4;
176 for (var row = 0; row < height; ++row) {
177 var refColor;
178 var yIndex = yoffset + row;
179 var xIndex;
181 // First pixel
182 var pos = skipSize + bytesPerRow * row;
183 xIndex = xoffset;
184 if (xIndex < 0 || xIndex >= canvasWidth || yIndex < 0 || yIndex >= canvasHeight) {
185 if (row > 0 && usePixelPackBuffer && packParams.rowLength > 0 && packParams.rowLength < width)
186 refColor = [initialColor, expectedColor[yIndex - 1]];
187 else
188 refColor = [initialColor];
189 } else {
190 refColor = [expectedColor[yIndex]];
192 samePixel(array, pos, refColor, row, "first");
194 // Last pixel
195 var xSpan;
196 if (row + 1 == height || packParams.rowLength > width)
197 xSpan = width;
198 else
199 xSpan = actualWidth;
200 xIndex = xoffset + xSpan - 1;
201 pos += (xSpan - 1) * bytesPerPixel;
202 if (xIndex < 0 || xIndex >= canvasWidth || yIndex < 0 || yIndex >= canvasHeight) {
203 if (row > 0 && usePixelPackBuffer && packParams.rowLength > 0 && packParams.rowLength < width)
204 refColor = [initialColor, expectedColor[yIndex - 1]];
205 else
206 refColor = [initialColor];
207 } else {
208 refColor = [expectedColor[yIndex]];
210 samePixel(array, pos, refColor, row, "last");
212 // Check padding bytes are unchanged and bytes beyond rowLength set correctly.
213 pos += bytesPerPixel;
214 if (row + 1 < height) {
215 // Beyond bytes filled for PACK_ROW_LENGTH, the row could have extra bytes due to
216 // padding. These extra bytes could be either filled with pixel data if
217 // PACK_ROW_LENGTH is set to be less than width, or they could be left unchanged
218 // if they are beyond |width| pixels.
219 if (packParams.rowLength > 0 && packParams.rowLength < width) {
220 var trailingBytes = Math.min((width - packParams.rowLength) * bytesPerPixel,
221 bytesPerRow - packParams.rowLength * bytesPerPixel);
222 for (var ii = 0; ii < trailingBytes; ++ii) {
223 if (array[pos + ii] != refColor[0][ii % bytesPerPixel]) {
224 testFailed("Trailing byte " + ii + " after rowLength of row " + row + " : expected " +
225 refColor[0][ii % bytesPerPixel] + ", got " + array[pos + ii]);
226 break;
229 pos += trailingBytes;
231 var paddingBytes = skipSize + bytesPerRow * (row + 1) - pos;
232 for (var ii = 0; ii < paddingBytes; ++ii) {
233 if (array[pos + ii] != initialColor[ii % bytesPerPixel]) {
234 testFailed("Padding byte " + ii + " of row " + row + " changed: expected " +
235 initialColor[ii % bytesPerPixel] + ", got " + array[pos + ii]);
236 break;
243 function testPackParameters(usePixelPackBuffer)
245 debug("");
246 var destText = usePixelPackBuffer ? "PIXEL_PACK buffer" : "array buffer";
247 debug("Verify that reading pixels to " + destText + " works fine with various pack alignments.");
248 runTestIteration(0, 0, 1, 3, {alignment:1}, usePixelPackBuffer, true);
249 runTestIteration(0, 0, 1, 3, {alignment:2}, usePixelPackBuffer, true);
250 runTestIteration(0, 0, 1, 3, {alignment:4}, usePixelPackBuffer, true);
251 runTestIteration(0, 0, 1, 3, {alignment:8}, usePixelPackBuffer, true);
252 runTestIteration(0, 0, 2, 3, {alignment:4}, usePixelPackBuffer, true);
253 runTestIteration(0, 0, 2, 3, {alignment:8}, usePixelPackBuffer, true);
254 runTestIteration(0, 0, 3, 3, {alignment:4}, usePixelPackBuffer, true);
255 runTestIteration(0, 0, 3, 3, {alignment:8}, usePixelPackBuffer, true);
256 runTestIteration(0, 0, 0, 0, {alignment:1}, usePixelPackBuffer, true);
257 runTestIteration(0, 0, 1, 3, {alignment:4}, usePixelPackBuffer, true);
258 runTestIteration(0, 0, 1, 3, {alignment:8}, usePixelPackBuffer, true);
260 debug("");
261 debug("Verify that reading pixels to " + destText + " is disallowed when PACK_ROW_LENGTH < width.");
262 runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
263 runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
264 runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
265 runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
266 runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
267 runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
268 runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
269 runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
270 runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
271 runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
272 runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
273 runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:1}, usePixelPackBuffer, false);
275 debug("");
276 debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH == width.");
277 runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
278 runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
279 runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
280 runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
281 runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
282 runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
283 runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
284 runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
285 runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
286 runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
287 runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
289 debug("");
290 debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH > width and with no padding");
291 runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
292 runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
293 runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
294 runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
295 runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
296 runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
297 runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
298 runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
299 runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
300 runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
301 runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
303 debug("");
304 debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH > width and with padding");
305 runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
306 runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
307 runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
308 runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
309 runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
310 runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
311 runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
312 runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
313 runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
314 runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
315 runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
317 debug("");
318 debug("Verify that reading pixels to " + destText + " works fine with pack skip parameters.");
319 runTestIteration(0, 0, 3, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
320 runTestIteration(0, 0, 3, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
321 runTestIteration(0, 0, 3, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
322 runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
323 runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
324 runTestIteration(0, 0, 2, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
325 runTestIteration(0, 0, 2, 3, {skipPixels:1, rowLength:4}, usePixelPackBuffer, true);
328 debug("");
329 debug("Canvas.getContext");
331 var canvas = document.getElementById("example");
332 var gl = wtu.create3DContext(canvas, undefined, 2);
334 if (!gl) {
335 testFailed("context does not exist");
336 } else {
337 testPassed("context exists");
339 debug("");
340 description('ReadPixels into array buffer');
341 paintWebGLCanvas(gl);
342 var usePixelPackBuffer = false;
343 testPackParameters(usePixelPackBuffer);
344 usePixelPackBuffer = true;
345 testPackParameters(usePixelPackBuffer);
348 debug("");
349 var successfullyParsed = true;
350 </script>
351 <script src="../../js/js-test-post.js"></script>
352 </body>
353 </html>