content/canvas/test/webgl-conformance/conformance/extensions/webgl-compressed-texture-etc1.html

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/canvas/test/webgl-conformance/conformance/extensions/webgl-compressed-texture-etc1.html	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,506 @@
     1.4 +<!--
     1.5 +
     1.6 +/*
     1.7 +** Copyright (c) 2012 The Khronos Group Inc.
     1.8 +**
     1.9 +** Permission is hereby granted, free of charge, to any person obtaining a
    1.10 +** copy of this software and/or associated documentation files (the
    1.11 +** "Materials"), to deal in the Materials without restriction, including
    1.12 +** without limitation the rights to use, copy, modify, merge, publish,
    1.13 +** distribute, sublicense, and/or sell copies of the Materials, and to
    1.14 +** permit persons to whom the Materials are furnished to do so, subject to
    1.15 +** the following conditions:
    1.16 +**
    1.17 +** The above copyright notice and this permission notice shall be included
    1.18 +** in all copies or substantial portions of the Materials.
    1.19 +**
    1.20 +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    1.21 +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    1.22 +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    1.23 +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    1.24 +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    1.25 +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    1.26 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
    1.27 +*/
    1.28 +
    1.29 +-->
    1.30 +
    1.31 +<!DOCTYPE html>
    1.32 +<html>
    1.33 +<head>
    1.34 +<meta charset="utf-8">
    1.35 +<link rel="stylesheet" href="../../resources/js-test-style.css"/>
    1.36 +<script src="../../resources/js-test-pre.js"></script>
    1.37 +<script src="../resources/webgl-test.js"></script>
    1.38 +<script src="../resources/webgl-test-utils.js"></script>
    1.39 +<title>WebGL WEBGL_compressed_texture_etc1 Conformance Tests</title>
    1.40 +<style>
    1.41 +img {
    1.42 + border: 1px solid black;
    1.43 + margin-right: 1em;
    1.44 +}
    1.45 +.testimages {
    1.46 +}
    1.47 +
    1.48 +.testimages br {
    1.49 +  clear: both;
    1.50 +}
    1.51 +
    1.52 +.testimages > div {
    1.53 +  float: left;
    1.54 +  margin: 1em;
    1.55 +}
    1.56 +</style>
    1.57 +</head>
    1.58 +<body>
    1.59 +<div id="description"></div>
    1.60 +<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
    1.61 +<div id="console"></div>
    1.62 +<script>
    1.63 +"use strict";
    1.64 +description("This test verifies the functionality of the WEBGL_compressed_texture_etc1 extension, if it is available.");
    1.65 +
    1.66 +debug("");
    1.67 +
    1.68 +var img_4x4_rgb_etc1 = new Uint8Array([
    1.69 +    0x00, 0xc0, 0x00, 0xff, 0x07, 0x45, 0x07, 0x45
    1.70 +]);
    1.71 +var img_8x8_rgb_etc1 = new Uint8Array([
    1.72 +    0x00, 0xff, 0x55, 0xfc, 0xff, 0xff, 0x07, 0x45,
    1.73 +    0x11, 0x11, 0xff, 0xfc, 0xf8, 0xba, 0x07, 0x45,
    1.74 +    0xee, 0x00, 0xee, 0xfc, 0x07, 0x45, 0x07, 0x45,
    1.75 +    0x00, 0x90, 0xf8, 0x92, 0x07, 0x45, 0xff, 0xff,
    1.76 +]);
    1.77 +
    1.78 +var wtu = WebGLTestUtils;
    1.79 +var canvas = document.getElementById("canvas");
    1.80 +var gl = wtu.create3DContext(canvas, {antialias: false});
    1.81 +var program = wtu.setupTexturedQuad(gl);
    1.82 +var ext = null;
    1.83 +var vao = null;
    1.84 +var validFormats = {
    1.85 +    COMPRESSED_RGB_ETC1_WEBGL : 0x8D64
    1.86 +};
    1.87 +var name;
    1.88 +var supportedFormats;
    1.89 +
    1.90 +if (!gl) {
    1.91 +    testFailed("WebGL context does not exist");
    1.92 +} else {
    1.93 +    testPassed("WebGL context exists");
    1.94 +
    1.95 +    // Run tests with extension disabled
    1.96 +    runTestDisabled();
    1.97 +
    1.98 +    // Query the extension and store globally so shouldBe can access it
    1.99 +    ext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_compressed_texture_etc1");
   1.100 +    if (!ext) {
   1.101 +        testPassed("No WEBGL_compressed_texture_etc1 support -- this is legal");
   1.102 +        runSupportedTest(false);
   1.103 +    } else {
   1.104 +        testPassed("Successfully enabled WEBGL_compressed_texture_etc1 extension");
   1.105 +
   1.106 +        runSupportedTest(true);
   1.107 +        runTestExtension();
   1.108 +    }
   1.109 +}
   1.110 +
   1.111 +function runSupportedTest(extensionEnabled) {
   1.112 +    var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_compressed_texture_etc1");
   1.113 +    if (name !== undefined) {
   1.114 +        if (extensionEnabled) {
   1.115 +            testPassed("WEBGL_compressed_texture_etc1 listed as supported and getExtension succeeded");
   1.116 +        } else {
   1.117 +            testFailed("WEBGL_compressed_texture_etc1 listed as supported but getExtension failed");
   1.118 +        }
   1.119 +    } else {
   1.120 +        if (extensionEnabled) {
   1.121 +            testFailed("WEBGL_compressed_texture_etc1 not listed as supported but getExtension succeeded");
   1.122 +        } else {
   1.123 +            testPassed("WEBGL_compressed_texture_etc1 not listed as supported and getExtension failed -- this is legal");
   1.124 +        }
   1.125 +    }
   1.126 +}
   1.127 +
   1.128 +
   1.129 +function runTestDisabled() {
   1.130 +    debug("Testing binding enum with extension disabled");
   1.131 +
   1.132 +    shouldBe('gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS)', '[]');
   1.133 +}
   1.134 +
   1.135 +function formatExists(format, supportedFormats) {
   1.136 +    for (var ii = 0; ii < supportedFormats.length; ++ii) {
   1.137 +        if (format == supportedFormats[ii]) {
   1.138 +            testPassed("supported format " + formatToString(format) + " is exists");
   1.139 +            return;
   1.140 +        }
   1.141 +    }
   1.142 +    testFailed("supported format " + formatToString(format) + " does not exist");
   1.143 +}
   1.144 +
   1.145 +function formatToString(format) {
   1.146 +    for (var p in ext) {
   1.147 +        if (ext[p] == format) {
   1.148 +            return p;
   1.149 +        }
   1.150 +    }
   1.151 +    return "0x" + format.toString(16);
   1.152 +}
   1.153 +
   1.154 +function runTestExtension() {
   1.155 +    debug("Testing WEBGL_compressed_texture_etc1");
   1.156 +
   1.157 +    // check that all format enums exist.
   1.158 +    for (name in validFormats) {
   1.159 +        var expected = "0x" + validFormats[name].toString(16);
   1.160 +        var actual = "ext['" + name + "']";
   1.161 +        shouldBe(actual, expected);
   1.162 +    }
   1.163 +
   1.164 +    supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
   1.165 +    // There should be exactly 4 formats
   1.166 +    shouldBe("supportedFormats.length", "1");
   1.167 +
   1.168 +    // check that all 4 formats exist
   1.169 +    for (var name in validFormats.length) {
   1.170 +        formatExists(validFormats[name], supportedFormats);
   1.171 +    }
   1.172 +
   1.173 +    // Test each format
   1.174 +    testETC1_RGB();
   1.175 +}
   1.176 +
   1.177 +function testETC1_RGB() {
   1.178 +    var tests = [
   1.179 +        {   width: 4,
   1.180 +            height: 4,
   1.181 +            channels: 3,
   1.182 +            data: img_4x4_rgb_etc1,
   1.183 +            format: ext.COMPRESSED_RGB_ETC1_WEBGL
   1.184 +        },
   1.185 +        {   width: 8,
   1.186 +            height: 8,
   1.187 +            channels: 3,
   1.188 +            data: img_8x8_rgb_etc1,
   1.189 +            format: ext.COMPRESSED_RGB_ETC1_WEBGL
   1.190 +        }
   1.191 +    ];
   1.192 +    testETCTextures(tests);
   1.193 +}
   1.194 +
   1.195 +function testETCTextures(tests) {
   1.196 +    for (var ii = 0; ii < tests.length; ++ii) {
   1.197 +        debug("<hr/>");
   1.198 +        testETCTexture(tests[ii]);
   1.199 +    }
   1.200 +}
   1.201 +
   1.202 +function offset_color(c, o) {
   1.203 +    return [
   1.204 +        Math.min(Math.max(0, c[0] + o), 255),
   1.205 +        Math.min(Math.max(0, c[1] + o), 255),
   1.206 +        Math.min(Math.max(0, c[2] + o), 255),
   1.207 +        c[3]
   1.208 +    ];
   1.209 +}
   1.210 +
   1.211 +function uncompressETC1Block(destBuffer, destX, destY, destWidth, src) {
   1.212 +    'use strict';
   1.213 +    var xx, yy, basecols;
   1.214 +    var _deltatable = [ 0, 1, 2, 3, -4, -3, -2, -1 ];
   1.215 +    var _modtable = [
   1.216 +        [ 2,    8,  -2,   -8 ],
   1.217 +        [ 5,   17,  -5,  -17 ],
   1.218 +        [ 9,   29,  -9,  -29 ],
   1.219 +        [ 13,  42, -13,  -42 ],
   1.220 +        [ 18,  60, -18,  -60 ],
   1.221 +        [ 24,  80, -24,  -80 ],
   1.222 +        [ 33, 106, -33, -106 ],
   1.223 +        [ 47, 183, -47, -183 ]
   1.224 +    ];
   1.225 +    var _sl = [
   1.226 +        0x00, 0x01, 0x04, 0x05,
   1.227 +        0x10, 0x11, 0x14, 0x15,
   1.228 +        0x40, 0x41, 0x44, 0x45,
   1.229 +        0x50, 0x51, 0x54, 0x55
   1.230 +    ];
   1.231 +    var _sh = [
   1.232 +        0x00, 0x02, 0x08, 0x0a,
   1.233 +        0x20, 0x22, 0x28, 0x2a,
   1.234 +        0x80, 0x82, 0x88, 0x8a,
   1.235 +        0xa0, 0xa2, 0xa8, 0xaa
   1.236 +    ];
   1.237 +
   1.238 +    function extend_4to8bits(r, g, b) {
   1.239 +        return [
   1.240 +            (r & 0xf0) | ((r >> 4) & 0x0f),
   1.241 +            (g & 0xf0) | ((g >> 4) & 0x0f),
   1.242 +            (b & 0xf0) | ((b >> 4) & 0x0f),
   1.243 +            255
   1.244 +        ];
   1.245 +    }
   1.246 +
   1.247 +    function extend_5to8bits(r, g, b) {
   1.248 +        return [
   1.249 +            (r & 0xf8) | ((r >> 5) & 0x07),
   1.250 +            (g & 0xf8) | ((g >> 5) & 0x07),
   1.251 +            (b & 0xf8) | ((b >> 5) & 0x07),
   1.252 +            255
   1.253 +        ];
   1.254 +    }
   1.255 +
   1.256 +    function base_colors(src, mode) {
   1.257 +        var col_1, col_2, didx, d;
   1.258 +        if (mode === 'I') {
   1.259 +            col_1 = extend_4to8bits(src[0], src[1], src[2]);
   1.260 +            col_2 = extend_4to8bits(src[0] << 4, src[1] << 4, src[2] << 4);
   1.261 +            return [ col_1, col_2 ];
   1.262 +        }
   1.263 +
   1.264 +        if (mode === 'D') {
   1.265 +            col_1 = extend_5to8bits(src[0], src[1], src[2]);
   1.266 +            col_2 = extend_5to8bits(src[0] + 8 * _deltatable[(src[0] & 0x7)],
   1.267 +                                    src[1] + 8 * _deltatable[(src[1] & 0x7)],
   1.268 +                                    src[2] + 8 * _deltatable[(src[2] & 0x7)]);
   1.269 +            return [ col_1, col_2 ];
   1.270 +        }
   1.271 +
   1.272 +        return [];
   1.273 +    }
   1.274 +
   1.275 +    function mode(src) {
   1.276 +        return (src[3] & 0x2) ? 'D' : 'I';
   1.277 +    }
   1.278 +
   1.279 +    function flip(src) {
   1.280 +        return (src[3] & 0x1) === 0x1;
   1.281 +    }
   1.282 +
   1.283 +    function subblock_modtable(src, sb) {
   1.284 +        var shift = (sb ? 2 : 5);
   1.285 +        var idx = (src[3] >> shift) & 0x7;
   1.286 +        return _modtable[idx];
   1.287 +    }
   1.288 +
   1.289 +    function interleave_table_indices(src) {
   1.290 +        var result =
   1.291 +                (_sl[src[7]         & 0xf] | _sh[src[5]        & 0xf]) |
   1.292 +                ((_sl[(src[7] >> 4) & 0xf] | _sh[(src[5] >> 4) & 0xf]) << 8) |
   1.293 +                ((_sl[src[6]        & 0xf] | _sh[src[4]        & 0xf]) << 16) |
   1.294 +                ((_sl[(src[6] >> 4) & 0xf] | _sh[(src[4] >> 4) & 0xf]) << 24);
   1.295 +        return result;
   1.296 +    }
   1.297 +
   1.298 +    function subblock(n, flip) {
   1.299 +        var mask = flip ? 0x2 : 0x8;
   1.300 +        return (n & mask) ? 1 : 0;
   1.301 +    }
   1.302 +
   1.303 +    var m = mode(src);
   1.304 +    basecols = base_colors(src, m);
   1.305 +
   1.306 +    var alpha = 255;
   1.307 +    var flipbit = flip(src);
   1.308 +    var table_indices = interleave_table_indices(src);
   1.309 +
   1.310 +    var n = 0;
   1.311 +    for (xx = 0; xx < 4; ++xx) {
   1.312 +        for (yy = 0; yy < 4; ++yy) {
   1.313 +            var dstOff = ((destY + yy) * destWidth + destX + xx) * 4;
   1.314 +
   1.315 +            var sb = subblock(n, flipbit);
   1.316 +            var mod = subblock_modtable(src, sb);
   1.317 +            var offset = mod[(table_indices & 0x3)];
   1.318 +            var col = offset_color(basecols[sb], offset);
   1.319 +
   1.320 +            destBuffer[dstOff]     = col[0];
   1.321 +            destBuffer[dstOff + 1] = col[1];
   1.322 +            destBuffer[dstOff + 2] = col[2];
   1.323 +            destBuffer[dstOff + 3] = alpha;
   1.324 +            table_indices >>= 2;
   1.325 +            n++;
   1.326 +        }
   1.327 +    }
   1.328 +}
   1.329 +
   1.330 +function uncompressETC1(width, height, data, format) {
   1.331 +    if (width % 4 || height % 4) throw "bad width or height";
   1.332 +
   1.333 +    var dest = new Uint8Array(width * height * 4);
   1.334 +    var blocksAcross = width / 4;
   1.335 +    var blocksDown = height / 4;
   1.336 +    var blockSize = 8;
   1.337 +    for (var yy = 0; yy < blocksDown; ++yy) {
   1.338 +        for (var xx = 0; xx < blocksAcross; ++xx) {
   1.339 +            var srcOffset = (yy * blocksAcross + xx) * blockSize;
   1.340 +            var srcblk = data.subarray(srcOffset, srcOffset + blockSize);
   1.341 +            uncompressETC1Block(dest, xx * 4, yy * 4, width, srcblk);
   1.342 +        }
   1.343 +    }
   1.344 +    return dest;
   1.345 +}
   1.346 +
   1.347 +function testETCTexture(test) {
   1.348 +    var data = new Uint8Array(test.data);
   1.349 +    var width = test.width;
   1.350 +    var height = test.height;
   1.351 +    var format = test.format;
   1.352 +
   1.353 +    var uncompressedData = uncompressETC1(width, height, data, format);
   1.354 +
   1.355 +    canvas.width = width;
   1.356 +    canvas.height = height;
   1.357 +    gl.viewport(0, 0, width, height);
   1.358 +    debug("testing " + formatToString(format) + " " + width + "x" + height);
   1.359 +
   1.360 +    var tex = gl.createTexture();
   1.361 +    gl.bindTexture(gl.TEXTURE_2D, tex);
   1.362 +    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
   1.363 +    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
   1.364 +    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
   1.365 +    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
   1.366 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
   1.367 +    glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
   1.368 +    gl.generateMipmap(gl.TEXTURE_2D);
   1.369 +    glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
   1.370 +    wtu.clearAndDrawUnitQuad(gl);
   1.371 +    compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
   1.372 +
   1.373 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
   1.374 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
   1.375 +
   1.376 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
   1.377 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
   1.378 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
   1.379 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
   1.380 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
   1.381 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
   1.382 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
   1.383 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
   1.384 +
   1.385 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
   1.386 +    glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
   1.387 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
   1.388 +    glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
   1.389 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
   1.390 +    glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
   1.391 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
   1.392 +    glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
   1.393 +
   1.394 +    if (width == 4) {
   1.395 +      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
   1.396 +      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
   1.397 +      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
   1.398 +      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
   1.399 +    }
   1.400 +    if (height == 4) {
   1.401 +      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
   1.402 +      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
   1.403 +      gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
   1.404 +      glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
   1.405 +    }
   1.406 +
   1.407 +    // Reupload the complete texture before SubImage tests.
   1.408 +    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
   1.409 +    glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
   1.410 +
   1.411 +    /* OES_compressed_ETC1_RGB8_texture:
   1.412 +     *   INVALID_OPERATION is generated by CompressedTexSubImage2D,
   1.413 +     *   TexSubImage2D, or CopyTexSubImage2D if the texture image
   1.414 +     *   <level> bound to <target> has internal format ETC1_RGB8_OES.
   1.415 +     */
   1.416 +    gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data);
   1.417 +    glErrorShouldBe(gl, gl.INVALID_OPERATION, "ETC1 should not support compressedTexSubImage2D.");
   1.418 +}
   1.419 +
   1.420 +function insertImg(element, caption, img) {
   1.421 +    var div = document.createElement("div");
   1.422 +    div.appendChild(img);
   1.423 +    var label = document.createElement("div");
   1.424 +    label.appendChild(document.createTextNode(caption));
   1.425 +    div.appendChild(label);
   1.426 +    element.appendChild(div);
   1.427 +}
   1.428 +
   1.429 +function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
   1.430 +    var scale = 8;
   1.431 +    var c = document.createElement("canvas");
   1.432 +    c.width = imageWidth * scale;
   1.433 +    c.height = imageHeight * scale;
   1.434 +    var ctx = c.getContext("2d");
   1.435 +    for (var yy = 0; yy < imageHeight; ++yy) {
   1.436 +        for (var xx = 0; xx < imageWidth; ++xx) {
   1.437 +            var offset = (yy * dataWidth + xx) * 4;
   1.438 +            ctx.fillStyle = "rgba(" +
   1.439 +                    data[offset + 0] + "," +
   1.440 +                    data[offset + 1] + "," +
   1.441 +                    data[offset + 2] + "," +
   1.442 +                    (alpha ? data[offset + 3] / 255 : 1) + ")";
   1.443 +            ctx.fillRect(xx * scale, yy * scale, scale, scale);
   1.444 +        }
   1.445 +    }
   1.446 +    var img = document.createElement("img");
   1.447 +    img.src = c.toDataURL();
   1.448 +    return img;
   1.449 +}
   1.450 +
   1.451 +function compareRect(actualWidth, actualHeight, actualChannels,
   1.452 +                     dataWidth, dataHeight, expectedData,
   1.453 +                     testData, testFormat)
   1.454 +{
   1.455 +    var actual = new Uint8Array(actualWidth * actualHeight * 4);
   1.456 +    gl.readPixels(0, 0, actualWidth, actualHeight,
   1.457 +                  gl.RGBA, gl.UNSIGNED_BYTE, actual);
   1.458 +
   1.459 +    var div = document.createElement("div");
   1.460 +    div.className = "testimages";
   1.461 +    insertImg(div, "expected", makeImage(
   1.462 +            actualWidth, actualHeight, dataWidth, expectedData,
   1.463 +            actualChannels == 4));
   1.464 +    insertImg(div, "actual", makeImage(
   1.465 +            actualWidth, actualHeight, actualWidth, actual,
   1.466 +            actualChannels == 4));
   1.467 +    div.appendChild(document.createElement('br'));
   1.468 +    document.getElementById("console").appendChild(div);
   1.469 +
   1.470 +    var failed = false;
   1.471 +    for (var yy = 0; yy < actualHeight; ++yy) {
   1.472 +        for (var xx = 0; xx < actualWidth; ++xx) {
   1.473 +            var actualOffset = (yy * actualWidth + xx) * 4;
   1.474 +            var expectedOffset = (yy * dataWidth + xx) * 4;
   1.475 +            var expected = [
   1.476 +                    expectedData[expectedOffset + 0],
   1.477 +                    expectedData[expectedOffset + 1],
   1.478 +                    expectedData[expectedOffset + 2],
   1.479 +                    (actualChannels == 3 ? 255
   1.480 +                                         : expectedData[expectedOffset + 3])
   1.481 +            ];
   1.482 +
   1.483 +            if (actual[actualOffset + 0] != expected[0] ||
   1.484 +                actual[actualOffset + 1] != expected[1] ||
   1.485 +                actual[actualOffset + 2] != expected[2] ||
   1.486 +                actual[actualOffset + 3] != expected[3])
   1.487 +            {
   1.488 +                failed = true;
   1.489 +                var was = actual[actualOffset + 0].toString();
   1.490 +                for (var j = 1; j < 4; ++j) {
   1.491 +                    was += "," + actual[actualOffset + j];
   1.492 +                }
   1.493 +                testFailed('at (' + xx + ', ' + yy +
   1.494 +                           ') expected: ' + expected + ' was ' + was);
   1.495 +            }
   1.496 +        }
   1.497 +    }
   1.498 +    if (!failed) {
   1.499 +        testPassed("texture rendered correctly");
   1.500 +    }
   1.501 +}
   1.502 +
   1.503 +debug("");
   1.504 +var successfullyParsed = true;
   1.505 +</script>
   1.506 +<script>finishTest();</script>
   1.507 +
   1.508 +</body>
   1.509 +</html>

mercurial