javascript - 如何避免 webGL 着色器加载对 cpu 施加过多负载

标签 javascript multithreading google-chrome webgl

当加载几个庞大的着色器程序时,webGl 会给 cpu 带来很大的压力,使 UI 停滞,有时甚至会触发 chrome 的 cpu watchdog,从而杀死页面。

我该怎么做才能在这种情况下显示“正在加载”屏幕并限制我的处理器使用率,以免我被 chrome 盯上?

relevant section of code ,最终导致 these actual webGL calls :

var p = this.program = gl.createProgram();
gl.attachShader(p, this.makeShader(gl.VERTEX_SHADER, vertex));
gl.attachShader(p, this.makeShader(gl.FRAGMENT_SHADER, fragment));
gl.linkProgram(p);

最佳答案

几个想法

  1. 您可以尝试等待几帧以检查结果

    var vs = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vs, vSource);
    gl.compileShader(vs);
    var fs = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fs, vSource);
    gl.compileShader(fs);
    var p = gl.createProgram();
    gl.attachShader(p, vs);
    gl.attachshader(p, fs);
    gl.linkProgram(p);
    gl.flush(); // Important!
    setTimeout(checkResults, 2000);  // check results 2 seconds later
    
    function checkResults() {
       var status = gl.getProgramParameter(p, gl.LINK_STATUS);
       ...
    }
    

    至少在 Chrome 中,这可能意味着 GPU 进程将编译程序,而渲染进程(运行 JavaScript 的进程)将继续运行,因此至少 JavaScript 不会阻塞,除非它在您运行时尚未完成检查结果。

  2. 将事情分解成多个步骤

    var tasks = [];
    
    addTask(compileVertexShader);
    addTask(compileFragmentShader);
    addTask(linkProgram);
    addTask(render);
    
    function addTask(fn) {
      tasks.push(fn);
      runNextTask();
    }
    
    var taskRunning = false;
    function runNextTask() {
      if (taskRunning) {
        return;
      }
      var taskFn = tasks.shift();
      if (taskFn) {
        taskRunning = true;
        setTimeout(function() {
          taskRunning = false;
          taskFn();
          runNextTask();
        }, 1);
      }
    }
    
    function compileVertexShader() {
      ...
    }
    
    function compileFragmentShader() {
      ...
    }
    
    function linkProgram() {
      ...
    }
    
    function render() {
      ...
    }    
    

    只要一个功能不会花费太长时间,就不会有任何问题。

    有一些通用库可以帮助处理此类问题。例如the async library .

关于javascript - 如何避免 webGL 着色器加载对 cpu 施加过多负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29184370/

相关文章:

java - 向所有客户端发送消息(客户端 - 服务器通信)

selenium - 错误号 : 33: SessionNotCreatedError session not created exception from unknown error while trying to simulate chrome browser using SeleniumBasic

javascript - 旋转图像的 SVG 低性能

html - Chrome 的 "save password"功能将用户名放在不相关的字段中

javascript - 如何提醒用户 Chrome 应用程序更新?

javascript - 有人可以告诉我从字符串中删除特定内联 CSS 样式的最佳方法吗?

Java在线程完成之前执行下一个任务

javascript - 卸载以使用跨浏览器的按钮

javascript - 为什么在 CasperJS 中 POST 请求响应数据为空,即使相同的请求在 Postman 中显示数据

java - 在 Socket.getInputStream 之前向 SocketInputStream 发送一些内容?