summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-mochitest/webgl-util.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-mochitest/webgl-util.js')
-rw-r--r--dom/canvas/test/webgl-mochitest/webgl-util.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-mochitest/webgl-util.js b/dom/canvas/test/webgl-mochitest/webgl-util.js
new file mode 100644
index 0000000000..ca4837860a
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/webgl-util.js
@@ -0,0 +1,137 @@
+WebGLUtil = (function () {
+ // ---------------------------------------------------------------------------
+ // WebGL helpers
+
+ function withWebGL2(canvasId, callback, onFinished) {
+ var run = function () {
+ var canvas = document.getElementById(canvasId);
+
+ var gl = null;
+ try {
+ gl = canvas.getContext("webgl2");
+ } catch (e) {}
+
+ if (!gl) {
+ todo(false, "WebGL2 is not supported");
+ onFinished();
+ return;
+ }
+
+ callback(gl);
+ onFinished();
+ };
+
+ try {
+ var prefArrArr = [
+ ["webgl.force-enabled", true],
+ ["webgl.enable-webgl2", true],
+ ];
+ var prefEnv = { set: prefArrArr };
+ SpecialPowers.pushPrefEnv(prefEnv, run);
+ } catch (e) {
+ warning("No SpecialPowers, but trying WebGL2 anyway...");
+ run();
+ }
+ }
+
+ // Returns a valid shader, or null on errors.
+ function createShaderById(gl, id) {
+ var elem = document.getElementById(id);
+ if (!elem) {
+ throw new Error(
+ "Failed to create shader from non-existent id '" + id + "'."
+ );
+ }
+
+ var src = elem.innerHTML.trim();
+
+ var shader;
+ if (elem.type == "x-shader/x-fragment") {
+ shader = gl.createShader(gl.FRAGMENT_SHADER);
+ } else if (elem.type == "x-shader/x-vertex") {
+ shader = gl.createShader(gl.VERTEX_SHADER);
+ } else {
+ throw new Error(
+ "Bad MIME type for shader '" + id + "': " + elem.type + "."
+ );
+ }
+
+ gl.shaderSource(shader, src);
+ gl.compileShader(shader);
+
+ return shader;
+ }
+
+ function createProgramByIds(gl, vsId, fsId) {
+ var vs = createShaderById(gl, vsId);
+ var fs = createShaderById(gl, fsId);
+ if (!vs || !fs) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vs);
+ gl.attachShader(prog, fs);
+ gl.linkProgram(prog);
+
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var str = "Shader program linking failed:";
+ str += "\nShader program info log:\n" + gl.getProgramInfoLog(prog);
+ str += "\n\nVert shader log:\n" + gl.getShaderInfoLog(vs);
+ str += "\n\nFrag shader log:\n" + gl.getShaderInfoLog(fs);
+ console.error(str);
+ return null;
+ }
+
+ return prog;
+ }
+
+ return {
+ withWebGL2,
+
+ createShaderById,
+ createProgramByIds,
+
+ linkProgramByIds(gl, vertSrcElem, fragSrcElem) {
+ const prog = gl.createProgram();
+
+ function attachShaderById(type, srcElem) {
+ const shader = gl.createShader(type);
+ gl.shaderSource(shader, srcElem.innerHTML.trim() + "\n");
+ gl.compileShader(shader);
+ gl.attachShader(prog, shader);
+ prog[type] = shader;
+ }
+ attachShaderById(gl.VERTEX_SHADER, vertSrcElem);
+ attachShaderById(gl.FRAGMENT_SHADER, fragSrcElem);
+
+ gl.linkProgram(prog);
+ const success = gl.getProgramParameter(prog, gl.LINK_STATUS);
+ if (!success) {
+ console.error("Error linking program:");
+ console.error("\nLink log: " + gl.getProgramInfoLog(prog));
+ console.error(
+ "\nVert shader log: " + gl.getShaderInfoLog(prog[gl.VERTEX_SHADER])
+ );
+ console.error(
+ "\nFrag shader log: " + gl.getShaderInfoLog(prog[gl.FRAGMENT_SHADER])
+ );
+ return null;
+ }
+ gl.deleteShader(prog[gl.VERTEX_SHADER]);
+ gl.deleteShader(prog[gl.FRAGMENT_SHADER]);
+
+ let count = gl.getProgramParameter(prog, gl.ACTIVE_ATTRIBUTES);
+ for (let i = 0; i < count; i++) {
+ const info = gl.getActiveAttrib(prog, i);
+ prog[info.name] = gl.getAttribLocation(prog, info.name);
+ }
+ count = gl.getProgramParameter(prog, gl.ACTIVE_UNIFORMS);
+ for (let i = 0; i < count; i++) {
+ const info = gl.getActiveUniform(prog, i);
+ prog[info.name] = gl.getUniformLocation(prog, info.name);
+ }
+ return prog;
+ },
+ };
+})();