Bug 1915045 Ensure decode tasks are scheduled on BufferingState::Enter() r=media...
[gecko.git] / dom / canvas / test / webgl-mochitest / webgl-util.js
blobca4837860a68bcfab2980ecdef669682ac07ab3a
1 WebGLUtil = (function () {
2   // ---------------------------------------------------------------------------
3   // WebGL helpers
5   function withWebGL2(canvasId, callback, onFinished) {
6     var run = function () {
7       var canvas = document.getElementById(canvasId);
9       var gl = null;
10       try {
11         gl = canvas.getContext("webgl2");
12       } catch (e) {}
14       if (!gl) {
15         todo(false, "WebGL2 is not supported");
16         onFinished();
17         return;
18       }
20       callback(gl);
21       onFinished();
22     };
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   }
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     }
46     var src = elem.innerHTML.trim();
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     }
59     gl.shaderSource(shader, src);
60     gl.compileShader(shader);
62     return shader;
63   }
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     }
72     var prog = gl.createProgram();
73     gl.attachShader(prog, vs);
74     gl.attachShader(prog, fs);
75     gl.linkProgram(prog);
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     }
86     return prog;
87   }
89   return {
90     withWebGL2,
92     createShaderById,
93     createProgramByIds,
95     linkProgramByIds(gl, vertSrcElem, fragSrcElem) {
96       const prog = gl.createProgram();
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);
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]);
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 })();