Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance / rendering / blending.html
blobb14705cd500de9137d23ec84da59e56fa9c37be2
1 <!--
2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
12 <script src="../../js/js-test-pre.js"></script>
13 <script src="../../js/webgl-test-utils.js"></script>
15 <script id="eVsSrc" type="text/plain">
16 void main()
18 gl_PointSize = 1.0;
19 gl_Position = vec4(0, 0, 0, 1);
21 </script>
23 <script id="eFsSrc" type="text/plain">
24 precision mediump float;
25 uniform vec4 uColor;
27 void main()
29 gl_FragColor = uColor;
31 </script>
33 </head>
34 <body>
35 <div id="description"></div>
36 <div id="console"></div>
37 <script>
38 "use strict";
39 description('Blending tests');
41 const wtu = WebGLTestUtils;
43 function CreateContext() {
44 const gl = wtu.create3DContext();
45 gl.viewport(0, 0, 1, 1);
47 gl.prog = wtu.setupProgram(gl, [eVsSrc.innerHTML, eFsSrc.innerHTML]);
48 gl.prog.uColor = (() => {
49 const loc = gl.getUniformLocation(gl.prog, 'uColor');
50 return x => gl.uniform4fv(loc, x);
51 })();
52 gl.useProgram(gl.prog);
53 gl.prog.uColor([1 / 255, 2 / 255, 3 / 255, 4 / 255]);
55 gl.drawAndRead = type => {
56 gl.drawArrays(gl.POINTS, 0, 1);
57 let ret;
58 if (type == gl.UNSIGNED_BYTE) {
59 ret = new Uint8Array(4);
60 } else if (type == gl.FLOAT) {
61 ret = new Float32Array(4);
63 gl.readPixels(0, 0, 1, 1, gl.RGBA, type, ret);
64 return ret;
67 gl.enable(gl.BLEND);
68 gl.blendFunc(gl.CONSTANT_COLOR, gl.ZERO);
70 return gl;
73 function CreateValidFb(gl, formats) {
74 const fb = gl.createFramebuffer();
75 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
77 for (let i in formats) {
78 i = i|0; // Otherwise i is a string. :(
79 const f = formats[i];
80 if (!f)
81 continue;
82 if (f.length == 1) {
83 const rb = gl.createRenderbuffer();
84 gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
85 gl.renderbufferStorage(gl.RENDERBUFFER, f[0], 1, 1);
86 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i,
87 gl.RENDERBUFFER, rb);
88 continue;
90 if (f.length == 3) {
91 let internalFormat = f[0];
92 if (internalFormat === undefined) {
93 internalFormat = f[1];
96 const tex = gl.createTexture();
97 gl.bindTexture(gl.TEXTURE_2D, tex);
98 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1,1,0, f[1],f[2], null);
99 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i,
100 gl.TEXTURE_2D, tex, 0);
101 continue;
103 throw new Error('Invalid format length: ' + f);
106 const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
107 if (status != gl.FRAMEBUFFER_COMPLETE) {
108 gl.deleteFramebuffer(fb);
109 return null;
111 return fb;
114 let was, fb;
116 const TESTS = [
117 () => {
118 debug('');
119 debug('Clamping of blendColor args:');
121 const gl = wtu.create3DContext();
122 if (!gl.texImage3D) { // WebGL 1.0
123 // WebGL 1.0 clamps without EXT_color_buffer_half_float or WEBGL_color_buffer_float.
124 gl.blendColor(1000, 1, 1, 1);
125 const was = gl.getParameter(gl.BLEND_COLOR);
126 expectArray(was, [1, 1, 1, 1]);
128 const ext = gl.getExtension('EXT_color_buffer_half_float') ||
129 gl.getExtension('WEBGL_color_buffer_float');
130 if (!ext) return;
133 // WebGL 2.0 or extended WebGL 1.0 may still clamp the value on store
134 // when the underlying platform does the same.
135 gl.blendColor(1000, 1, 1, 1);
136 const was = gl.getParameter(gl.BLEND_COLOR);
137 if (was[0] == 1000) {
138 expectArray(was, [1000, 1, 1, 1]);
139 } else {
140 debug("Platform does not support unclamped blend color.")
141 expectArray(was, [1, 1, 1, 1]);
144 () => {
145 debug('');
146 debug('Blending for RGBA8:');
148 const gl = CreateContext();
149 fb = CreateValidFb(gl, [[gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE]]);
150 shouldBeNonNull('fb');
152 // Regardless of the context version and enabled extensions,
153 // the value will be clamped at draw time,
154 gl.blendColor(10, 1, 1, 1);
155 const was = gl.drawAndRead(gl.UNSIGNED_BYTE);
156 expectArray(was, [1, 2, 3, 4]);
158 if (gl.getExtension('EXT_color_buffer_half_float') ||
159 gl.getExtension('WEBGL_color_buffer_float') ||
160 gl.getExtension('EXT_color_buffer_float'))
162 debug('Enable floating-point color buffers and retest');
163 gl.blendColor(1000, 1, 1, 1);
164 const was = gl.drawAndRead(gl.UNSIGNED_BYTE);
165 expectArray(was, [1, 2, 3, 4]);
168 () => {
169 debug('');
170 debug('Blending for RGBA16F:');
172 const gl = CreateContext();
174 // Set the value before enabling the extension.
175 // It must be clamped only on WebGL 1.0 contexts.
176 gl.blendColor(10, 1, 1, 1);
177 if (!gl.getExtension('EXT_color_buffer_half_float')) {
178 testPassed('Missing ext EXT_color_buffer_half_float is optional, skipping.');
179 return;
181 if (!gl.texImage3D) { // WebGL 1.0
182 const ext = gl.getExtension('OES_texture_half_float');
183 gl.HALF_FLOAT = ext.HALF_FLOAT_OES; // These aren't the same value, but this'll work.
186 fb = CreateValidFb(gl, [[gl.RGBA16F, gl.RGBA, gl.HALF_FLOAT]]);
187 shouldBeNonNull('fb');
188 gl.prog.uColor([1, 2, 3, 4]);
190 let was = gl.drawAndRead(gl.FLOAT);
191 if (!gl.texImage3D) { // WebGL 1.0
192 expectArray(was, [1, 2, 3, 4]);
193 } else {
194 // Some WebGL 2.0 implementations may clamp the blend color anyway.
195 const r = gl.getParameter(gl.BLEND_COLOR)[0];
196 expectArray(was, [r, 2, 3, 4]);
199 // Re-set the value after the extension was enabled.
200 gl.blendColor(100, 1, 1, 1);
201 const r = gl.getParameter(gl.BLEND_COLOR)[0];
202 was = gl.drawAndRead(gl.FLOAT);
203 expectArray(was, [r, 2, 3, 4]);
205 () => {
206 debug('');
207 debug('Blending for RGBA32F:');
209 const gl = CreateContext();
211 // Set the value before enabling the extension.
212 // It must be clamped only on WebGL 1.0 contexts.
213 gl.blendColor(10, 1, 1, 1);
214 if (gl.texImage3D) { // WebGL 2.0
215 if (!gl.getExtension('EXT_color_buffer_float')) {
216 testPassed('Missing ext EXT_color_buffer_float is optional, skipping.');
217 return;
219 } else {
220 if (!gl.getExtension('WEBGL_color_buffer_float')) {
221 testPassed('Missing ext WEBGL_color_buffer_float is optional, skipping.');
222 return;
224 gl.getExtension('OES_texture_float');
226 fb = CreateValidFb(gl, [[gl.RGBA32F, gl.RGBA, gl.FLOAT]]);
227 shouldBeNonNull('fb');
228 gl.prog.uColor([1, 2, 3, 4]);
230 let was = gl.drawAndRead(gl.FLOAT);
231 if (!gl.texImage3D) { // WebGL 1.0
232 expectArray(was, [1, 2, 3, 4]);
233 } else {
234 // Some WebGL 2.0 implementations may clamp the blend color anyway.
235 const r = gl.getParameter(gl.BLEND_COLOR)[0];
236 expectArray(was, [r, 2, 3, 4]);
239 // Re-set the value after the extension was enabled.
240 gl.blendColor(100, 1, 1, 1);
241 const r = gl.getParameter(gl.BLEND_COLOR)[0];
242 was = gl.drawAndRead(gl.FLOAT);
244 if (!gl.getExtension('EXT_float_blend')) {
245 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'Should not be able to blend 32F formats.');
246 return;
248 wtu.glErrorShouldBe(gl, 0, 'Should be able to blend 32F formats.');
249 expectArray(was, [r, 2, 3, 4]);
253 async function Test() {
254 for (const fn of TESTS) {
255 await wtu.dispatchPromise(fn);
257 wtu.destroyAllContexts();
258 finishTest();
261 Test();
263 var successfullyParsed = true;
264 </script>
265 </body>
266 </html>