Bug 1915045 Ensure decode tasks are scheduled on BufferingState::Enter() r=media...
[gecko.git] / dom / canvas / test / webgl-mochitest / test_webgl_compressed_texture_es3.html
blob9a92893378f81d0b70eebe14fb3681a1cb668da9
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <script src="/tests/SimpleTest/SimpleTest.js"></script>
6 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
7 <script src="webgl-util.js"></script>
8 <script src="es3-data.js"></script>
9 <title>WebGL test: test WEBGL_compressed_texture_etc extension</title>
10 <style>
11 img {
12 border: 1px solid black;
13 margin-right: 1em;
15 .testimages {
18 .testimages br {
19 clear: both;
22 .testimages > div {
23 float: left;
24 margin: 1em;
26 </style>
27 </head>
28 <body>
29 <div id="description"></div>
30 <canvas id="canvas" width="8" height="8"></canvas>
31 <div id="console"></div>
32 <script id="vshader" type="x-shader/x-vertex">
33 attribute vec4 vPosition;
34 attribute vec2 texCoord0;
35 varying vec2 texCoord;
36 void main() {
37 gl_Position = vPosition;
38 texCoord = texCoord0;
40 </script>
41 <script id="fshader" type="x-shader/x-fragment">
42 precision mediump float;
43 uniform sampler2D tex;
44 varying vec2 texCoord;
45 void main() {
46 gl_FragData[0] = texture2D(tex, texCoord);
48 </script>
49 <script id="fshader-r" type="x-shader/x-fragment">
50 precision mediump float;
51 uniform sampler2D tex;
52 varying vec2 texCoord;
53 void main() {
54 vec4 pixel = (texture2D(tex, texCoord));
55 pixel.r = (pixel.r + 1.0) / 2.0;
56 gl_FragData[0] = pixel;
58 </script>
59 <script id="fshader-rg" type="x-shader/x-fragment">
60 precision mediump float;
61 uniform sampler2D tex;
62 varying vec2 texCoord;
63 void main() {
64 vec4 pixel = (texture2D(tex, texCoord));
65 pixel.rg = (pixel.rg + 1.0) / 2.0;
66 gl_FragData[0] = pixel;
68 </script>
69 <script>
70 "use strict";
71 var ext = null;
72 var vao = null;
73 var gl = null;
74 var validFormats = {
75 COMPRESSED_R11_EAC : 0x9270,
76 COMPRESSED_SIGNED_R11_EAC : 0x9271,
77 COMPRESSED_RG11_EAC : 0x9272,
78 COMPRESSED_SIGNED_RG11_EAC : 0x9273,
79 COMPRESSED_RGB8_ETC2 : 0x9274,
80 COMPRESSED_SRGB8_ETC2 : 0x9275,
81 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276,
82 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277,
83 COMPRESSED_RGBA8_ETC2_EAC : 0x9278,
84 COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279,
87 function setupUnitQuad() {
88 var vertexObject = gl.createBuffer();
89 gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
90 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
91 1.0, 1.0, 0.0,
92 -1.0, 1.0, 0.0,
93 -1.0, -1.0, 0.0,
94 1.0, 1.0, 0.0,
95 -1.0, -1.0, 0.0,
96 1.0, -1.0, 0.0]), gl.STATIC_DRAW);
97 gl.enableVertexAttribArray(0);
98 gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
100 var vertexObject = gl.createBuffer();
101 gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
102 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
103 1.0, 1.0,
104 0.0, 1.0,
105 0.0, 0.0,
106 1.0, 1.0,
107 0.0, 0.0,
108 1.0, 0.0]), gl.STATIC_DRAW);
109 gl.enableVertexAttribArray(1);
110 gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
113 function runTest() {
114 gl = canvas.getContext('webgl', {antialias: false});
115 if (!gl) {
116 ok(false, "WebGL context does not exist");
117 } else {
118 ok(true, "WebGL context exists");
119 setupUnitQuad();
121 // Run tests with extension disabled
122 runTestDisabled();
124 // Query the extension and store globally so shouldBe can access it
125 ext = gl.getExtension("WEBGL_compressed_texture_etc");
126 if (!ext) {
127 ok(true, "No WEBGL_compressed_texture_etc support -- this is legal");
128 runSupportedTest(false);
129 } else {
130 ok(true, "Successfully enabled WEBGL_compressed_texture_etc extension");
132 runSupportedTest(true);
133 runTestExtension();
136 SimpleTest.finish();
139 function runSupportedTest(extensionEnabled) {
140 var supported = gl.getSupportedExtensions();
141 if (supported.includes("WEBGL_compressed_texture_etc")) {
142 if (extensionEnabled) {
143 ok(true, "WEBGL_compressed_texture_etc listed as supported and getExtension succeeded");
144 } else {
145 ok(false, "WEBGL_compressed_texture_etc listed as supported but getExtension failed");
147 } else {
148 if (extensionEnabled) {
149 ok(false, "WEBGL_compressed_texture_etc not listed as supported but getExtension succeeded");
150 } else {
151 ok(true, "WEBGL_compressed_texture_etc not listed as supported and getExtension failed -- this is legal");
156 function runTestDisabled() {
157 is(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS).length, 0,
158 "Should be no compressed texture formats");
161 function formatExists(format, supportedFormats) {
162 for (var ii = 0; ii < supportedFormats.length; ++ii) {
163 if (format == supportedFormats[ii]) {
164 ok(true, "supported format " + formatToString(format) + " is exists");
165 return;
168 ok(false, "supported format " + formatToString(format) + " does not exist");
171 function formatToString(format) {
172 for (var p in ext) {
173 if (ext[p] == format) {
174 return p;
177 return "0x" + format.toString(16);
180 function runTestExtension() {
181 // check that all format enums exist.
182 for (let name in validFormats) {
183 is(ext[name], validFormats[name], "format is match");
186 let supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
187 // There should be exactly 10 formats
188 is(supportedFormats.length, 10, "Should be exactly 10 formats");
190 // check that all 10 formats exist
191 for (let name in validFormats.length) {
192 formatExists(validFormats[name], supportedFormats);
195 // Test each format
196 testETC2_RGB();
199 function testETC2_RGB() {
200 var tests = [
202 width: 4,
203 height: 4,
204 channels: 1,
205 data: img_4x4_r11_eac,
206 format: ext.COMPRESSED_R11_EAC
209 width: 4,
210 height: 4,
211 channels: 1,
212 data: img_4x4_signed_r11_eac,
213 format: ext.COMPRESSED_SIGNED_R11_EAC
216 width: 4,
217 height: 4,
218 channels: 2,
219 data: img_4x4_rg11_eac,
220 format: ext.COMPRESSED_RG11_EAC
223 width: 4,
224 height: 4,
225 channels: 2,
226 data: img_4x4_signed_rg11_eac,
227 format: ext.COMPRESSED_SIGNED_RG11_EAC
230 width: 4,
231 height: 4,
232 channels: 3,
233 data: img_4x4_rgb_etc2,
234 format: ext.COMPRESSED_RGB8_ETC2
237 width: 4,
238 height: 4,
239 channels: 3,
240 data: img_4x4_rgb_etc2,
241 format: ext.COMPRESSED_SRGB8_ETC2
244 width: 4,
245 height: 4,
246 channels: 4,
247 data: img_4x4_rgb_punchthrough_etc2,
248 format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
251 width: 4,
252 height: 4,
253 channels: 4,
254 data: img_4x4_rgb_punchthrough_etc2,
255 format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
258 width: 4,
259 height: 4,
260 channels: 4,
261 data: img_4x4_rgba_etc2,
262 format: ext.COMPRESSED_RGBA8_ETC2_EAC
265 width: 4,
266 height: 4,
267 channels: 4,
268 data: img_4x4_rgba_etc2,
269 format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
272 width: 8,
273 height: 8,
274 channels: 1,
275 data: img_8x8_r11_eac,
276 format: ext.COMPRESSED_R11_EAC
279 width: 8,
280 height: 8,
281 channels: 1,
282 data: img_8x8_signed_r11_eac,
283 format: ext.COMPRESSED_SIGNED_R11_EAC
286 width: 8,
287 height: 8,
288 channels: 2,
289 data: img_8x8_rg11_eac,
290 format: ext.COMPRESSED_RG11_EAC
293 width: 8,
294 height: 8,
295 channels: 2,
296 data: img_8x8_signed_rg11_eac,
297 format: ext.COMPRESSED_SIGNED_RG11_EAC
300 width: 8,
301 height: 8,
302 channels: 3,
303 data: img_8x8_rgb_etc2,
304 format: ext.COMPRESSED_RGB8_ETC2
307 width: 8,
308 height: 8,
309 channels: 3,
310 data: img_8x8_rgb_etc2,
311 format: ext.COMPRESSED_SRGB8_ETC2
314 width: 8,
315 height: 8,
316 channels: 4,
317 data: img_8x8_rgb_punchthrough_etc2,
318 format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
321 width: 8,
322 height: 8,
323 channels: 4,
324 data: img_8x8_rgb_punchthrough_etc2,
325 format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
328 width: 8,
329 height: 8,
330 channels: 4,
331 data: img_8x8_rgba_etc2,
332 format: ext.COMPRESSED_RGBA8_ETC2_EAC
335 width: 8,
336 height: 8,
337 channels: 4,
338 data: img_8x8_rgba_etc2,
339 format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
342 width: 32,
343 height: 32,
344 channels: 1,
345 data: img_32x32_r11_eac,
346 format: ext.COMPRESSED_R11_EAC
349 width: 32,
350 height: 32,
351 channels: 1,
352 data: img_32x32_signed_r11_eac,
353 format: ext.COMPRESSED_SIGNED_R11_EAC
356 width: 32,
357 height: 32,
358 channels: 2,
359 data: img_32x32_rg11_eac,
360 format: ext.COMPRESSED_RG11_EAC
363 width: 32,
364 height: 32,
365 channels: 2,
366 data: img_32x32_signed_rg11_eac,
367 format: ext.COMPRESSED_SIGNED_RG11_EAC
370 width: 32,
371 height: 32,
372 channels: 3,
373 data: img_32x32_rgb_etc2,
374 format: ext.COMPRESSED_RGB8_ETC2
377 width: 32,
378 height: 32,
379 channels: 3,
380 data: img_32x32_rgb_etc2,
381 format: ext.COMPRESSED_SRGB8_ETC2
384 width: 32,
385 height: 32,
386 channels: 4,
387 data: img_32x32_rgb_punchthrough_etc2,
388 format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
391 width: 32,
392 height: 32,
393 channels: 4,
394 data: img_32x32_rgb_punchthrough_etc2,
395 format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
398 width: 32,
399 height: 32,
400 channels: 4,
401 data: img_32x32_rgba_etc2,
402 format: ext.COMPRESSED_RGBA8_ETC2_EAC
405 width: 32,
406 height: 32,
407 channels: 4,
408 data: img_32x32_rgba_etc2,
409 format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
412 testETCTextures(tests);
415 function testETCTextures(tests) {
416 for (var ii = 0; ii < tests.length; ++ii) {
417 testETCTexture(tests[ii]);
421 /* Return the size of block in bytes */
422 function getBlockSize(format) {
423 switch (format) {
424 case ext.COMPRESSED_R11_EAC:
425 case ext.COMPRESSED_SIGNED_R11_EAC:
426 case ext.COMPRESSED_RGB8_ETC2:
427 case ext.COMPRESSED_SRGB8_ETC2:
428 case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
429 case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
430 return 8;
431 case ext.COMPRESSED_RG11_EAC:
432 case ext.COMPRESSED_SIGNED_RG11_EAC:
433 case ext.COMPRESSED_RGBA8_ETC2_EAC:
434 case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
435 return 16
437 throw new Error(`Unexpected format ${format}`);
440 function copyRect(data, srcX, srcY, dstX, dstY, width, height, stride) {
441 var bytesPerLine = width * 4;
442 var srcOffset = srcX * 4 + srcY * stride;
443 var dstOffset = dstX * 4 + dstY * stride;
444 for (var jj = height; jj > 0; --jj) {
445 for (var ii = 0; ii < bytesPerLine; ++ii) {
446 data[dstOffset + ii] = data[srcOffset + ii];
448 srcOffset += stride;
449 dstOffset += stride;
453 function testETCTexture(test) {
454 var data = new Uint8Array(test.data.compressed);
455 var width = test.width;
456 var height = test.height;
457 var format = test.format;
459 var uncompressedData = new Uint8Array(test.data.decompressed);
460 var glErrorShouldBe = (glInner, glError, msg) => {
461 msg = msg || "";
462 var err = glInner.getError();
463 var getGLErrorAsString = error => {
464 if (error === glInner.NO_ERROR) {
465 return "NO_ERROR";
467 for (let name in glInner) {
468 if (glInner[name] === error) {
469 return name;
472 return error.toString();
475 if (err != glError) {
476 ok(false, "getError expected: " + getGLErrorAsString(glError) +
477 ". Was " + getGLErrorAsString(err) + " : " + msg);
478 } else {
479 ok(true, "getError was expected value: " +
480 getGLErrorAsString(glError) + " : " + msg);
484 canvas.width = width;
485 canvas.height = height;
486 gl.viewport(0, 0, width, height);
488 var tex = gl.createTexture();
489 gl.bindTexture(gl.TEXTURE_2D, tex);
490 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
491 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
492 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
493 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
494 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
495 glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
496 gl.generateMipmap(gl.TEXTURE_2D);
497 glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
498 if (format == ext.COMPRESSED_SIGNED_R11_EAC) {
499 var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-r');
500 } else if (format == ext.COMPRESSED_SIGNED_RG11_EAC) {
501 var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-rg');
502 } else {
503 var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader');
505 gl.bindAttribLocation(program, 0, 'vPosition');
506 gl.bindAttribLocation(program, 1, 'texCoord0');
507 gl.useProgram(program);
509 gl.clearColor(1.0, 1.0, 1.0, 1.0);
510 gl.clear(gl.COLOR_BUFFER_BIT);
511 gl.drawArrays(gl.TRIANGLES, 0, 6);
512 compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
514 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
515 glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
517 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
518 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
519 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
520 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
521 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
522 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
523 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
524 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
526 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
527 glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
528 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
529 glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
530 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
531 glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
532 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
533 glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
535 if (width == 4) {
536 gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
537 glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
538 gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
539 glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
541 if (height == 4) {
542 gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
543 glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
544 gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
545 glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
548 // pick a wrong format that uses the same amount of data.
549 var wrongFormat;
550 switch (format) {
551 case ext.COMPRESSED_R11_EAC:
552 wrongFormat = ext.COMPRESSED_SIGNED_R11_EAC;
553 break;
554 case ext.COMPRESSED_SIGNED_R11_EAC:
555 wrongFormat = ext.COMPRESSED_R11_EAC;
556 break;
557 case ext.COMPRESSED_RG11_EAC:
558 wrongFormat = ext.COMPRESSED_SIGNED_RG11_EAC;
559 break;
560 case ext.COMPRESSED_SIGNED_RG11_EAC:
561 wrongFormat = ext.COMPRESSED_RG11_EAC;
562 break;
563 case ext.COMPRESSED_RGB8_ETC2:
564 wrongFormat = ext.COMPRESSED_SRGB8_ETC2;
565 break;
566 case ext.COMPRESSED_SRGB8_ETC2:
567 wrongFormat = ext.COMPRESSED_RGB8_ETC2;
568 break;
569 case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
570 wrongFormat = ext.COMPRESSED_RGB8_ETC2;
571 break;
572 case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
573 wrongFormat = ext.COMPRESSED_RGB8_ETC2;
574 break;
575 case ext.COMPRESSED_RGBA8_ETC2_EAC:
576 wrongFormat = ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
577 break;
578 case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
579 wrongFormat = ext.COMPRESSED_RGBA8_ETC2_EAC;
580 break;
583 // Restore original texture.
584 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
585 glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
587 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);
588 glErrorShouldBe(gl, gl.INVALID_OPERATION, "format does not match");
590 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width + 4, height, format, data);
591 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
592 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height + 4, format, data);
593 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
594 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 4, height, format, data);
595 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
596 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 4, format, data);
597 glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
599 gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
600 glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
601 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 1, height, format, data);
602 glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
603 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data);
604 glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
605 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 1, format, data);
606 glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
607 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data);
608 glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
610 var subData = new Uint8Array(data.buffer, 0, getBlockSize(format));
612 if (width == 8 && height == 8) {
613 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, format, subData);
614 glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
615 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, format, subData);
616 glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
619 if (width < 32 && height < 32) {
620 var stride = width * 4;
621 for (var yoff = 0; yoff < height; yoff += 4) {
622 for (var xoff = 0; xoff < width; xoff += 4) {
623 copyRect(uncompressedData, 0, 0, xoff, yoff, 4, 4, stride);
624 gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, xoff, yoff, 4, 4, format, subData);
625 glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
626 gl.clearColor(1.0, 1.0, 1.0, 1.0);
627 gl.clear(gl.COLOR_BUFFER_BIT);
628 gl.drawArrays(gl.TRIANGLES, 0, 6);
629 compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
635 function insertImg(element, caption, img) {
636 var div = document.createElement("div");
637 div.appendChild(img);
638 var label = document.createElement("div");
639 label.appendChild(document.createTextNode(caption));
640 div.appendChild(label);
641 element.appendChild(div);
644 function convertToSRGB(val) {
645 var norm = val / 255.0;
646 var res = 0;
647 if (norm <= 0.04045) {
648 res = norm / 12.92;
649 } else {
650 res = Math.pow(((norm + 0.055)/1.055), 2.4);
653 return res * 255.0;
656 function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
657 var scale = 8;
658 var c = document.createElement("canvas");
659 c.width = imageWidth * scale;
660 c.height = imageHeight * scale;
661 var ctx = c.getContext("2d");
662 for (var yy = 0; yy < imageHeight; ++yy) {
663 for (var xx = 0; xx < imageWidth; ++xx) {
664 var offset = (yy * dataWidth + xx) * 4;
665 ctx.fillStyle = "rgba(" +
666 data[offset + 0] + "," +
667 data[offset + 1] + "," +
668 data[offset + 2] + "," +
669 (alpha ? data[offset + 3] / 255 : 1) + ")";
670 ctx.fillRect(xx * scale, yy * scale, scale, scale);
673 var img = document.createElement("img");
674 img.src = c.toDataURL();
675 return img;
678 function compareRect(actualWidth, actualHeight, actualChannels,
679 dataWidth, dataHeight, expectedData,
680 testData, testFormat)
682 var actual = new Uint8Array(actualWidth * actualHeight * 4);
683 gl.readPixels(
684 0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
686 var div = document.createElement("div");
687 div.className = "testimages";
688 var hasAlpha = actualChannels == 4;
689 var imgExpected = makeImage(actualWidth, actualHeight, dataWidth, expectedData, hasAlpha);
690 var imgActual = makeImage(actualWidth, actualHeight, actualWidth, actual, hasAlpha);
691 insertImg(div, "expected", imgExpected);
692 insertImg(div, "actual", imgActual);
693 div.appendChild(document.createElement('br'));
694 document.getElementById("console").appendChild(div);
696 var failed = false;
697 for (var yy = 0; yy < actualHeight; ++yy) {
698 for (var xx = 0; xx < actualWidth; ++xx) {
699 var actualOffset = (yy * actualWidth + xx) * 4;
700 var expectedOffset = (yy * dataWidth + xx) * 4;
701 var expected = expectedData.slice(expectedOffset, expectedOffset + 4);
703 var maxDiffPixel = 0;
704 switch (testFormat) {
705 case ext.COMPRESSED_SRGB8_ETC2:
706 case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
707 case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
709 // Alpha shouldn't do conversion.
710 for (var i = 0; i < 3; ++i) {
711 expected[i] = convertToSRGB(expected[i]);
713 //fallthrough
714 case ext.COMPRESSED_R11_EAC:
715 case ext.COMPRESSED_RG11_EAC:
716 case ext.COMPRESSED_SIGNED_R11_EAC:
717 case ext.COMPRESSED_SIGNED_RG11_EAC:
718 // Due to floating round error, we need fuzzy test here.
719 var maxDiffPixel = 1;
720 break;
721 default:
722 var maxDiffPixel = 0;
723 break;
726 for (var channel = 0; channel < actualChannels; ++channel) {
727 var diff = Math.abs(expected[channel] - actual[actualOffset + channel]);
729 if (diff > maxDiffPixel) {
730 failed = true;
731 var was = actual.slice(actualOffset, actualOffset + 4).join();
732 ok(false, 'at (' + xx + ', ' + yy +
733 ') expected: ' + expected.join() + ' was ' + was);
734 break;
739 if (!failed) {
740 ok(true, "texture rendered correctly");
744 var prefArrArr = [
745 ['webgl.enable-draft-extensions', true],
747 var prefEnv = {'set': prefArrArr};
748 SimpleTest.waitForExplicitFinish();
749 SpecialPowers.pushPrefEnv(prefEnv, runTest);
750 </script>
751 </body>
752 </html>