Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

  • This test gets skipped with pattern: (os == 'android')
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script src="webgl-util.js"></script>
<script src="es3-data.js"></script>
<title>WebGL test: test WEBGL_compressed_texture_etc extension</title>
<style>
img {
border: 1px solid black;
margin-right: 1em;
}
.testimages {
}
.testimages br {
clear: both;
}
.testimages > div {
float: left;
margin: 1em;
}
</style>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" width="8" height="8"></canvas>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord;
void main() {
gl_Position = vPosition;
texCoord = texCoord0;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
gl_FragData[0] = texture2D(tex, texCoord);
}
</script>
<script id="fshader-r" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
vec4 pixel = (texture2D(tex, texCoord));
pixel.r = (pixel.r + 1.0) / 2.0;
gl_FragData[0] = pixel;
}
</script>
<script id="fshader-rg" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
vec4 pixel = (texture2D(tex, texCoord));
pixel.rg = (pixel.rg + 1.0) / 2.0;
gl_FragData[0] = pixel;
}
</script>
<script>
"use strict";
var ext = null;
var vao = null;
var gl = null;
var validFormats = {
COMPRESSED_R11_EAC : 0x9270,
COMPRESSED_SIGNED_R11_EAC : 0x9271,
COMPRESSED_RG11_EAC : 0x9272,
COMPRESSED_SIGNED_RG11_EAC : 0x9273,
COMPRESSED_RGB8_ETC2 : 0x9274,
COMPRESSED_SRGB8_ETC2 : 0x9275,
COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276,
COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277,
COMPRESSED_RGBA8_ETC2_EAC : 0x9278,
COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279,
};
function setupUnitQuad() {
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
}
function runTest() {
gl = canvas.getContext('webgl', {antialias: false});
if (!gl) {
ok(false, "WebGL context does not exist");
} else {
ok(true, "WebGL context exists");
setupUnitQuad();
// Run tests with extension disabled
runTestDisabled();
// Query the extension and store globally so shouldBe can access it
ext = gl.getExtension("WEBGL_compressed_texture_etc");
if (!ext) {
ok(true, "No WEBGL_compressed_texture_etc support -- this is legal");
runSupportedTest(false);
} else {
ok(true, "Successfully enabled WEBGL_compressed_texture_etc extension");
runSupportedTest(true);
runTestExtension();
}
}
SimpleTest.finish();
}
function runSupportedTest(extensionEnabled) {
var supported = gl.getSupportedExtensions();
if (supported.includes("WEBGL_compressed_texture_etc")) {
if (extensionEnabled) {
ok(true, "WEBGL_compressed_texture_etc listed as supported and getExtension succeeded");
} else {
ok(false, "WEBGL_compressed_texture_etc listed as supported but getExtension failed");
}
} else {
if (extensionEnabled) {
ok(false, "WEBGL_compressed_texture_etc not listed as supported but getExtension succeeded");
} else {
ok(true, "WEBGL_compressed_texture_etc not listed as supported and getExtension failed -- this is legal");
}
}
}
function runTestDisabled() {
is(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS).length, 0,
"Should be no compressed texture formats");
}
function formatExists(format, supportedFormats) {
for (var ii = 0; ii < supportedFormats.length; ++ii) {
if (format == supportedFormats[ii]) {
ok(true, "supported format " + formatToString(format) + " is exists");
return;
}
}
ok(false, "supported format " + formatToString(format) + " does not exist");
}
function formatToString(format) {
for (var p in ext) {
if (ext[p] == format) {
return p;
}
}
return "0x" + format.toString(16);
}
function runTestExtension() {
// check that all format enums exist.
for (let name in validFormats) {
is(ext[name], validFormats[name], "format is match");
}
let supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
// There should be exactly 10 formats
is(supportedFormats.length, 10, "Should be exactly 10 formats");
// check that all 10 formats exist
for (let name in validFormats.length) {
formatExists(validFormats[name], supportedFormats);
}
// Test each format
testETC2_RGB();
}
function testETC2_RGB() {
var tests = [
{
width: 4,
height: 4,
channels: 1,
data: img_4x4_r11_eac,
format: ext.COMPRESSED_R11_EAC
},
{
width: 4,
height: 4,
channels: 1,
data: img_4x4_signed_r11_eac,
format: ext.COMPRESSED_SIGNED_R11_EAC
},
{
width: 4,
height: 4,
channels: 2,
data: img_4x4_rg11_eac,
format: ext.COMPRESSED_RG11_EAC
},
{
width: 4,
height: 4,
channels: 2,
data: img_4x4_signed_rg11_eac,
format: ext.COMPRESSED_SIGNED_RG11_EAC
},
{
width: 4,
height: 4,
channels: 3,
data: img_4x4_rgb_etc2,
format: ext.COMPRESSED_RGB8_ETC2
},
{
width: 4,
height: 4,
channels: 3,
data: img_4x4_rgb_etc2,
format: ext.COMPRESSED_SRGB8_ETC2
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgb_punchthrough_etc2,
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgb_punchthrough_etc2,
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgba_etc2,
format: ext.COMPRESSED_RGBA8_ETC2_EAC
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgba_etc2,
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
},
{
width: 8,
height: 8,
channels: 1,
data: img_8x8_r11_eac,
format: ext.COMPRESSED_R11_EAC
},
{
width: 8,
height: 8,
channels: 1,
data: img_8x8_signed_r11_eac,
format: ext.COMPRESSED_SIGNED_R11_EAC
},
{
width: 8,
height: 8,
channels: 2,
data: img_8x8_rg11_eac,
format: ext.COMPRESSED_RG11_EAC
},
{
width: 8,
height: 8,
channels: 2,
data: img_8x8_signed_rg11_eac,
format: ext.COMPRESSED_SIGNED_RG11_EAC
},
{
width: 8,
height: 8,
channels: 3,
data: img_8x8_rgb_etc2,
format: ext.COMPRESSED_RGB8_ETC2
},
{
width: 8,
height: 8,
channels: 3,
data: img_8x8_rgb_etc2,
format: ext.COMPRESSED_SRGB8_ETC2
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgb_punchthrough_etc2,
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgb_punchthrough_etc2,
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgba_etc2,
format: ext.COMPRESSED_RGBA8_ETC2_EAC
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgba_etc2,
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
},
{
width: 32,
height: 32,
channels: 1,
data: img_32x32_r11_eac,
format: ext.COMPRESSED_R11_EAC
},
{
width: 32,
height: 32,
channels: 1,
data: img_32x32_signed_r11_eac,
format: ext.COMPRESSED_SIGNED_R11_EAC
},
{
width: 32,
height: 32,
channels: 2,
data: img_32x32_rg11_eac,
format: ext.COMPRESSED_RG11_EAC
},
{
width: 32,
height: 32,
channels: 2,
data: img_32x32_signed_rg11_eac,
format: ext.COMPRESSED_SIGNED_RG11_EAC
},
{
width: 32,
height: 32,
channels: 3,
data: img_32x32_rgb_etc2,
format: ext.COMPRESSED_RGB8_ETC2
},
{
width: 32,
height: 32,
channels: 3,
data: img_32x32_rgb_etc2,
format: ext.COMPRESSED_SRGB8_ETC2
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgb_punchthrough_etc2,
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgb_punchthrough_etc2,
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgba_etc2,
format: ext.COMPRESSED_RGBA8_ETC2_EAC
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgba_etc2,
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
},
];
testETCTextures(tests);
}
function testETCTextures(tests) {
for (var ii = 0; ii < tests.length; ++ii) {
testETCTexture(tests[ii]);
}
}
/* Return the size of block in bytes */
function getBlockSize(format) {
switch (format) {
case ext.COMPRESSED_R11_EAC:
case ext.COMPRESSED_SIGNED_R11_EAC:
case ext.COMPRESSED_RGB8_ETC2:
case ext.COMPRESSED_SRGB8_ETC2:
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
return 8;
case ext.COMPRESSED_RG11_EAC:
case ext.COMPRESSED_SIGNED_RG11_EAC:
case ext.COMPRESSED_RGBA8_ETC2_EAC:
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
return 16
}
}
function copyRect(data, srcX, srcY, dstX, dstY, width, height, stride) {
var bytesPerLine = width * 4;
var srcOffset = srcX * 4 + srcY * stride;
var dstOffset = dstX * 4 + dstY * stride;
for (var jj = height; jj > 0; --jj) {
for (var ii = 0; ii < bytesPerLine; ++ii) {
data[dstOffset + ii] = data[srcOffset + ii];
}
srcOffset += stride;
dstOffset += stride;
}
}
function testETCTexture(test) {
var data = new Uint8Array(test.data.compressed);
var width = test.width;
var height = test.height;
var format = test.format;
var uncompressedData = new Uint8Array(test.data.decompressed);
var glErrorShouldBe = (glInner, glError, msg) => {
msg = msg || "";
var err = glInner.getError();
var getGLErrorAsString = error => {
if (error === glInner.NO_ERROR) {
return "NO_ERROR";
}
for (let name in glInner) {
if (glInner[name] === error) {
return name;
}
}
return error.toString();
}
if (err != glError) {
ok(false, "getError expected: " + getGLErrorAsString(glError) +
". Was " + getGLErrorAsString(err) + " : " + msg);
} else {
ok(true, "getError was expected value: " +
getGLErrorAsString(glError) + " : " + msg);
}
};
canvas.width = width;
canvas.height = height;
gl.viewport(0, 0, width, height);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
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);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.generateMipmap(gl.TEXTURE_2D);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
if (format == ext.COMPRESSED_SIGNED_R11_EAC) {
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-r');
} else if (format == ext.COMPRESSED_SIGNED_RG11_EAC) {
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-rg');
} else {
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader');
}
gl.bindAttribLocation(program, 0, 'vPosition');
gl.bindAttribLocation(program, 1, 'texCoord0');
gl.useProgram(program);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
if (width == 4) {
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
}
if (height == 4) {
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
}
// pick a wrong format that uses the same amount of data.
var wrongFormat;
switch (format) {
case ext.COMPRESSED_R11_EAC:
wrongFormat = ext.COMPRESSED_SIGNED_R11_EAC;
break;
case ext.COMPRESSED_SIGNED_R11_EAC:
wrongFormat = ext.COMPRESSED_R11_EAC;
break;
case ext.COMPRESSED_RG11_EAC:
wrongFormat = ext.COMPRESSED_SIGNED_RG11_EAC;
break;
case ext.COMPRESSED_SIGNED_RG11_EAC:
wrongFormat = ext.COMPRESSED_RG11_EAC;
break;
case ext.COMPRESSED_RGB8_ETC2:
wrongFormat = ext.COMPRESSED_SRGB8_ETC2;
break;
case ext.COMPRESSED_SRGB8_ETC2:
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
break;
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
break;
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
break;
case ext.COMPRESSED_RGBA8_ETC2_EAC:
wrongFormat = ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
break;
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
wrongFormat = ext.COMPRESSED_RGBA8_ETC2_EAC;
break;
}
// Restore original texture.
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "format does not match");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width + 4, height, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height + 4, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 4, height, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 4, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 1, height, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 1, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
var subData = new Uint8Array(data.buffer, 0, getBlockSize(format));
if (width == 8 && height == 8) {
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, format, subData);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, format, subData);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
}
if (width < 32 && height < 32) {
var stride = width * 4;
for (var yoff = 0; yoff < height; yoff += 4) {
for (var xoff = 0; xoff < width; xoff += 4) {
copyRect(uncompressedData, 0, 0, xoff, yoff, 4, 4, stride);
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, xoff, yoff, 4, 4, format, subData);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
}
}
}
}
function insertImg(element, caption, img) {
var div = document.createElement("div");
div.appendChild(img);
var label = document.createElement("div");
label.appendChild(document.createTextNode(caption));
div.appendChild(label);
element.appendChild(div);
}
function convertToSRGB(val) {
var norm = val / 255.0;
var res = 0;
if (norm <= 0.04045) {
res = norm / 12.92;
} else {
res = Math.pow(((norm + 0.055)/1.055), 2.4);
}
return res * 255.0;
}
function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
var scale = 8;
var c = document.createElement("canvas");
c.width = imageWidth * scale;
c.height = imageHeight * scale;
var ctx = c.getContext("2d");
for (var yy = 0; yy < imageHeight; ++yy) {
for (var xx = 0; xx < imageWidth; ++xx) {
var offset = (yy * dataWidth + xx) * 4;
ctx.fillStyle = "rgba(" +
data[offset + 0] + "," +
data[offset + 1] + "," +
data[offset + 2] + "," +
(alpha ? data[offset + 3] / 255 : 1) + ")";
ctx.fillRect(xx * scale, yy * scale, scale, scale);
}
}
var img = document.createElement("img");
img.src = c.toDataURL();
return img;
}
function compareRect(actualWidth, actualHeight, actualChannels,
dataWidth, dataHeight, expectedData,
testData, testFormat)
{
var actual = new Uint8Array(actualWidth * actualHeight * 4);
gl.readPixels(
0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
var div = document.createElement("div");
div.className = "testimages";
var hasAlpha = actualChannels == 4;
var imgExpected = makeImage(actualWidth, actualHeight, dataWidth, expectedData, hasAlpha);
var imgActual = makeImage(actualWidth, actualHeight, actualWidth, actual, hasAlpha);
insertImg(div, "expected", imgExpected);
insertImg(div, "actual", imgActual);
div.appendChild(document.createElement('br'));
document.getElementById("console").appendChild(div);
var failed = false;
for (var yy = 0; yy < actualHeight; ++yy) {
for (var xx = 0; xx < actualWidth; ++xx) {
var actualOffset = (yy * actualWidth + xx) * 4;
var expectedOffset = (yy * dataWidth + xx) * 4;
var expected = expectedData.slice(expectedOffset, expectedOffset + 4);
var maxDiffPixel = 0;
switch (testFormat) {
case ext.COMPRESSED_SRGB8_ETC2:
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
// Alpha shouldn't do conversion.
for (var i = 0; i < 3; ++i) {
expected[i] = convertToSRGB(expected[i]);
}
//fallthrough
case ext.COMPRESSED_R11_EAC:
case ext.COMPRESSED_RG11_EAC:
case ext.COMPRESSED_SIGNED_R11_EAC:
case ext.COMPRESSED_SIGNED_RG11_EAC:
// Due to floating round error, we need fuzzy test here.
var maxDiffPixel = 1;
break;
default:
var maxDiffPixel = 0;
break;
}
for (var channel = 0; channel < actualChannels; ++channel) {
var diff = Math.abs(expected[channel] - actual[actualOffset + channel]);
if (diff > maxDiffPixel) {
failed = true;
var was = actual.slice(actualOffset, actualOffset + 4).join();
ok(false, 'at (' + xx + ', ' + yy +
') expected: ' + expected.join() + ' was ' + was);
break;
}
}
}
}
if (!failed) {
ok(true, "texture rendered correctly");
}
}
var prefArrArr = [
['webgl.enable-draft-extensions', true],
];
var prefEnv = {'set': prefArrArr};
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(prefEnv, runTest);
</script>
</body>
</html>