我正在尝试使用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上搜索了此类内容,但一无所获。



编辑

基于answer from pleup,我整理了此代码示例,该示例在我的环境(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


  为了确保跨平台的行为一致,仅当用户代理的事件循环未执行任务时,同步对象才可以转换为发出信号的状态。换一种说法:
  
  直到控制权返回到用户代理的主循环之前,同步对象才可以发出信号。
  在循环中重复获取同步对象的SYNC_STATUS参数,而不将控制权返回给用户代理,必须始终返回相同的值。

关于javascript - WebGLSync始终是未签名的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53647031/

10-12 13:20