tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

webgl-util.js (3882B)


      1 WebGLUtil = (function () {
      2  // ---------------------------------------------------------------------------
      3  // WebGL helpers
      4 
      5  function withWebGL2(canvasId, callback, onFinished) {
      6    var run = function () {
      7      var canvas = document.getElementById(canvasId);
      8 
      9      var gl = null;
     10      try {
     11        gl = canvas.getContext("webgl2");
     12      } catch (e) {}
     13 
     14      if (!gl) {
     15        todo(false, "WebGL2 is not supported");
     16        onFinished();
     17        return;
     18      }
     19 
     20      callback(gl);
     21      onFinished();
     22    };
     23 
     24    try {
     25      var prefArrArr = [
     26        ["webgl.force-enabled", true],
     27        ["webgl.enable-webgl2", true],
     28      ];
     29      var prefEnv = { set: prefArrArr };
     30      SpecialPowers.pushPrefEnv(prefEnv, run);
     31    } catch (e) {
     32      warning("No SpecialPowers, but trying WebGL2 anyway...");
     33      run();
     34    }
     35  }
     36 
     37  // Returns a valid shader, or null on errors.
     38  function createShaderById(gl, id) {
     39    var elem = document.getElementById(id);
     40    if (!elem) {
     41      throw new Error(
     42        "Failed to create shader from non-existent id '" + id + "'."
     43      );
     44    }
     45 
     46    var src = elem.innerHTML.trim();
     47 
     48    var shader;
     49    if (elem.type == "x-shader/x-fragment") {
     50      shader = gl.createShader(gl.FRAGMENT_SHADER);
     51    } else if (elem.type == "x-shader/x-vertex") {
     52      shader = gl.createShader(gl.VERTEX_SHADER);
     53    } else {
     54      throw new Error(
     55        "Bad MIME type for shader '" + id + "': " + elem.type + "."
     56      );
     57    }
     58 
     59    gl.shaderSource(shader, src);
     60    gl.compileShader(shader);
     61 
     62    return shader;
     63  }
     64 
     65  function createProgramByIds(gl, vsId, fsId) {
     66    var vs = createShaderById(gl, vsId);
     67    var fs = createShaderById(gl, fsId);
     68    if (!vs || !fs) {
     69      return null;
     70    }
     71 
     72    var prog = gl.createProgram();
     73    gl.attachShader(prog, vs);
     74    gl.attachShader(prog, fs);
     75    gl.linkProgram(prog);
     76 
     77    if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
     78      var str = "Shader program linking failed:";
     79      str += "\nShader program info log:\n" + gl.getProgramInfoLog(prog);
     80      str += "\n\nVert shader log:\n" + gl.getShaderInfoLog(vs);
     81      str += "\n\nFrag shader log:\n" + gl.getShaderInfoLog(fs);
     82      console.error(str);
     83      return null;
     84    }
     85 
     86    return prog;
     87  }
     88 
     89  return {
     90    withWebGL2,
     91 
     92    createShaderById,
     93    createProgramByIds,
     94 
     95    linkProgramByIds(gl, vertSrcElem, fragSrcElem) {
     96      const prog = gl.createProgram();
     97 
     98      function attachShaderById(type, srcElem) {
     99        const shader = gl.createShader(type);
    100        gl.shaderSource(shader, srcElem.innerHTML.trim() + "\n");
    101        gl.compileShader(shader);
    102        gl.attachShader(prog, shader);
    103        prog[type] = shader;
    104      }
    105      attachShaderById(gl.VERTEX_SHADER, vertSrcElem);
    106      attachShaderById(gl.FRAGMENT_SHADER, fragSrcElem);
    107 
    108      gl.linkProgram(prog);
    109      const success = gl.getProgramParameter(prog, gl.LINK_STATUS);
    110      if (!success) {
    111        console.error("Error linking program:");
    112        console.error("\nLink log: " + gl.getProgramInfoLog(prog));
    113        console.error(
    114          "\nVert shader log: " + gl.getShaderInfoLog(prog[gl.VERTEX_SHADER])
    115        );
    116        console.error(
    117          "\nFrag shader log: " + gl.getShaderInfoLog(prog[gl.FRAGMENT_SHADER])
    118        );
    119        return null;
    120      }
    121      gl.deleteShader(prog[gl.VERTEX_SHADER]);
    122      gl.deleteShader(prog[gl.FRAGMENT_SHADER]);
    123 
    124      let count = gl.getProgramParameter(prog, gl.ACTIVE_ATTRIBUTES);
    125      for (let i = 0; i < count; i++) {
    126        const info = gl.getActiveAttrib(prog, i);
    127        prog[info.name] = gl.getAttribLocation(prog, info.name);
    128      }
    129      count = gl.getProgramParameter(prog, gl.ACTIVE_UNIFORMS);
    130      for (let i = 0; i < count; i++) {
    131        const info = gl.getActiveUniform(prog, i);
    132        prog[info.name] = gl.getUniformLocation(prog, info.name);
    133      }
    134      return prog;
    135    },
    136  };
    137 })();