Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / extensions / webgl-shader-pixel-local-storage.html
blobe548eea46ca2d2c6931e5447b434e09a631d4b99
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>WebGL WEBGL_shader_pixel_local_storage Conformance Tests</title>
6 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
7 <script src="../../js/desktop-gl-constants.js"></script>
8 <script src="../../js/js-test-pre.js"></script>
9 <script src="../../js/webgl-test-utils.js"></script>
10 <script src="../../js/tests/compositing-test.js"></script>
11 <script src="../../js/tests/invalid-vertex-attrib-test.js"></script>
12 </head>
13 <body>
14 <div id="description"></div>
15 <canvas id="canvas" width="128" height="128" style="background-color:#080"> </canvas>
16 <canvas id="canvas_no_alpha" width="128" height="128"> </canvas>
17 <div id="console"></div>
18 <script>
19 "use strict";
20 description("This test verifies the functionality of the WEBGL_shader_pixel_local_storage " +
21 "extension, if it is available.");
23 const wtu = WebGLTestUtils;
24 const canvas = document.getElementById("canvas");
25 const gl = wtu.create3DContext(canvas, {alpha: true}, 2);
26 const gl_no_alpha = wtu.create3DContext("canvas_no_alpha", {alpha: false}, 2);
27 let pls = null;
29 // Outputs a fullscreen quad from a 4-vertex triangle strip.
30 const fullscreenQuadVertexShader = `#version 300 es
31 void main() {
32 gl_Position.x = (gl_VertexID & 1) == 0 ? -1. : 1.;
33 gl_Position.y = (gl_VertexID & 2) == 0 ? -1. : 1.;
34 gl_Position.zw = vec2(0, 1);
35 }`;
37 function arraysEqual(a, b) {
38 if (typeof a !== typeof b)
39 return false;
40 if (a.length != b.length)
41 return false;
42 for (let i = 0; i < a.length; ++i) {
43 if (a[i] !== b[i])
44 return false;
46 return true;
49 async function runTest() {
50 if (!gl) {
51 testFailed("WebGL2 context does not exist");
52 finishTest();
53 return;
56 debug("\nCheck the behavior surrounding WEBGL_shader_pixel_local_storage being enabled.");
57 checkExtensionNotSupportedWhenDisabled();
58 checkDependencyExtensionsEnabled(false);
59 debug("Enable WEBGL_shader_pixel_local_storage.");
60 pls = gl.getExtension("WEBGL_shader_pixel_local_storage");
61 wtu.runExtensionSupportedTest(gl, "WEBGL_shader_pixel_local_storage", pls != null);
62 if (!pls) {
63 finishTest();
64 return;
66 checkDependencyExtensionsEnabled(true);
68 checkImplementationDependentLimits();
69 checkInitialValues();
70 checkWebGLNonNormativeBehavior();
72 await checkRendering(gl);
73 await checkRendering(gl_no_alpha);
75 finishTest();
78 function checkExtensionNotSupportedWhenDisabled() {
79 debug("\nCheck that a context does not support WEBGL_shader_pixel_local_storage before it is " +
80 "enabled");
81 shouldBeNull("gl.getParameter(0x96E0 /*MAX_PIXEL_LOCAL_STORAGE_PLANES_WEBGL*/)");
82 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
83 shouldBeNull(
84 "gl.getParameter(0x96E1 /*MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_WEBGL*/)");
85 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
86 shouldBeNull(
87 "gl.getParameter(0x96E2 /*MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_WEBGL*/)");
88 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
89 shouldBeNull(
90 "gl.getParameter(0x96E3 /*PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL*/)");
91 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
92 wtu.glErrorShouldBe(gl, gl.NONE);
95 function checkDependencyExtensionsEnabled(enabled) {
96 debug("\nCheck that dependency extensions of WEBGL_shader_pixel_local_storage are " +
97 (enabled ? "enabled" : "disabled"));
98 if (wtu.getSupportedExtensionWithKnownPrefixes(gl, "OES_draw_buffers_indexed") !== undefined) {
99 gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1);
100 wtu.glErrorShouldBe(gl, enabled ? gl.NONE : gl.INVALID_ENUM,
101 "OES_draw_buffers_indexed not enabled or disabled as expected");
103 if (wtu.getSupportedExtensionWithKnownPrefixes(gl, "EXT_color_buffer_float") !== undefined) {
104 gl.bindRenderbuffer(gl.RENDERBUFFER, gl.createRenderbuffer());
105 gl.renderbufferStorage(gl.RENDERBUFFER, gl.R32F, 1, 1);
106 wtu.glErrorShouldBe(gl, enabled ? gl.NONE : gl.INVALID_ENUM,
107 "EXT_color_buffer_float not enabled or disabled as expected");
108 gl.bindRenderbuffer(gl.RENDERBUFFER, null);
110 if (wtu.getSupportedExtensionWithKnownPrefixes(gl, "EXT_color_buffer_half_float") !== undefined) {
111 gl.bindRenderbuffer(gl.RENDERBUFFER, gl.createRenderbuffer());
112 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RG16F, 1, 1);
113 wtu.glErrorShouldBe(gl, enabled ? gl.NONE : gl.INVALID_ENUM,
114 "EXT_color_buffer_half_float not enabled or disabled as expected");
115 gl.bindRenderbuffer(gl.RENDERBUFFER, null);
119 function checkImplementationDependentLimits() {
120 debug("\nVerify conformant implementation-dependent PLS limits.");
121 window.MAX_PIXEL_LOCAL_STORAGE_PLANES =
122 gl.getParameter(pls.MAX_PIXEL_LOCAL_STORAGE_PLANES_WEBGL);
123 window.MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE =
124 gl.getParameter(pls.MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_WEBGL);
125 window.MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES =
126 gl.getParameter(pls.MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_WEBGL);
127 wtu.glErrorShouldBe(gl, gl.NONE, "Pixel local storage queries should be supported.");
129 window.MAX_COLOR_ATTACHMENTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
130 window.MAX_DRAW_BUFFERS = gl.getParameter(gl.MAX_DRAW_BUFFERS);
132 // Table 6.X: Impementation Dependent Pixel Local Storage Limits.
133 shouldBeTrue("MAX_PIXEL_LOCAL_STORAGE_PLANES >= 4");
134 shouldBeTrue("MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE >= 0");
135 shouldBeTrue("MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES >= 4");
137 // Logical deductions based on 6.X.
138 shouldBeTrue(`MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES >=
139 MAX_PIXEL_LOCAL_STORAGE_PLANES`);
140 shouldBeTrue(`MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES >=
141 MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE`);
142 shouldBeTrue(`MAX_COLOR_ATTACHMENTS + MAX_PIXEL_LOCAL_STORAGE_PLANES >=
143 MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES`);
144 shouldBeTrue(`MAX_DRAW_BUFFERS + MAX_PIXEL_LOCAL_STORAGE_PLANES >=
145 MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES`);
148 function checkInitialValues() {
149 debug("\nCheck that PLS state has the correct initial values.");
150 shouldBeTrue("gl.getParameter(pls.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 0");
151 wtu.glErrorShouldBe(
152 gl, gl.NONE,
153 "It's valid to query GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL even when fbo 0 is bound.");
155 // Table 6.Y: Pixel Local Storage State
156 gl.bindFramebuffer(gl.FRAMEBUFFER, gl.createFramebuffer());
157 shouldBeTrue("gl.getParameter(pls.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 0");
158 debug("Check the initial clear values for each plane.");
159 const MAX_PIXEL_LOCAL_STORAGE_PLANES =
160 gl.getParameter(pls.MAX_PIXEL_LOCAL_STORAGE_PLANES_WEBGL);
161 for (let i = 0; i < MAX_PIXEL_LOCAL_STORAGE_PLANES; ++i)
163 expectTrue(pls.getFramebufferPixelLocalStorageParameterWEBGL(
164 i, pls.PIXEL_LOCAL_FORMAT_WEBGL) == gl.NONE);
165 expectTrue(pls.getFramebufferPixelLocalStorageParameterWEBGL(
166 i, pls.PIXEL_LOCAL_TEXTURE_NAME_WEBGL) == null);
167 expectTrue(pls.getFramebufferPixelLocalStorageParameterWEBGL(
168 i, pls.PIXEL_LOCAL_TEXTURE_LEVEL_WEBGL) == 0);
169 expectTrue(pls.getFramebufferPixelLocalStorageParameterWEBGL(
170 i, pls.PIXEL_LOCAL_TEXTURE_LAYER_WEBGL) == 0);
171 expectTrue(arraysEqual(
172 pls.getFramebufferPixelLocalStorageParameterWEBGL(
173 i, pls.PIXEL_LOCAL_CLEAR_VALUE_FLOAT_WEBGL),
174 new Float32Array([0, 0, 0, 0])));
175 expectTrue(arraysEqual(
176 pls.getFramebufferPixelLocalStorageParameterWEBGL(
177 i, pls.PIXEL_LOCAL_CLEAR_VALUE_INT_WEBGL),
178 new Int32Array([0, 0, 0, 0])));
179 expectTrue(arraysEqual(
180 pls.getFramebufferPixelLocalStorageParameterWEBGL(
181 i, pls.PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_WEBGL),
182 new Uint32Array([0, 0, 0, 0])));
184 wtu.glErrorShouldBe(gl, gl.NONE);
185 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
188 function checkWebGLNonNormativeBehavior() {
189 debug("\nCheck the WebGL-specific behavior not found in the " +
190 "ANGLE_shader_pixel_local_storage specification.");
191 gl.bindFramebuffer(gl.FRAMEBUFFER, gl.createFramebuffer());
193 debug("If 'texture' has been deleted, generates an INVALID_OPERATION error.");
194 wtu.glErrorShouldBe(gl, gl.NONE);
195 const tex = gl.createTexture();
196 gl.bindTexture(gl.TEXTURE_2D, tex);
197 gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 1, 1);
198 wtu.glErrorShouldBe(gl, gl.NONE);
199 gl.deleteTexture(tex);
200 pls.framebufferTexturePixelLocalStorageWEBGL(0, tex, 0, 0);
201 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
203 debug("\nIf 'texture' was generated by a different WebGL2RenderingContext than this one, " +
204 "generates an INVALID_OPERATION error.");
205 const gl2 = wtu.create3DContext(null, null, 2);
206 const tex2 = gl2.createTexture();
207 gl2.bindTexture(gl2.TEXTURE_2D, tex2);
208 gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, 1, 1);
209 pls.framebufferTexturePixelLocalStorageWEBGL(0, tex2, 0, 0);
210 wtu.glErrorShouldBe(gl2, gl2.NONE);
211 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
213 debug("\nIf value has less than srcOffset + 4 elements, generates an INVALID_VALUE error.");
214 wtu.glErrorShouldBe(gl, gl.NONE);
215 pls.framebufferPixelLocalClearValuefvWEBGL(0, new Float32Array(3));
216 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
217 pls.framebufferPixelLocalClearValuefvWEBGL(1, [0, 0, 0]);
218 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
219 pls.framebufferPixelLocalClearValueivWEBGL(2, new Int32Array(3));
220 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
221 pls.framebufferPixelLocalClearValueivWEBGL(3, [0, 0, 0]);
222 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
223 pls.framebufferPixelLocalClearValueuivWEBGL(4, new Uint32Array(3));
224 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
225 pls.framebufferPixelLocalClearValueuivWEBGL(3, [0, 0, 0]);
226 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
227 pls.framebufferPixelLocalClearValuefvWEBGL(2, new Float32Array(5), 2);
228 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
229 pls.framebufferPixelLocalClearValuefvWEBGL(1, [0, 0, 0, 0, 0], 2);
230 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
231 pls.framebufferPixelLocalClearValueivWEBGL(0, new Int32Array(5), 2);
232 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
233 pls.framebufferPixelLocalClearValueivWEBGL(1, [0, 0, 0, 0, 0], 2);
234 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
235 pls.framebufferPixelLocalClearValueuivWEBGL(2, new Uint32Array(5), 2);
236 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
237 pls.framebufferPixelLocalClearValueuivWEBGL(3, [0, 0, 0, 0, 0], 2);
238 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
240 debug("\nCheck that srcOffset works properly.");
241 const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
242 pls.framebufferPixelLocalClearValuefvWEBGL(0, new Float32Array(arr), 1);
243 wtu.glErrorShouldBe(gl, gl.NONE);
244 shouldBeTrue(`arraysEqual(pls.getFramebufferPixelLocalStorageParameterWEBGL(
245 0, pls.PIXEL_LOCAL_CLEAR_VALUE_FLOAT_WEBGL),
246 new Float32Array([1, 2, 3, 4]))`);
247 pls.framebufferPixelLocalClearValuefvWEBGL(1, arr, 2);
248 wtu.glErrorShouldBe(gl, gl.NONE);
249 shouldBeTrue(`arraysEqual(pls.getFramebufferPixelLocalStorageParameterWEBGL(
250 1, pls.PIXEL_LOCAL_CLEAR_VALUE_FLOAT_WEBGL),
251 [2, 3, 4, 5])`);
252 pls.framebufferPixelLocalClearValueivWEBGL(2, new Int32Array(arr), 3);
253 wtu.glErrorShouldBe(gl, gl.NONE);
254 shouldBeTrue(`arraysEqual(pls.getFramebufferPixelLocalStorageParameterWEBGL(
255 2, pls.PIXEL_LOCAL_CLEAR_VALUE_INT_WEBGL),
256 new Float32Array([3, 4, 5, 6]))`);
257 pls.framebufferPixelLocalClearValueivWEBGL(3, arr, 4);
258 wtu.glErrorShouldBe(gl, gl.NONE);
259 shouldBeTrue(`arraysEqual(pls.getFramebufferPixelLocalStorageParameterWEBGL(
260 3, pls.PIXEL_LOCAL_CLEAR_VALUE_INT_WEBGL),
261 [4, 5, 6, 7])`);
262 pls.framebufferPixelLocalClearValueuivWEBGL(2, new Uint32Array(arr), 5);
263 wtu.glErrorShouldBe(gl, gl.NONE);
264 shouldBeTrue(`arraysEqual(pls.getFramebufferPixelLocalStorageParameterWEBGL(
265 2, pls.PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_WEBGL),
266 new Uint32Array([5, 6, 7, 8]))`);
267 pls.framebufferPixelLocalClearValueuivWEBGL(1, arr, 6);
268 wtu.glErrorShouldBe(gl, gl.NONE);
269 shouldBeTrue(`arraysEqual(pls.getFramebufferPixelLocalStorageParameterWEBGL(
270 1, pls.PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_WEBGL),
271 [6, 7, 8, 9])`);
272 wtu.glErrorShouldBe(gl, gl.NONE);
274 debug("\nCheck that PIXEL_LOCAL_TEXTURE_NAME_WEBGL returns a WebGLTexture.");
275 shouldBeTrue(`pls.getFramebufferPixelLocalStorageParameterWEBGL(
276 0, pls.PIXEL_LOCAL_TEXTURE_NAME_WEBGL) === null`);
277 window.validTex = gl.createTexture();
278 gl.bindTexture(gl.TEXTURE_2D, validTex);
279 gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 1, 1);
280 wtu.glErrorShouldBe(gl, gl.NONE);
281 pls.framebufferTexturePixelLocalStorageWEBGL(0, validTex, 0, 0);
282 shouldBeTrue(`pls.getFramebufferPixelLocalStorageParameterWEBGL(
283 0, pls.PIXEL_LOCAL_TEXTURE_NAME_WEBGL) === validTex`);
284 pls.framebufferTexturePixelLocalStorageWEBGL(0, null, 0, 0);
285 shouldBeTrue(`pls.getFramebufferPixelLocalStorageParameterWEBGL(
286 0, pls.PIXEL_LOCAL_TEXTURE_NAME_WEBGL) === null`);
288 wtu.glErrorShouldBe(gl, gl.NONE);
289 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
292 async function checkRendering(localGL) {
293 const localCanvas = localGL.canvas;
294 const alpha = localGL.getContextAttributes().alpha;
295 debug("\nCheck very simple rendering with {alpha: " + alpha + "}");
297 const localPLS = localGL.getExtension("WEBGL_shader_pixel_local_storage");
298 if (!localPLS) {
299 testFailed("localGL doesn't support pixel local storage.");
300 return;
303 const tex = localGL.createTexture();
304 localGL.bindTexture(localGL.TEXTURE_2D, tex);
305 localGL.texStorage2D(localGL.TEXTURE_2D, 1, localGL.RGBA8, localCanvas.width, localCanvas.height);
306 wtu.glErrorShouldBe(localGL, localGL.NONE);
308 const plsFBO = localGL.createFramebuffer();
309 localGL.bindFramebuffer(localGL.FRAMEBUFFER, plsFBO);
310 localPLS.framebufferTexturePixelLocalStorageWEBGL(0, tex, 0, 0);
311 wtu.glErrorShouldBe(localGL, localGL.NONE);
313 localGL.viewport(0, 0, localCanvas.width, localCanvas.height);
315 // Adds a uniform color into the existing color in pixel local storage.
316 const fs = `#version 300 es
317 #extension GL_ANGLE_shader_pixel_local_storage : require
318 precision lowp float;
319 uniform vec4 color;
320 layout(binding=0, rgba8) uniform lowp pixelLocalANGLE pls;
321 void main() {
322 vec4 newColor = color + pixelLocalLoadANGLE(pls);
323 pixelLocalStoreANGLE(pls, newColor);
326 const program = wtu.setupProgram(localGL, [fullscreenQuadVertexShader, fs]);
327 if (!program) {
328 testFailed("Failed to compile program.");
329 return;
332 localGL.useProgram(program);
333 const colorUniLocation = localGL.getUniformLocation(program, "color");
334 wtu.glErrorShouldBe(localGL, localGL.NONE);
336 // Disable color mask to ensure PLS and canvas manage their own color masks properly.
337 localGL.colorMask(false, true, false, true);
339 // Set global variables for shouldBeTrue().
340 window.localGL = localGL;
341 window.localPLS = localPLS;
343 debug("\nCheck that pixel local storage works properly");
344 localGL.disable(localGL.DITHER);
345 localPLS.beginPixelLocalStorageWEBGL([localPLS.LOAD_OP_ZERO_WEBGL]);
346 wtu.glErrorShouldBe(localGL, localGL.NONE);
347 shouldBeTrue("localGL.getParameter(localPLS.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 1");
349 localGL.uniform4f(colorUniLocation, 0, 1, 0, 0);
350 localGL.drawArrays(localGL.TRIANGLE_STRIP, 0, 4);
352 localPLS.pixelLocalStorageBarrierWEBGL();
354 localGL.uniform4f(colorUniLocation, 1, 0, 0, 0);
355 localGL.drawArrays(localGL.TRIANGLE_STRIP, 0, 4);
357 localPLS.endPixelLocalStorageWEBGL([localPLS.STORE_OP_STORE_WEBGL]);
358 wtu.glErrorShouldBe(localGL, localGL.NONE);
359 shouldBeTrue("localGL.getParameter(localPLS.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 0");
361 const readFBO = localGL.createFramebuffer();
362 localGL.bindFramebuffer(localGL.READ_FRAMEBUFFER, readFBO);
363 localGL.framebufferTexture2D(localGL.READ_FRAMEBUFFER, localGL.COLOR_ATTACHMENT0,
364 localGL.TEXTURE_2D, tex, 0);
365 wtu.glErrorShouldBe(localGL, localGL.NONE);
366 wtu.checkCanvas(localGL, [255, 255, 0, 0]);
368 debug("\nCheck that alpha is properly handled in the main canvas.");
369 localGL.bindFramebuffer(localGL.DRAW_FRAMEBUFFER, null);
370 localGL.blitFramebuffer(0, 0, localCanvas.width, localCanvas.height, 0, 0, localCanvas.width,
371 localCanvas.height, localGL.COLOR_BUFFER_BIT, localGL.NEAREST);
372 localGL.bindFramebuffer(localGL.FRAMEBUFFER, null);
373 wtu.glErrorShouldBe(localGL, localGL.NONE);
374 wtu.checkCanvas(localGL, [255, 255, 0, alpha ? 0 : 255]);
376 localGL.bindFramebuffer(localGL.FRAMEBUFFER, plsFBO);
377 localPLS.beginPixelLocalStorageWEBGL([localPLS.LOAD_OP_LOAD_WEBGL]);
378 wtu.glErrorShouldBe(localGL, localGL.NONE);
379 shouldBeTrue("localGL.getParameter(localPLS.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 1");
381 debug("\nGoing down from composite.");
383 // The canvas should get cleared after compositing, even if PLS is active and color mask is
384 // disabled.
385 await new Promise(resolve => wtu.waitForComposite(resolve));
387 // Reset global variables for shouldBeTrue() after await.
388 window.localGL = localGL;
389 window.localPLS = localPLS;
391 debug("\nBack from composite!");
392 debug("\nPLS should still be active on plsFBO even after being interrupted for compositing.");
393 wtu.glErrorShouldBe(localGL, localGL.NONE);
394 shouldBeTrue("localGL.getParameter(localPLS.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 1");
396 localGL.uniform4f(colorUniLocation, 0, 0, 1, 0);
397 localGL.drawArrays(localGL.TRIANGLE_STRIP, 0, 4);
399 localPLS.endPixelLocalStorageWEBGL([localPLS.STORE_OP_STORE_WEBGL]);
400 wtu.glErrorShouldBe(localGL, localGL.NONE);
401 shouldBeTrue("localGL.getParameter(localPLS.PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_WEBGL) == 0");
403 debug("\nThe canvas should have gotten cleared while PLS was active.");
404 localGL.bindFramebuffer(localGL.FRAMEBUFFER, null);
405 wtu.checkCanvas(localGL, [0, 0, 0, alpha ? 0 : 255]);
407 debug("\nThe additional PLS draw to plsFBO should have still worked after being interrupted " +
408 "for compositing.");
409 localGL.bindFramebuffer(localGL.READ_FRAMEBUFFER, readFBO);
410 wtu.checkCanvas(localGL, [255, 255, 255, 0]);
411 wtu.glErrorShouldBe(localGL, localGL.NONE);
413 // Draws 'tex' to the canvas.
414 const fs2 = `#version 300 es
415 uniform lowp sampler2D tex;
416 out lowp vec4 fragColor;
417 void main() {
418 ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
419 fragColor = texelFetch(tex, pixelCoord, 0);
422 const program2 = wtu.setupProgram(localGL, [fullscreenQuadVertexShader, fs2]);
423 if (!program2) {
424 testFailed("Failed to compile program2.");
425 return;
428 debug("\nBlue should still be disabled in the color mask. Alpha is not disabled but should be " +
429 "implicitly disabled since the canvas doesn't have alpha.");
430 localGL.useProgram(program2);
431 localGL.uniform1i(localGL.getUniformLocation(program2, "tex"), 0);
432 localGL.bindFramebuffer(localGL.FRAMEBUFFER, null);
433 localGL.drawArrays(localGL.TRIANGLE_STRIP, 0, 4);
434 wtu.checkCanvas(localGL, [0, 255, 0, alpha ? 0 : 255]);
436 debug("\nThe client's color mask should have been preserved.");
437 shouldBeTrue(`arraysEqual(localGL.getParameter(localGL.COLOR_WRITEMASK),
438 [false, true, false, true])`);
441 runTest();
442 var successfullyParsed = true;
443 </script>
444 </body>
445 </html>