diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-pvrtc.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-pvrtc.html | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-pvrtc.html b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-pvrtc.html new file mode 100644 index 000000000..8c05b1f5c --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-pvrtc.html @@ -0,0 +1,392 @@ +<!-- + +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<title>WebGL WEBGL_compressed_texture_pvrtc Conformance Tests</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" style="width: 8px; height: 8px;"></canvas> +<div id="console"></div> +<script> +"use strict"; +description("This test verifies the functionality of the WEBGL_compressed_texture_pvrtc extension, if it is available."); + +debug(""); + +var pvrtc_4x4_2bpp = new Uint8Array([ + 0x77, 0x22, 0x77, 0x22, 0xbb, 0x2b, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +]); + +var pvrtc_4x4_4bpp = new Uint8Array([ + 0x1b, 0x1b, 0x1b, 0x1b, 0xba, 0x2b, 0x00, 0x80, 0x1b, 0x1b, 0x1b, 0x1b, 0xba, 0x2b, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +]); + +var pvrtc_4x4_rgba_decoded = new Uint8Array([ + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x46, 0xb8, 0x76, 0x76, 0x71, 0x8a, 0xbd, 0xbd, 0xba, 0x44, + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x43, 0xb8, 0x76, 0x76, 0x71, 0x8a, 0xbd, 0xbd, 0xb5, 0x44, + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x43, 0xb8, 0x76, 0x76, 0x71, 0x8a, 0xbd, 0xbd, 0xb5, 0x44, + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x46, 0xb8, 0x76, 0x76, 0x71, 0x8a, 0xbd, 0xbd, 0xb7, 0x44, +]); + +var pvrtc_4x4_rgb_decoded = new Uint8Array([ + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x46, 0xff, 0x76, 0x76, 0x71, 0xff, 0xbd, 0xbd, 0xba, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x43, 0xff, 0x76, 0x76, 0x71, 0xff, 0xbd, 0xbd, 0xb5, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x43, 0xff, 0x76, 0x76, 0x71, 0xff, 0xbd, 0xbd, 0xb5, 0xff, + 0x00, 0x00, 0x00, 0xff, 0x46, 0x46, 0x46, 0xff, 0x76, 0x76, 0x71, 0xff, 0xbd, 0xbd, 0xb7, 0xff, +]); + +var wtu = WebGLTestUtils; +var contextVersion = wtu.getDefault3DContextVersion(); +var canvas = document.getElementById("canvas"); +var gl = wtu.create3DContext(canvas, {antialias: false}); +var program = wtu.setupTexturedQuad(gl); +var ext = null; +var vao = null; +var validFormats = { + COMPRESSED_RGB_PVRTC_4BPPV1_IMG : 0x8C00, + COMPRESSED_RGB_PVRTC_2BPPV1_IMG : 0x8C01, + COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : 0x8C02, + COMPRESSED_RGBA_PVRTC_2BPPV1_IMG : 0x8C03, +}; +var name; +var supportedFormats; + +if (!gl) { + testFailed("WebGL context does not exist"); +} else { + testPassed("WebGL context exists"); + + // Run tests with extension disabled + runTestDisabled(); + + // Query the extension and store globally so shouldBe can access it + ext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_compressed_texture_pvrtc"); + if (!ext) { + testPassed("No WEBGL_compressed_texture_pvrtc support -- this is legal"); + runSupportedTest(false); + } else { + testPassed("Successfully enabled WEBGL_compressed_texture_pvrtc extension"); + + runSupportedTest(true); + runTestExtension(); + } +} + +function runSupportedTest(extensionEnabled) { + var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_compressed_texture_pvrtc"); + if (name !== undefined) { + if (extensionEnabled) { + testPassed("WEBGL_compressed_texture_pvrtc listed as supported and getExtension succeeded"); + } else { + testFailed("WEBGL_compressed_texture_pvrtc listed as supported but getExtension failed"); + } + } else { + if (extensionEnabled) { + testFailed("WEBGL_compressed_texture_pvrtc not listed as supported but getExtension succeeded"); + } else { + testPassed("WEBGL_compressed_texture_pvrtc not listed as supported and getExtension failed -- this is legal"); + } + } +} + + +function runTestDisabled() { + debug("Testing binding enum with extension disabled"); + + supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS); + shouldBe("supportedFormats", "[]"); +} + +function formatExists(format, supportedFormats) { + for (var ii = 0; ii < supportedFormats.length; ++ii) { + if (format == supportedFormats[ii]) { + testPassed("supported format " + formatToString(format) + " is exists"); + return; + } + } + testFailed("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() { + debug("Testing WEBGL_compressed_texture_pvrtc"); + + // check that all format enums exist. + for (name in validFormats) { + var expected = "0x" + validFormats[name].toString(16); + var actual = "ext['" + name + "']"; + shouldBe(actual, expected); + } + + supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS); + // There should be exactly 4 formats for both WebGL 1.0 and WebGL 2.0. + shouldBe("supportedFormats.length", "4"); + + // check that all 4 formats exist + for (var name in validFormats.length) { + formatExists(validFormats[name], supportedFormats); + } + + // Test each format + testPVRTC_RGBA_2BPP(); + testPVRTC_RGB_2BPP(); + testPVRTC_RGBA_4BPP(); + testPVRTC_RGB_4BPP(); +} + +function testPVRTC_RGBA_2BPP() { + var tests = [ + { width: 4, + height: 4, + channels: 4, + data: pvrtc_4x4_2bpp, + raw: pvrtc_4x4_rgba_decoded, + format: ext.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG + } + ]; + testPVRTCTextures(tests); +} + +function testPVRTC_RGB_2BPP() { + var tests = [ + { width: 4, + height: 4, + channels: 4, + data: pvrtc_4x4_2bpp, + raw: pvrtc_4x4_rgb_decoded, + format: ext.COMPRESSED_RGB_PVRTC_2BPPV1_IMG + } + ]; + testPVRTCTextures(tests); +} + +function testPVRTC_RGBA_4BPP() { + var tests = [ + { width: 4, + height: 4, + channels: 4, + data: pvrtc_4x4_4bpp, + raw: pvrtc_4x4_rgba_decoded, + format: ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG + } + ]; + testPVRTCTextures(tests); +} + +function testPVRTC_RGB_4BPP() { + var tests = [ + { width: 4, + height: 4, + channels: 4, + data: pvrtc_4x4_4bpp, + raw: pvrtc_4x4_rgb_decoded, + format: ext.COMPRESSED_RGB_PVRTC_4BPPV1_IMG + } + ]; + testPVRTCTextures(tests); +} + +function testPVRTCTextures(tests) { + debug("<hr/>"); + for (var ii = 0; ii < tests.length; ++ii) { + testPVRTCTexture(tests[ii]); + } +} + +function testPVRTCTexture(test) { + var data = new Uint8Array(test.data); + var width = test.width; + var height = test.height; + var format = test.format; + var uncompressedData = test.raw; + + canvas.width = width; + canvas.height = height; + gl.viewport(0, 0, width, height); + debug("testing " + formatToString(format) + " " + width + "x" + 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); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture"); + gl.generateMipmap(gl.TEXTURE_2D); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture"); + wtu.drawQuad(gl); + compareRect(width, height, test.channels, width, height, uncompressedData, data, format, undefined, "NEAREST"); + // Test again with linear filtering. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + wtu.clearAndDrawUnitQuad(gl); + compareRect(width, height, test.channels, width, height, uncompressedData, data, format, undefined, "LINEAR"); + + gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data); + wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border"); + + gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions"); + gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions"); + gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions"); + gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions"); + + gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "compressedTexSubImage2D allowed for reloading of complete textures"); + + gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexSubImage2D not allowed for partial texture updates"); + gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexSubImage2D not allowed for partial texture updates"); + gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 2, 0, width - 2, height, format, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexSubImage2D not allowed for partial texture updates"); + gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 2, width, height - 2, format, data); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexSubImage2D not allowed for partial texture updates"); +} + +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 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); + } + } + return wtu.makeImageFromCanvas(c); +} +function compareRect( + actualWidth, actualHeight, actualChannels, + dataWidth, dataHeight, expectedData, + testData, testFormat, tolerance, filteringMode) { + if(typeof(tolerance) == 'undefined') { tolerance = 5; } + 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"; + insertImg(div, "expected", makeImage( + actualWidth, actualHeight, dataWidth, expectedData, + actualChannels == 4)); + insertImg(div, "actual", makeImage( + actualWidth, actualHeight, actualWidth, actual, + actualChannels == 4)); + 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[expectedOffset + 0], + expectedData[expectedOffset + 1], + expectedData[expectedOffset + 2], + (actualChannels == 3 ? 255 : expectedData[expectedOffset + 3]) + ]; + for (var jj = 0; jj < 4; ++jj) { + if (Math.abs(actual[actualOffset + jj] - expected[jj]) > tolerance) { + failed = true; + var was = actual[actualOffset + 0].toString(); + for (var j = 1; j < 4; ++j) { + was += "," + actual[actualOffset + j]; + } + testFailed('at (' + xx + ', ' + yy + + ') expected: ' + expected + ' was ' + was); + } + } + } + } + if (!failed) { + testPassed("texture rendered correctly with " + filteringMode + " filtering"); + } +} + +debug(""); +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> |