sync-webgl-specific.html (4831B)
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 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>WebGL2 specific sync object behaviors</title> 12 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 13 <script src="../../js/js-test-pre.js"></script> 14 <script src="../../js/webgl-test-utils.js"></script> 15 </head> 16 <body> 17 <div id="description"></div> 18 <div id="console"></div> 19 <canvas id="canvas" width="2" height="2"> </canvas> 20 <script> 21 "use strict"; 22 description("This test checks WebGL2 specific sync object behaviors"); 23 24 debug(""); 25 debug("Canvas.getContext"); 26 27 var wtu = WebGLTestUtils; 28 var gl = wtu.create3DContext("canvas", null, 2); 29 var sync = null; 30 var pixel = new Uint8Array(4); 31 32 if (!gl) { 33 testFailed("context does not exist"); 34 finishTest(); 35 } else { 36 testPassed("context exists"); 37 38 debug(""); 39 shouldBe("gl.TIMEOUT_IGNORED", "-1"); 40 shouldBe("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL", "0x9247"); 41 var max = gl.getParameter(gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL); 42 debug("Querying gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL"); 43 shouldBe("gl.getError()", "gl.NO_ERROR"); 44 debug("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL returns " + max + "ns"); 45 if (max < 0) { 46 testFailed("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL < 0"); 47 } else if (max > 1000 * 1000 * 1000) { 48 // This is not demanded by the WebGL2 spec, but anything larger than 1000ms 49 // is bad idea and no implementation should allow it. 50 testFailed("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL should not exceed 1000ms"); 51 } else { 52 testPassed("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL returns a valid value"); 53 } 54 sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); 55 shouldBeNonNull("sync"); 56 shouldBe("gl.getError()", "gl.NO_ERROR"); 57 gl.clientWaitSync(sync, 0, max); 58 shouldBe("gl.getError()", "gl.NO_ERROR"); 59 gl.clientWaitSync(sync, 0, max + 1); 60 shouldBe("gl.getError()", "gl.INVALID_OPERATION"); 61 62 requestAnimationFrame(runGetSyncParameterTest); 63 } 64 65 var numRetries = 20000; 66 var iteration = 0; 67 68 function syncWithGLServer() { 69 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); 70 } 71 72 function runGetSyncParameterTest() { 73 debug(""); 74 debug("Verifying sync object isn't signaled too early"); 75 sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); 76 // Verify as best as possible that the implementation doesn't allow a sync 77 // object to become signaled until returning control to the event loop, by 78 // spin-looping for some time. 79 var iter = numRetries; 80 while (--iter > 0) { 81 syncWithGLServer(); 82 if (gl.getSyncParameter(sync, gl.SYNC_STATUS) == gl.SIGNALED) { 83 testFailed("Sync object was signaled too early"); 84 finishTest(); 85 return; 86 } 87 } 88 testPassed("Sync object wasn't signaled too early"); 89 iteration = numRetries; 90 requestAnimationFrame(finishSyncParameterTest); 91 } 92 93 94 function finishSyncParameterTest() { 95 if (--iteration == 0) { 96 testFailed("Sync object wasn't signaled in a reasonable timeframe (" + numRetries + " iterations)"); 97 finishTest(); 98 return; 99 } 100 var res = gl.getSyncParameter(sync, gl.SYNC_STATUS); 101 if (res == gl.SIGNALED) { 102 testPassed("Sync object was signaled"); 103 requestAnimationFrame(runClientWaitSyncTest); 104 return; 105 } 106 // Try again. 107 syncWithGLServer(); 108 requestAnimationFrame(finishSyncParameterTest); 109 } 110 111 function runClientWaitSyncTest() { 112 debug(""); 113 debug("Verifying clientWaitSync doesn't complete too early"); 114 115 sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); 116 // Verify as best as possible that the implementation doesn't allow 117 // clientWaitSync to return CONDITION_SATISFIED or ALREADY_SIGNALED until 118 // returning control to the event loop, by spin-looping for some time. 119 var iter = numRetries; 120 while (--iter > 0) { 121 syncWithGLServer(); 122 var res = gl.clientWaitSync(sync, 0, 0); 123 if (res == gl.CONDITION_SATISFIED || res == gl.ALREADY_SIGNALED) { 124 testFailed("clientWaitSync completed successfully too early"); 125 finishTest(); 126 return; 127 } 128 } 129 testPassed("clientWaitSync didn't complete successfully too early"); 130 iteration = numRetries; 131 requestAnimationFrame(finishClientWaitSyncTest); 132 } 133 134 function finishClientWaitSyncTest() { 135 if (--iteration == 0) { 136 testFailed("clientWaitSync didn't complete in a reasonable timeframe (" + numRetries + " iterations)"); 137 finishTest(); 138 return; 139 } 140 var res = gl.clientWaitSync(sync, 0, 0); 141 if (res == gl.CONDITION_SATISFIED || res == gl.ALREADY_SIGNALED) { 142 testPassed("clientWaitSync completed successfully"); 143 // This is the last test right now. 144 finishTest(); 145 return; 146 } 147 // Try again. 148 syncWithGLServer(); 149 requestAnimationFrame(finishClientWaitSyncTest); 150 } 151 152 debug(""); 153 var successfullyParsed = true; 154 </script> 155 </body> 156 </html>