Backed out changeset 8fc3326bce7f (bug 1943032) for causing failures at browser_tab_g...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / textures / misc / tex-unpack-params-with-flip-y-and-premultiply-alpha.html
blobb80b01c69a9fac382acc638395584b63d935481a
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 <title>WebGL2 texture unpack parameters with FLIP_Y / PREMULTIPLY_ALPHA conformance test.</title>
12 <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
13 <script src="../../../js/js-test-pre.js"></script>
14 <script src="../../../js/webgl-test-utils.js"></script>
15 </head>
16 <body>
17 <canvas id="example" width="4" height="4"></canvas>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script>
21 "use strict";
23 var wtu = WebGLTestUtils;
24 var __verbose__ = false;
26 // Some drivers (for example, NVIDIA Linux) incorrectly require padding for
27 // the last row. The below flag is only for testing convenience. Browsers should
28 // work around the bug.
29 var __apply_alignment_workaround__ = false;
31 function setupArrayBuffer(size, initData) {
32 var array = new Uint8Array(size);
33 if (initData) {
34 for (var ii = 0; ii < size; ++ii) {
35 array[ii] = ii % 255;
38 return array;
41 function calculatePaddingBytes(bytesPerPixel, alignment, width) {
42 var padding = 0;
43 switch (alignment) {
44 case 1:
45 case 2:
46 case 4:
47 case 8:
48 padding = (bytesPerPixel * width) % alignment;
49 if (padding > 0)
50 padding = alignment - padding;
51 return padding;
52 default:
53 testFailed("should not reach here");
54 return;
58 function computeImageSizes2D(width, height, testCase) {
59 // Assume RGBA8/UNSIGNED_BYTE
60 var bytesPerPixel = 4;
61 var actualWidth = testCase.rowLength == 0 ? width : testCase.rowLength;
62 var padding = calculatePaddingBytes(bytesPerPixel, testCase.alignment, actualWidth);
63 var bytesPerRow = actualWidth * bytesPerPixel + padding;
64 var bytesLastRow = bytesPerPixel * width;
65 var size = bytesPerRow * (height - 1) + bytesLastRow;
66 var skipSize = 0;
67 if (testCase.skipPixels > 0)
68 skipSize += bytesPerPixel * testCase.skipPixels;
69 if (testCase.skipRows > 0)
70 skipSize += bytesPerRow * testCase.skipRows;
71 return {size: size,
72 bytesPerRow: bytesPerRow,
73 bytesLastRow: bytesLastRow,
74 padding: padding,
75 skipSize: skipSize,
76 totalSize: size + skipSize};
79 function copyData(srcData, srcIndex, dstData, dstIndex, size, premultiply_alpha) {
80 for (var ii = 0; ii < size / 4; ++ii) {
81 var factor = 1.0;
82 if (premultiply_alpha)
83 factor = srcData[srcIndex + ii * 4 + 3] / 255.0;
84 dstData[dstIndex + ii * 4] = srcData[srcIndex + ii * 4] * factor;
85 dstData[dstIndex + ii * 4 + 1] = srcData[srcIndex + ii * 4 + 1] * factor;
86 dstData[dstIndex + ii * 4 + 2] = srcData[srcIndex + ii * 4 + 2] * factor;
87 dstData[dstIndex + ii * 4 + 3] = srcData[srcIndex + ii * 4 + 3];
91 function unpackPixels(srcData, width, height, imageSizes, flip_y, premultiply_alpha) {
92 var bytesPerPixel = 4;
93 var unpackedSize = width * height * bytesPerPixel;
94 var dstData = setupArrayBuffer(unpackedSize, false);
95 var srcIndex = imageSizes.skipSize;
96 var dstIndex = 0;
97 var inc = width * bytesPerPixel;
98 if (flip_y)
99 dstIndex += (height - 1) * inc;
100 for (var y = 0; y < height; ++y) {
101 copyData(srcData, srcIndex, dstData, dstIndex, width * bytesPerPixel, premultiply_alpha);
102 srcIndex += imageSizes.bytesPerRow;
103 if (flip_y)
104 dstIndex -= inc;
105 else
106 dstIndex += inc;
108 if (flip_y)
109 dstIndex += height * inc;
110 return dstData;
113 function getPixelsFromTexture2D(gl, tex, xoffset, yoffset, width, height) {
114 var fbo = gl.createFramebuffer();
115 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
116 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
117 var bytesPerReadbackPixel = 4;
118 var readbackBuffer = setupArrayBuffer(width * height * bytesPerReadbackPixel, false);
119 gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readbackBuffer);
120 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "read back texture pixels should succeed");
121 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
122 gl.deleteFramebuffer(fbo);
123 return readbackBuffer;
126 function comparePixels(buffer1, buffer2, tolerance) {
127 if (buffer1.length != buffer2.length || buffer1.length % 4 != 0) {
128 testFailed("compare pixels: invalid buffer size");
129 return;
131 var count = 0;
132 for (var ii = 0; ii < buffer1.length / 4; ++ii) {
133 var distance = 0;
134 for (var jj = 0; jj < 4; ++jj) {
135 var diff = buffer1[ii * 4 + jj] - buffer2[ii * 4 + jj];
136 distance += diff * diff;
138 if (Math.sqrt(diff) > tolerance) {
139 if (__verbose__) {
140 debug("Pixel " + ii + ": expected (" +
141 [buffer1[ii * 4], buffer1[ii * 4 + 1], buffer1[ii * 4 + 2], buffer1[ii * 4 + 3]] + "), got (" +
142 [buffer2[ii * 4], buffer2[ii * 4 + 1], buffer2[ii * 4 + 2], buffer2[ii * 4 + 3]] + ")");
144 count++;
147 if (count > 0) {
148 testFailed("compare pixels: " + count + " pixels differ");
149 } else {
150 testPassed("compare pixels: as expected");
154 function runTestIteration2D(gl, testCase, flip_y, premultiply_alpha) {
155 debug("");
156 debug("Texture upload with : flip_y = " + flip_y + ", premultiply_alpha = " + premultiply_alpha +
157 ", alignment = " + testCase.alignment + ", rowLength = " + testCase.rowLength +
158 ", skipPixels = " + testCase.skipPixels + ", skipRows = " + testCase.skipRows);
159 debug("TexImage2D : size = (" + testCase.width + ", " + testCase.height + ")");
160 gl.pixelStorei(gl.UNPACK_ALIGNMENT, testCase.alignment);
161 gl.pixelStorei(gl.UNPACK_ROW_LENGTH, testCase.rowLength);
162 gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, testCase.skipPixels);
163 gl.pixelStorei(gl.UNPACK_SKIP_ROWS, testCase.skipRows);
164 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip_y);
165 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiply_alpha);
166 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up pixel store parameters should succeed");
168 var tol = 3;
170 var tex = gl.createTexture();
171 gl.bindTexture(gl.TEXTURE_2D, tex);
173 var imageSizes = computeImageSizes2D(testCase.width, testCase.height, testCase);
174 var bufferSize = imageSizes.totalSize;
175 var array;
177 // Verify buffer with less than enough size will fail.
178 array = setupArrayBuffer(bufferSize - 1, false);
179 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0,
180 gl.RGBA, gl.UNSIGNED_BYTE, array);
181 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
183 if (__apply_alignment_workaround__)
184 bufferSize += imageSizes.padding;
185 array = setupArrayBuffer(bufferSize, true);
186 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0,
187 gl.RGBA, gl.UNSIGNED_BYTE, array);
188 if (testCase.validUnpackParams2D) {
189 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D with correct buffer size should succeed");
190 } else {
191 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
192 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0,
193 gl.RGBA, gl.UNSIGNED_BYTE, null);
194 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "unpack param constraints do not apply if no data are uploaded.");
195 return;
198 var buffer1 = unpackPixels(array, testCase.width, testCase.height, imageSizes, flip_y, premultiply_alpha);
199 var buffer2 = getPixelsFromTexture2D(gl, tex, 0, 0, testCase.width, testCase.height);
200 comparePixels(buffer1, buffer2, tol);
202 var subWidth = testCase.width - testCase.xoffset;
203 var subHeight = testCase.height - testCase.yoffset;
204 debug("TexSubImage2D : offset = (" + testCase.xoffset + ", " + testCase.yoffset +
205 "), size = (" + subWidth + ", " + subHeight + ")");
206 imageSizes = computeImageSizes2D(subWidth, subHeight, testCase);
207 bufferSize = imageSizes.totalSize;
209 array = setupArrayBuffer(bufferSize - 1, false);
210 gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset,
211 subWidth, subHeight, gl.RGBA, gl.UNSIGNED_BYTE, array);
212 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
214 if (__apply_alignment_workaround__)
215 bufferSize += imageSizes.padding;
216 array = setupArrayBuffer(bufferSize, true);
217 gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset, subWidth, subHeight,
218 gl.RGBA, gl.UNSIGNED_BYTE, array);
219 if (testCase.validUnpackParamsForSub2D) {
220 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D with correct buffer size should succeed");
221 } else {
222 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
223 return;
226 var buffer1 = unpackPixels(array, subWidth, subHeight, imageSizes, flip_y, premultiply_alpha);
227 var buffer2 = getPixelsFromTexture2D(
228 gl, tex, testCase.xoffset, testCase.yoffset, subWidth, subHeight);
229 comparePixels(buffer1, buffer2, tol);
231 gl.bindTexture(gl.TEXTURE_2D, null);
232 gl.deleteTexture(tex);
233 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
236 function runTests(gl) {
237 var testCases = [
238 { width: 5, height: 7, xoffset: 2, yoffset: 3,
239 alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0,
240 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
241 { width: 5, height: 7, xoffset: 2, yoffset: 3,
242 alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0,
243 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
244 { width: 6, height: 7, xoffset: 2, yoffset: 3,
245 alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0,
246 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
247 { width: 5, height: 8, xoffset: 2, yoffset: 3,
248 alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
249 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
251 // ROW_LENGTH == width
252 { width: 10, height: 9, xoffset: 2, yoffset: 3,
253 alignment: 4, rowLength: 10, skipPixels: 0, skipRows: 0,
254 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
256 // ROW_LENGTH < width
257 { width: 5, height: 7, xoffset: 2, yoffset: 3,
258 alignment: 1, rowLength: 4, skipPixels: 0, skipRows: 0,
259 validUnpackParams2D: false },
260 { width: 5, height: 7, xoffset: 2, yoffset: 3,
261 alignment: 2, rowLength: 4, skipPixels: 0, skipRows: 0,
262 validUnpackParams2D: false },
263 { width: 5, height: 7, xoffset: 2, yoffset: 3,
264 alignment: 4, rowLength: 4, skipPixels: 0, skipRows: 0,
265 validUnpackParams2D: false },
266 { width: 5, height: 7, xoffset: 2, yoffset: 3,
267 alignment: 8, rowLength: 4, skipPixels: 0, skipRows: 0,
268 validUnpackParams2D: false },
270 // ROW_LENGTH > width
271 { width: 5, height: 7, xoffset: 2, yoffset: 3,
272 alignment: 1, rowLength: 6, skipPixels: 0, skipRows: 0,
273 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
274 { width: 5, height: 7, xoffset: 2, yoffset: 3,
275 alignment: 2, rowLength: 7, skipPixels: 0, skipRows: 0,
276 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
277 { width: 5, height: 7, xoffset: 2, yoffset: 3,
278 alignment: 4, rowLength: 8, skipPixels: 0, skipRows: 0,
279 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
280 { width: 5, height: 7, xoffset: 2, yoffset: 3,
281 alignment: 8, rowLength: 9, skipPixels: 0, skipRows: 0,
282 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
284 // IMAGE_HEIGHT == height
285 { width: 6, height: 7, xoffset: 2, yoffset: 3,
286 alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
287 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
289 // IMAGE_HEIGHT < height
290 { width: 5, height: 7, xoffset: 2, yoffset: 3,
291 alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0,
292 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
293 { width: 5, height: 7, xoffset: 2, yoffset: 3,
294 alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0,
295 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
296 { width: 5, height: 7, xoffset: 2, yoffset: 3,
297 alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0,
298 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
299 { width: 5, height: 7, xoffset: 2, yoffset: 3,
300 alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
301 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
303 // IMAGE_HEIGHT > height
304 { width: 5, height: 7, xoffset: 2, yoffset: 3,
305 alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0,
306 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
307 { width: 6, height: 7, xoffset: 2, yoffset: 2,
308 alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0,
309 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
310 { width: 7, height: 7, xoffset: 2, yoffset: 4,
311 alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0,
312 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
313 { width: 8, height: 7, xoffset: 2, yoffset: 3,
314 alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
315 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
317 // SKIP parameters
318 { width: 5, height: 7, xoffset: 2, yoffset: 3,
319 alignment: 1, rowLength: 0, skipPixels: 10, skipRows: 0,
320 validUnpackParams2D: false },
321 { width: 5, height: 7, xoffset: 2, yoffset: 3,
322 alignment: 2, rowLength: 0, skipPixels: 2, skipRows: 8,
323 validUnpackParams2D: false },
324 { width: 5, height: 7, xoffset: 2, yoffset: 3,
325 alignment: 4, rowLength: 0, skipPixels: 3, skipRows: 5,
326 validUnpackParams2D: false },
327 { width: 5, height: 7, xoffset: 2, yoffset: 3,
328 alignment: 8, rowLength: 0, skipPixels: 7, skipRows: 0,
329 validUnpackParams2D: false },
331 // all mixed.
332 { width: 5, height: 7, xoffset: 2, yoffset: 3,
333 alignment: 1, rowLength: 6, skipPixels: 3, skipRows: 5,
334 validUnpackParams2D: false },
335 { width: 5, height: 7, xoffset: 2, yoffset: 3,
336 alignment: 2, rowLength: 4, skipPixels: 7, skipRows: 2,
337 validUnpackParams2D: false },
338 { width: 5, height: 7, xoffset: 2, yoffset: 3,
339 alignment: 4, rowLength: 10, skipPixels: 0, skipRows: 3,
340 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
341 { width: 1, height: 1, xoffset: 0, yoffset: 0,
342 alignment: 2, rowLength: 3, skipPixels: 3, skipRows: 5,
343 validUnpackParams2D: false },
344 { width: 17, height: 6, xoffset: 12, yoffset: 3,
345 alignment: 2, rowLength: 4, skipPixels: 1, skipRows: 4,
346 validUnpackParams2D: false },
347 { width: 8, height: 17, xoffset: 2, yoffset: 13,
348 alignment: 4, rowLength: 9, skipPixels: 0, skipRows: 3,
349 validUnpackParams2D: true, validUnpackParamsForSub2D: true },
352 var groups = [
353 // { flip_y: false, premultiply_alpha: false },
354 { flip_y: true, premultiply_alpha: false },
355 { flip_y: false, premultiply_alpha: true },
356 { flip_y: true, premultiply_alpha: true },
359 for (var jj = 0; jj < groups.length; ++jj) {
360 var group = groups[jj];
361 for (var ii = 0; ii < testCases.length; ++ii) {
362 var testCase = testCases[ii];
363 runTestIteration2D(gl, testCase, group.flip_y, group.premultiply_alpha);
368 function runNegativeTests(gl) {
369 debug("");
370 debug("Test tex{Sub}Image2D from pbo fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true");
372 var width = 16, height = 16, depth = 2;
374 // Restore default values.
375 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
376 gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0);
377 gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0);
378 gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
379 gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
380 gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
381 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
382 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
384 var tex = gl.createTexture();
385 gl.bindTexture(gl.TEXTURE_2D, tex);
387 var bufferSize = width * height * 4; // RGBA8
388 var buffer = gl.createBuffer();
389 gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
390 gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
392 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
393 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D from pbo works with default pixel store settings");
394 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
395 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D from pbo works with default pixel store settings");
397 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
398 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
399 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D from pbo with FLIP_Y=true should fail");
400 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
401 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D from pbo with FLIP_Y=true should fail");
402 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
404 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
405 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
406 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D from pbo with PREMULTIPLY_ALPHA=true should fail");
407 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
408 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D from pbo with PREMULTIPLY_ALPHA=true should fail");
409 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
411 debug("");
412 debug("Test tex{Sub}Image3D from pbo fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true");
414 gl.deleteTexture(tex);
415 tex = gl.createTexture();
416 gl.bindTexture(gl.TEXTURE_3D, tex);
418 bufferSize = width * height * depth * 4; // RGBA8
419 gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
420 gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
422 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
423 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D from pbo works with default pixel store settings");
424 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
425 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D from pbo works with default pixel store settings");
427 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
428 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
429 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with FLIP_Y=true should fail");
430 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
431 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with FLIP_Y=true should fail");
432 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
434 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
435 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
436 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
437 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
438 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
439 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
441 debug("");
442 debug("Test tex{Sub}Image3D from client array fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true");
444 gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
445 gl.deleteBuffer(buffer);
446 buffer = null;
447 var array = setupArrayBuffer(bufferSize, false);
449 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array);
450 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D from client array works with default pixel store settings");
451 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array);
452 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D from client array works with default pixel store settings");
454 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
455 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array);
456 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from client array with FLIP_Y=true should fail");
457 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array);
458 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from client array with FLIP_Y=true should fail");
459 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
461 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
462 gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array);
463 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
464 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array);
465 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
466 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
469 function runRegressionTests(gl) {
470 debug("");
471 debug("The following test serves as a regression test for crbug.com/774174");
472 var array = new Uint16Array(32);
473 gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 4);
474 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 6);
475 var tex = gl.createTexture();
476 gl.bindTexture(gl.TEXTURE_2D, tex);
477 gl.texSubImage2D(gl.TEXTURE_2D, 4, 7, 5, 8, 5, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, array);
478 // At this point, the Chrome ASAN build used to crash.
479 testPassed("The regression test for crbug.com/774174 doesn't crash");
480 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Calling texSubImage2D without initializing the texture is illegal");
481 gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0);
482 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
485 var gl = wtu.create3DContext("example", undefined, 2);
486 if (!gl) {
487 testFailed("Fail to get a WebGL context");
488 } else {
489 runTests(gl);
490 runNegativeTests(gl);
491 runRegressionTests(gl);
494 debug("");
495 var successfullyParsed = true;
496 </script>
497 <script src="../../../js/js-test-post.js"></script>
498 </body>
499 </html>