1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/canvas/test/webgl-conformance/conformance/extensions/ext-sRGB.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,363 @@ 1.4 +<!DOCTYPE html> 1.5 +<html> 1.6 +<head> 1.7 +<meta charset="utf-8"/> 1.8 +<link rel="stylesheet" href="../../resources/js-test-style.css"/> 1.9 +<script src="../../resources/js-test-pre.js"></script> 1.10 +<script src="../resources/webgl-test.js"></script> 1.11 +<script src="../resources/webgl-test-utils.js"></script> 1.12 +</head> 1.13 +<body> 1.14 +<div id="description"></div> 1.15 +<div id="console"></div> 1.16 +<canvas id="canvas" width="16" height="16" style="width: 50px; height: 50px; border: 1px solid black;"></canvas> 1.17 + 1.18 +<!-- Shaders to test output --> 1.19 +<script id="vertexShader" type="x-shader/x-vertex"> 1.20 +attribute vec4 aPosition; 1.21 +void main() { 1.22 + gl_Position = aPosition; 1.23 +} 1.24 +</script> 1.25 + 1.26 +<script id="fragmentShader" type="x-shader/x-fragment"> 1.27 +precision mediump float; 1.28 +uniform float uColor; 1.29 +void main() { 1.30 + gl_FragColor = vec4(uColor, uColor, uColor, 1); 1.31 +} 1.32 +</script> 1.33 + 1.34 +<script> 1.35 +"use strict"; 1.36 + 1.37 +var wtu = WebGLTestUtils; 1.38 +var canvas; 1.39 +var gl; 1.40 +var ext = null; 1.41 + 1.42 +function getExtension() { 1.43 + ext = gl.getExtension("EXT_sRGB"); 1.44 +} 1.45 + 1.46 +function listsExtension() { 1.47 + var supported = gl.getSupportedExtensions(); 1.48 + return (supported.indexOf("EXT_sRGB") >= 0); 1.49 +} 1.50 + 1.51 +function readLocation(x, y) { 1.52 + var pixel = new Uint8Array(1 * 1 * 4); 1.53 + var px = Math.floor(x * canvas.drawingBufferWidth); 1.54 + var py = Math.floor(y * canvas.drawingBufferHeight); 1.55 + gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); 1.56 + return pixel; 1.57 +} 1.58 + 1.59 +function toVec3String(val) { 1.60 + if (typeof(val) == 'number') { 1.61 + return toVec3String([val, val, val]); 1.62 + } 1.63 + return '[' + val[0] + ', ' + val[1] + ', ' + val[2] + ']'; 1.64 +} 1.65 + 1.66 +var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher 1.67 + 1.68 +function expectResult(target, successMessage, failureMessage) { 1.69 + var anyDiffer = false; 1.70 + var source = readLocation(0.5, 0.5); 1.71 + for (var m = 0; m < 3; m++) { 1.72 + if (Math.abs(source[m] - target) > e) { 1.73 + anyDiffer = true; 1.74 + testFailed(failureMessage + "; should be " + toVec3String(target) + ", was " + toVec3String(source)); 1.75 + break; 1.76 + } 1.77 + } 1.78 + 1.79 + if (!anyDiffer) { 1.80 + testPassed(successMessage); 1.81 + } 1.82 +} 1.83 + 1.84 +function createGreysRGBTexture(gl, color) { 1.85 + var numPixels = gl.drawingBufferWidth * gl.drawingBufferHeight; 1.86 + var size = numPixels * 3; 1.87 + var buf = new Uint8Array(size); 1.88 + for (var ii = 0; ii < numPixels; ++ii) { 1.89 + var off = ii * 3; 1.90 + buf[off + 0] = color; 1.91 + buf[off + 1] = color; 1.92 + buf[off + 2] = color; 1.93 + } 1.94 + 1.95 + var tex = gl.createTexture(); 1.96 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.97 + gl.texImage2D(gl.TEXTURE_2D, 1.98 + 0, 1.99 + ext.SRGB_EXT, 1.100 + gl.drawingBufferWidth, 1.101 + gl.drawingBufferHeight, 1.102 + 0, 1.103 + ext.SRGB_EXT, 1.104 + gl.UNSIGNED_BYTE, 1.105 + buf); 1.106 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 1.107 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 1.108 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 1.109 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 1.110 + return tex; 1.111 +} 1.112 + 1.113 +function testValidFormat(fn, internalFormat, formatName) { 1.114 + fn(internalFormat); 1.115 + glErrorShouldBe(gl, gl.NO_ERROR, "was able to create type " + formatName); 1.116 +} 1.117 + 1.118 +function testInvalidFormat(fn, internalFormat, formatName) { 1.119 + fn(internalFormat); 1.120 + var err = gl.getError(); 1.121 + if (err == gl.NO_ERROR) { 1.122 + testFailed("should NOT be able to create type " + formatName); 1.123 + } else if (err == gl.INVALID_OPERATION) { 1.124 + testFailed("should return gl.INVALID_ENUM for type " + formatName); 1.125 + } else if (err == gl.INVALID_ENUM) { 1.126 + testPassed("not able to create invalid format: " + formatName); 1.127 + } 1.128 +} 1.129 + 1.130 +var textureFormatFixture = { 1.131 + desc: "Checking texture formats", 1.132 + create: function(format) { 1.133 + var tex = gl.createTexture(); 1.134 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.135 + gl.texImage2D(gl.TEXTURE_2D, 1.136 + 0, // level 1.137 + format, // internalFormat 1.138 + gl.drawingBufferWidth, // width 1.139 + gl.drawingBufferHeight, // height 1.140 + 0, // border 1.141 + format, // format 1.142 + gl.UNSIGNED_BYTE, // type 1.143 + null); // data 1.144 + }, 1.145 + tests: [ 1.146 + { 1.147 + desc: "Checking valid formats", 1.148 + fn: testValidFormat, 1.149 + formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ] 1.150 + }, 1.151 + { 1.152 + desc: "Checking invalid formats", 1.153 + fn: testInvalidFormat, 1.154 + formats: [ 'SRGB8_ALPHA8_EXT' ] 1.155 + } 1.156 + ] 1.157 +}; 1.158 + 1.159 +var renderbufferFormatFixture = { 1.160 + desc: "Checking renderbuffer formats", 1.161 + create: function(format) { 1.162 + var rbo = gl.createRenderbuffer(); 1.163 + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); 1.164 + gl.renderbufferStorage(gl.RENDERBUFFER, 1.165 + format, 1.166 + gl.drawingBufferWidth, 1.167 + gl.drawingBufferHeight); 1.168 + }, 1.169 + tests: [ 1.170 + { 1.171 + desc: "Checking valid formats", 1.172 + fn: testValidFormat, 1.173 + formats: [ 'SRGB8_ALPHA8_EXT' ] 1.174 + }, 1.175 + { 1.176 + desc: "Checking invalid formats", 1.177 + fn: testInvalidFormat, 1.178 + formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ] 1.179 + } 1.180 + ] 1.181 +}; 1.182 + 1.183 + 1.184 +description("Test sRGB texture support"); 1.185 + 1.186 +debug(""); 1.187 +debug("Canvas.getContext"); 1.188 + 1.189 +canvas = document.getElementById("canvas"); 1.190 +gl = wtu.create3DContext(canvas); 1.191 +if (!gl) { 1.192 + testFailed("context does not exist"); 1.193 +} else { 1.194 + testPassed("context exists"); 1.195 + 1.196 + debug(""); 1.197 + debug("Checking sRGB texture support"); 1.198 + 1.199 + // Query the extension and store globally so shouldBe can access it 1.200 + ext = gl.getExtension("EXT_sRGB"); 1.201 + 1.202 + if (!ext) { 1.203 + testPassed("No EXT_sRGB support -- this is legal"); 1.204 + 1.205 + runSupportedTest(false); 1.206 + } else { 1.207 + testPassed("Successfully enabled EXT_sRGB extension"); 1.208 + 1.209 + runSupportedTest(true); 1.210 + 1.211 + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 1.212 + 1.213 + runFormatTest(textureFormatFixture); 1.214 + runFormatTest(renderbufferFormatFixture); 1.215 + runTextureReadConversionTest(); 1.216 + runFramebufferTextureConversionTest(); 1.217 + runFramebufferRenderbufferConversionTest(); 1.218 + } 1.219 +} 1.220 + 1.221 +function runSupportedTest(extensionEnabled) { 1.222 + if (listsExtension()) { 1.223 + if (extensionEnabled) { 1.224 + testPassed("EXT_sRGB listed as supported and getExtension succeeded"); 1.225 + } else { 1.226 + testFailed("EXT_sRGB listed as supported but getExtension failed"); 1.227 + } 1.228 + } else { 1.229 + if (extensionEnabled) { 1.230 + testFailed("EXT_sRGB not listed as supported but getExtension succeeded"); 1.231 + } else { 1.232 + testPassed("EXT_sRGB not listed as supported and getExtension failed -- this is legal"); 1.233 + } 1.234 + } 1.235 +} 1.236 + 1.237 +function runFormatTest(fixture) { 1.238 + debug(""); 1.239 + debug(fixture.desc); 1.240 + 1.241 + for (var tt = 0; tt < fixture.tests.length; ++tt) { 1.242 + var test = fixture.tests[tt]; 1.243 + debug(test.desc); 1.244 + 1.245 + for (var ii = 0; ii < test.formats.length; ++ii) { 1.246 + var formatName = test.formats[ii]; 1.247 + test.fn(fixture.create, ext[formatName], "ext." + formatName); 1.248 + } 1.249 + 1.250 + if (tt != fixture.tests.length - 1) 1.251 + debug(""); 1.252 + } 1.253 +} 1.254 + 1.255 +function runTextureReadConversionTest() { 1.256 + debug(""); 1.257 + debug("Test the conversion of colors from sRGB to linear on texture read"); 1.258 + 1.259 + // Draw 1.260 + var conversions = [ 1.261 + [ 0, 0 ], 1.262 + [ 63, 13 ], 1.263 + [ 127, 54 ], 1.264 + [ 191, 133 ], 1.265 + [ 255, 255 ] 1.266 + ]; 1.267 + 1.268 + var program = wtu.setupTexturedQuad(gl); 1.269 + gl.uniform1i(gl.getUniformLocation(program, "tex2d"), 0); 1.270 + 1.271 + for (var ii = 0; ii < conversions.length; ii++) { 1.272 + var tex = createGreysRGBTexture(gl, conversions[ii][0]); 1.273 + wtu.drawQuad(gl); 1.274 + expectResult(conversions[ii][1], 1.275 + "sRGB texture read returned correct data", 1.276 + "sRGB texture read returned incorrect data"); 1.277 + } 1.278 +} 1.279 + 1.280 +function runFramebufferTextureConversionTest() { 1.281 + debug(""); 1.282 + debug("Test the conversion of colors from linear to sRGB on framebuffer (texture) write"); 1.283 + 1.284 + var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]); 1.285 + var tex = createGreysRGBTexture(gl, 0); 1.286 + var fbo = gl.createFramebuffer(); 1.287 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.288 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); 1.289 + glErrorShouldBe(gl, gl.NO_ERROR); 1.290 + 1.291 + shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT'); 1.292 + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); 1.293 + 1.294 + // Draw 1.295 + var conversions = [ 1.296 + [ 0, 0 ], 1.297 + [ 13, 63 ], 1.298 + [ 54, 127 ], 1.299 + [ 133, 191 ], 1.300 + [ 255, 255 ] 1.301 + ]; 1.302 + 1.303 + wtu.setupUnitQuad(gl, 0); 1.304 + 1.305 + for (var ii = 0; ii < conversions.length; ii++) { 1.306 + gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0); 1.307 + wtu.drawQuad(gl, [0, 0, 0, 0]); 1.308 + expectResult(conversions[ii][1], 1.309 + "framebuffer (texture) read returned correct data", 1.310 + "framebuffer (texture) read returned incorrect data"); 1.311 + } 1.312 + 1.313 + gl.bindFramebuffer(gl.FRAMEBUFFER, null); 1.314 +} 1.315 + 1.316 +function runFramebufferRenderbufferConversionTest() { 1.317 + debug(""); 1.318 + debug("Test the conversion of colors from linear to sRGB on framebuffer (renderbuffer) write"); 1.319 + 1.320 + function createsRGBFramebuffer(gl, width, height) { 1.321 + var rbo = gl.createRenderbuffer(); 1.322 + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); 1.323 + gl.renderbufferStorage(gl.RENDERBUFFER, ext.SRGB8_ALPHA8_EXT, width, height); 1.324 + glErrorShouldBe(gl, gl.NO_ERROR); 1.325 + 1.326 + var fbo = gl.createFramebuffer(); 1.327 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.328 + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 1.329 + gl.RENDERBUFFER, rbo); 1.330 + glErrorShouldBe(gl, gl.NO_ERROR); 1.331 + 1.332 + shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT'); 1.333 + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); 1.334 + 1.335 + return fbo; 1.336 + } 1.337 + 1.338 + // Draw 1.339 + var conversions = [ 1.340 + [ 0, 0 ], 1.341 + [ 13, 63 ], 1.342 + [ 54, 127 ], 1.343 + [ 133, 191 ], 1.344 + [ 255, 255 ] 1.345 + ]; 1.346 + 1.347 + var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]); 1.348 + wtu.setupUnitQuad(gl, 0); 1.349 + var fbo = createsRGBFramebuffer(gl, 4, 4); 1.350 + 1.351 + for (var ii = 0; ii < conversions.length; ii++) { 1.352 + gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0); 1.353 + wtu.drawQuad(gl, [0, 0, 0, 0]); 1.354 + expectResult(conversions[ii][1], 1.355 + "framebuffer (renderbuffer) read returned the correct data", 1.356 + "framebuffer (renderbuffer) read returned incorrect data"); 1.357 + } 1.358 +} 1.359 + 1.360 +debug(""); 1.361 +var successfullyParsed = true; 1.362 +</script> 1.363 +<script>finishTest();</script> 1.364 + 1.365 +</body> 1.366 +</html>