WebGLSync 始终未签名
WebGLSync is always UNSIGNALED
我正在尝试使用 WebGLSyncs,但我很难让 WebGLSync 发出信号。
以下内容在所有支持 WebGL2 的浏览器(Chrome、Opera、Firefox)上未显示:
function test() {
let canvas = document.createElement('canvas');
let gl = canvas.getContext('webgl2');
let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
gl.finish();
let status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(sync, status, status === gl.UNSIGNALED); // logs "true"
gl.deleteSync(sync);
}
我希望它能工作,因为 gl.finish() 应该等到所有 GPU 命令都已处理 - 但看起来同步栅栏没有。
我非常感谢一个最小的、有效的 WebGLSync
示例,它实际上得到了信号。我搜索了 GitHub 但没有找到。
编辑
基于 ,我整理了这段代码示例,它在我的环境中运行良好 (Windows + Chrome)。
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function test() {
let canvas = document.createElement('canvas');
let gl = canvas.getContext('webgl2');
let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
while (gl.getSyncParameter(sync, gl.SYNC_STATUS) === gl.UNSIGNALED) {
await sleep(100);
}
let status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(sync, status, status === gl.SIGNALED);
gl.deleteSync(sync);
}
test()
您必须等待滴答声才能看到同步信号。 JS执行帧同步状态永远不会改变
https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.14
In order to ensure consistent behavior across platforms, sync objects may only transition to the signaled state when the user agent's event loop is not executing a task. In other words:
A sync object must not become signaled until control has returned to the user agent's main loop.
Repeatedly fetching a sync object's SYNC_STATUS parameter in a loop, without returning control to the user agent, must always return the same value.
5.39 Sync objects' results must not be made available in the current frame
In OpenGL ES 3.0, if the appropriate primitives (e.g. glFinish() or another synchronous API) are called, a sync object may be signaled in the same frame it was issued. In WebGL, in order to improve application portability, a sync object must never transition to the signaled state in the same frame the sync was issued. See the specification of getSyncParameter and clientWaitSync for discussion and rationale.
async function test() {
let canvas = document.createElement('canvas');
let gl = canvas.getContext('webgl2');
let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
gl.finish();
await waitFrame();
let status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(sync, glEnumToString(gl, status));
gl.deleteSync(sync);
}
function waitFrame() {
return new Promise((resolve) => {
requestAnimationFrame(resolve);
});
}
function glEnumToString(gl, v) {
for (const k in gl) {
if (gl[k] === v) {
return k;
}
}
return `0x${v.toString(16)}`;
}
test();
我正在尝试使用 WebGLSyncs,但我很难让 WebGLSync 发出信号。
以下内容在所有支持 WebGL2 的浏览器(Chrome、Opera、Firefox)上未显示:
function test() {
let canvas = document.createElement('canvas');
let gl = canvas.getContext('webgl2');
let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
gl.finish();
let status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(sync, status, status === gl.UNSIGNALED); // logs "true"
gl.deleteSync(sync);
}
我希望它能工作,因为 gl.finish() 应该等到所有 GPU 命令都已处理 - 但看起来同步栅栏没有。
我非常感谢一个最小的、有效的 WebGLSync
示例,它实际上得到了信号。我搜索了 GitHub 但没有找到。
编辑
基于
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function test() {
let canvas = document.createElement('canvas');
let gl = canvas.getContext('webgl2');
let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
while (gl.getSyncParameter(sync, gl.SYNC_STATUS) === gl.UNSIGNALED) {
await sleep(100);
}
let status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(sync, status, status === gl.SIGNALED);
gl.deleteSync(sync);
}
test()
您必须等待滴答声才能看到同步信号。 JS执行帧同步状态永远不会改变
https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.14
In order to ensure consistent behavior across platforms, sync objects may only transition to the signaled state when the user agent's event loop is not executing a task. In other words:
A sync object must not become signaled until control has returned to the user agent's main loop. Repeatedly fetching a sync object's SYNC_STATUS parameter in a loop, without returning control to the user agent, must always return the same value.
5.39 Sync objects' results must not be made available in the current frame In OpenGL ES 3.0, if the appropriate primitives (e.g. glFinish() or another synchronous API) are called, a sync object may be signaled in the same frame it was issued. In WebGL, in order to improve application portability, a sync object must never transition to the signaled state in the same frame the sync was issued. See the specification of getSyncParameter and clientWaitSync for discussion and rationale.
async function test() {
let canvas = document.createElement('canvas');
let gl = canvas.getContext('webgl2');
let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
gl.finish();
await waitFrame();
let status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
console.log(sync, glEnumToString(gl, status));
gl.deleteSync(sync);
}
function waitFrame() {
return new Promise((resolve) => {
requestAnimationFrame(resolve);
});
}
function glEnumToString(gl, v) {
for (const k in gl) {
if (gl[k] === v) {
return k;
}
}
return `0x${v.toString(16)}`;
}
test();