4 <meta charset=
"utf-8"/>
5 <link rel=
"stylesheet" href=
"../../resources/js-test-style.css"/>
6 <script src=
"../../js/js-test-pre.js"></script>
7 <script src=
"../../js/webgl-test-utils.js"></script>
10 <div id=
"description"></div>
11 <div id=
"console"></div>
12 <canvas id=
"canvas" width=
"16" height=
"16" style=
"width: 50px; height: 50px; border: 1px solid black;"></canvas>
14 <!-- Shaders to test output -->
15 <script id=
"vertexShader" type=
"x-shader/x-vertex">
16 attribute vec4 aPosition;
18 gl_Position = aPosition;
22 <script id=
"fragmentShader" type=
"x-shader/x-fragment">
23 precision mediump float;
26 gl_FragColor = vec4(uColor, uColor, uColor,
1);
30 <script id=
"vshader" type=
"x-shader/x-vertex">
31 attribute vec4 vPosition;
32 attribute vec2 texCoord0;
33 varying vec2 texCoord;
36 gl_Position = vPosition;
41 <script id=
"fshader" type=
"x-shader/x-fragment">
42 precision mediump float;
43 uniform sampler2D tex;
44 varying vec2 texCoord;
47 gl_FragColor = texture2D(tex, texCoord);
54 var wtu
= WebGLTestUtils
;
61 "SRGB_ALPHA_EXT": 0x8C42,
62 "SRGB8_ALPHA8_EXT": 0x8C43,
63 "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT": 0x8210
66 function getExtension() {
67 ext
= gl
.getExtension("EXT_sRGB");
70 function listsExtension() {
71 var supported
= gl
.getSupportedExtensions();
72 return (supported
.indexOf("EXT_sRGB") >= 0);
75 function toVec3String(val
) {
76 if (typeof(val
) == 'number') {
77 return toVec3String([val
, val
, val
]);
79 return '[' + val
[0] + ', ' + val
[1] + ', ' + val
[2] + ']';
82 var e
= 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
84 function expectResult(target
) {
85 wtu
.checkCanvasRect(gl
,
86 Math
.floor(gl
.drawingBufferWidth
/ 2),
87 Math
.floor(gl
.drawingBufferHeight
/ 2),
90 [target
, target
, target
, 255],
95 function createGreysRGBTexture(gl
, color
, format
) {
96 var numPixels
= gl
.drawingBufferWidth
* gl
.drawingBufferHeight
;
99 case ext
.SRGB_EXT
: elements
= 3; break;
100 case ext
.SRGB_ALPHA_EXT
: elements
= 4; break;
101 default: return null;
104 var size
= numPixels
* elements
;
105 var buf
= new Uint8Array(size
);
106 for (var ii
= 0; ii
< numPixels
; ++ii
) {
107 var off
= ii
* elements
;
108 buf
[off
+ 0] = color
;
109 buf
[off
+ 1] = color
;
110 buf
[off
+ 2] = color
;
111 if (format
== ext
.SRGB_ALPHA_EXT
) {
116 var tex
= gl
.createTexture();
117 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
118 gl
.texImage2D(gl
.TEXTURE_2D
,
121 gl
.drawingBufferWidth
,
122 gl
.drawingBufferHeight
,
127 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAG_FILTER
, gl
.LINEAR
);
128 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.NEAREST
);
129 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_WRAP_S
, gl
.CLAMP_TO_EDGE
);
130 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_WRAP_T
, gl
.CLAMP_TO_EDGE
);
134 function testValidFormat(fn
, internalFormat
, formatName
, enabled
) {
137 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "was able to create type " + formatName
);
139 testInvalidFormat(fn
, internalFormat
, formatName
, enabled
);
143 function testInvalidFormat(fn
, internalFormat
, formatName
, enabled
) {
145 var err
= gl
.getError();
146 if (err
== gl
.NO_ERROR
) {
147 testFailed("should NOT be able to create type " + formatName
);
148 } else if (err
== gl
.INVALID_ENUM
|| err
== gl
.INVALID_VALUE
) {
149 testPassed("not able to create invalid format: " + formatName
);
153 var textureFormatFixture
= {
154 desc
: "Checking texture formats",
155 create: function(format
) {
156 var tex
= gl
.createTexture();
157 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
158 gl
.texImage2D(gl
.TEXTURE_2D
,
160 format
, // internalFormat
161 gl
.drawingBufferWidth
, // width
162 gl
.drawingBufferHeight
, // height
165 gl
.UNSIGNED_BYTE
, // type
170 desc
: "Checking valid formats",
172 formats
: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
175 desc
: "Checking invalid formats",
176 fn
: testInvalidFormat
,
177 formats
: [ 'SRGB8_ALPHA8_EXT' ]
182 var renderbufferFormatFixture
= {
183 desc
: "Checking renderbuffer formats",
184 create: function(format
) {
185 var rbo
= gl
.createRenderbuffer();
186 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
187 gl
.renderbufferStorage(gl
.RENDERBUFFER
,
189 gl
.drawingBufferWidth
,
190 gl
.drawingBufferHeight
);
194 desc
: "Checking valid formats",
196 formats
: [ 'SRGB8_ALPHA8_EXT' ]
199 desc
: "Checking invalid formats",
200 fn
: testInvalidFormat
,
201 formats
: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
207 description("Test sRGB texture support");
210 debug("Canvas.getContext");
212 canvas
= document
.getElementById("canvas");
213 gl
= wtu
.create3DContext(canvas
);
215 testFailed("context does not exist");
217 testPassed("context exists");
220 debug("Checking sRGB texture support with extension disabled");
222 runFormatTest(textureFormatFixture
, false);
223 runFormatTest(renderbufferFormatFixture
, false);
226 var fbo
= gl
.createFramebuffer();
227 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
229 debug("Checking getFramebufferAttachmentParameter with a renderbuffer");
231 var rbo
= gl
.createRenderbuffer();
232 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
233 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.RGB565
, 1, 1);
234 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rbo
);
235 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
236 shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8210 /* FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT */)');
237 wtu
.glErrorShouldBe(gl
, gl
.INVALID_ENUM
);
238 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, null);
239 gl
.deleteRenderbuffer(rbo
);
242 debug("Checking getFramebufferAttachmentParameter with a texture");
244 var tex
= gl
.createTexture();
245 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
246 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA
, 1, 1, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
247 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex
, 0);
248 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
249 shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8210 /* FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT */)');
250 wtu
.glErrorShouldBe(gl
, gl
.INVALID_ENUM
);
251 gl
.bindTexture(gl
.TEXTURE_2D
, null);
252 gl
.deleteTexture(tex
);
255 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
256 gl
.deleteFramebuffer(fbo
);
260 debug("Checking sRGB texture support");
262 // Query the extension and store globally so shouldBe can access it
263 ext
= gl
.getExtension("EXT_sRGB");
266 testPassed("No EXT_sRGB support -- this is legal");
268 runSupportedTest(false);
271 testPassed("Successfully enabled EXT_sRGB extension");
273 runSupportedTest(true);
275 gl
.viewport(0, 0, gl
.drawingBufferWidth
, gl
.drawingBufferHeight
);
278 runFormatTest(textureFormatFixture
, true);
279 runFormatTest(renderbufferFormatFixture
, true);
280 runTextureReadConversionTest();
281 runFramebufferTextureConversionTest(ext
.SRGB_EXT
);
282 runFramebufferTextureConversionTest(ext
.SRGB_ALPHA_EXT
);
283 runFramebufferRenderbufferConversionTest();
284 runGenerateMipmapTest();
285 runLoadFromImageTest(function() {
291 function runConstantsTest() {
293 debug("Checking extension constants values");
295 for (var constant
in extConstants
) {
296 if (constant
in ext
) {
297 if (extConstants
[constant
] != ext
[constant
]) {
298 testFailed("Value of " + constant
+ " should be: " + extConstants
[constant
] + ", was: " + ext
[constant
]);
300 testPassed("Value of " + constant
+ " was expected value: " + extConstants
[constant
]);
303 testFailed(constant
+ " not found in extension object");
308 function runSupportedTest(extensionEnabled
) {
309 if (listsExtension()) {
310 if (extensionEnabled
) {
311 testPassed("EXT_sRGB listed as supported and getExtension succeeded");
313 testFailed("EXT_sRGB listed as supported but getExtension failed");
316 if (extensionEnabled
) {
317 testFailed("EXT_sRGB not listed as supported but getExtension succeeded");
319 testPassed("EXT_sRGB not listed as supported and getExtension failed -- this is legal");
324 function runFormatTest(fixture
, enabled
) {
328 for (var tt
= 0; tt
< fixture
.tests
.length
; ++tt
) {
329 var test
= fixture
.tests
[tt
];
332 for (var ii
= 0; ii
< test
.formats
.length
; ++ii
) {
333 var formatName
= test
.formats
[ii
];
334 test
.fn(fixture
.create
, extConstants
[formatName
], "ext." + formatName
, enabled
);
337 if (tt
!= fixture
.tests
.length
- 1)
342 function runTextureReadConversionTest() {
344 debug("Test the conversion of colors from sRGB to linear on texture read");
355 var program
= wtu
.setupTexturedQuad(gl
);
356 gl
.uniform1i(gl
.getUniformLocation(program
, "tex"), 0);
358 for (var ii
= 0; ii
< conversions
.length
; ii
++) {
359 var tex
= createGreysRGBTexture(gl
, conversions
[ii
][0], ext
.SRGB_EXT
);
360 wtu
.drawUnitQuad(gl
);
361 expectResult(conversions
[ii
][1]);
365 function runFramebufferTextureConversionTest(format
) {
369 case ext
.SRGB_EXT
: formatString
= "sRGB"; validFormat
= false; break;
370 case ext
.SRGB_ALPHA_EXT
: formatString
= "sRGB_ALPHA"; validFormat
= true; break;
371 default: return null;
374 debug("Test " + formatString
+ " framebuffer attachments." + (validFormat
? "" : " (Invalid)"));
376 var program
= wtu
.setupProgram(gl
, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
377 var tex
= createGreysRGBTexture(gl
, 0, format
);
378 var fbo
= gl
.createFramebuffer();
379 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
380 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex
, 0);
381 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
383 shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
386 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
389 debug("Test the conversion of colors from linear to " + formatString
+ " on framebuffer (texture) write");
400 wtu
.setupUnitQuad(gl
, 0);
402 for (var ii
= 0; ii
< conversions
.length
; ii
++) {
403 gl
.uniform1f(gl
.getUniformLocation(program
, "uColor"), conversions
[ii
][0]/255.0);
404 wtu
.drawUnitQuad(gl
, [0, 0, 0, 0]);
405 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
406 expectResult(conversions
[ii
][1]);
409 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
411 wtu
.setupUnitQuad(gl
, 0);
412 gl
.uniform1f(gl
.getUniformLocation(program
, "uColor"), 0.5);
413 wtu
.drawUnitQuad(gl
, [0, 0, 0, 0]);
414 wtu
.glErrorShouldBe(gl
, gl
.INVALID_FRAMEBUFFER_OPERATION
);
417 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
420 function runFramebufferRenderbufferConversionTest() {
422 debug("Test the conversion of colors from linear to sRGB on framebuffer (renderbuffer) write");
424 function createsRGBFramebuffer(gl
, width
, height
) {
425 var rbo
= gl
.createRenderbuffer();
426 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rbo
);
427 gl
.renderbufferStorage(gl
.RENDERBUFFER
, ext
.SRGB8_ALPHA8_EXT
, width
, height
);
428 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
430 var fbo
= gl
.createFramebuffer();
431 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
432 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
,
433 gl
.RENDERBUFFER
, rbo
);
434 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
436 shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
437 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
451 var program
= wtu
.setupProgram(gl
, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
452 wtu
.setupUnitQuad(gl
, 0);
453 var fbo
= createsRGBFramebuffer(gl
, gl
.drawingBufferWidth
, gl
.drawingBufferHeight
);
455 for (var ii
= 0; ii
< conversions
.length
; ii
++) {
456 gl
.uniform1f(gl
.getUniformLocation(program
, "uColor"), conversions
[ii
][0]/255.0);
457 wtu
.drawUnitQuad(gl
, [0, 0, 0, 0]);
458 expectResult(conversions
[ii
][1]);
462 function runLoadFromImageTest(callback
) {
464 debug("Tests to ensure that SRGB textures can successfully use image elements as their source");
466 var img
= wtu
.makeImage("../../resources/gray-1024x1024.jpg", function() {
467 var tex
= gl
.createTexture();
468 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
469 gl
.texImage2D(gl
.TEXTURE_2D
, 0, ext
.SRGB_EXT
, ext
.SRGB_EXT
, gl
.UNSIGNED_BYTE
, img
);
470 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
472 gl
.texImage2D(gl
.TEXTURE_2D
, 0, ext
.SRGB_ALPHA_EXT
, ext
.SRGB_ALPHA_EXT
, gl
.UNSIGNED_BYTE
, img
);
473 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
477 testFailed("Image could not be loaded");
482 function runGenerateMipmapTest()
485 debug("GenerateMipmaps for sRGB textures is forbidden");
487 var tex
= gl
.createTexture();
488 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
490 gl
.texImage2D(gl
.TEXTURE_2D
, 0, ext
.SRGB_ALPHA_EXT
, 2, 2, 0, ext
.SRGB_ALPHA_EXT
,
491 gl
.UNSIGNED_BYTE
, null);
492 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
493 gl
.generateMipmap(gl
.TEXTURE_2D
);
494 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
);
496 gl
.deleteTexture(tex
);
499 var successfullyParsed
= true;