From cf1277a469edcd89e60c71efb12d3701d560fcc3 Mon Sep 17 00:00:00 2001
From: Jeff Gilbert
Date: Thu, 19 Sep 2013 15:37:54 -0700
Subject: [PATCH] Bug 911346 - Add a test for WebGL context creation. -
r=bjacob
---
.../test/webgl/non-conf-tests/Makefile.in | 4 +
.../test/webgl/non-conf-tests/driver-info.js | 125 ++++++++++++++++++
.../non-conf-tests/test_webgl_available.html | 37 ++++++
.../test_webgl_conformance.html | 10 +-
.../test/webgl/non-conf-tests/webgl-util.js | 114 ++++++++++++++++
5 files changed, 287 insertions(+), 3 deletions(-)
create mode 100644 content/canvas/test/webgl/non-conf-tests/driver-info.js
create mode 100644 content/canvas/test/webgl/non-conf-tests/test_webgl_available.html
create mode 100644 content/canvas/test/webgl/non-conf-tests/webgl-util.js
diff --git a/content/canvas/test/webgl/non-conf-tests/Makefile.in b/content/canvas/test/webgl/non-conf-tests/Makefile.in
index aca1b163808f..bb4dae8c3b53 100644
--- a/content/canvas/test/webgl/non-conf-tests/Makefile.in
+++ b/content/canvas/test/webgl/non-conf-tests/Makefile.in
@@ -4,6 +4,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MOCHITEST_FILES = \
+ driver-info.js \
+ webgl-util.js \
+ \
+ test_webgl_available.html \
test_webgl_conformance.html \
test_webgl_request_mismatch.html \
$(NULL)
diff --git a/content/canvas/test/webgl/non-conf-tests/driver-info.js b/content/canvas/test/webgl/non-conf-tests/driver-info.js
new file mode 100644
index 000000000000..de2a483ddd3d
--- /dev/null
+++ b/content/canvas/test/webgl/non-conf-tests/driver-info.js
@@ -0,0 +1,125 @@
+DriverInfo = (function() {
+ // ---------------------------------------------------------------------------
+ // Debug info handling
+
+ function defaultInfoFunc(str) {
+ console.log('Info: ' + str);
+ }
+
+ var gInfoFunc = defaultInfoFunc;
+ function setInfoFunc(func) {
+ gInfoFunc = func;
+ }
+
+ function info(str) {
+ gInfoFunc(str);
+ }
+
+ // ---------------------------------------------------------------------------
+ // OS and driver identification
+ // Stolen from content/canvas/test/webgl/test_webgl_conformance_test_suite.html
+ function detectDriverInfo() {
+ const Cc = SpecialPowers.Cc;
+ const Ci = SpecialPowers.Ci;
+ var doc = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser).parseFromString("", "text/html");
+
+ var canvas = doc.createElement("canvas");
+ canvas.width = 1;
+ canvas.height = 1;
+
+ var type = "";
+ var gl;
+ try {
+ gl = canvas.getContext("experimental-webgl");
+ } catch(e) {
+ ok(false, "Failed to create a WebGL context for getting driver info.");
+ return ["", ""]
+ }
+ var ext = gl.getExtension("WEBGL_debug_renderer_info");
+ // this extension is unconditionally available to chrome. No need to check.
+
+ var webglRenderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
+ var webglVendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
+ return [webglVendor, webglRenderer];
+ }
+
+ var OS = {
+ WINDOWS: 'windows',
+ MAC: 'mac',
+ LINUX: 'linux',
+ ANDROID: 'android',
+ };
+
+ var DRIVER = {
+ MESA: 'mesa',
+ NVIDIA: 'nvidia',
+ ANDROID_X86_EMULATOR: 'android x86 emulator',
+ };
+
+ var kOS = null;
+ var kOSVersion = null;
+ var kDriver = null;
+
+ if (navigator.platform.indexOf('Win') == 0) {
+ kOS = OS.WINDOWS;
+
+ // code borrowed from browser/modules/test/browser_taskbar_preview.js
+ var version = SpecialPowers.Services.sysinfo.getProperty('version');
+ kOSVersion = parseFloat(version);
+ // Version 6.0 is Vista, 6.1 is 7.
+
+ } else if (navigator.platform.indexOf('Mac') == 0) {
+ kOS = OS.MAC;
+
+ var versionMatch = /Mac OS X (\d+.\d+)/.exec(navigator.userAgent);
+ kOSVersion = versionMatch ? parseFloat(versionMatch[1]) : null;
+
+ } else if (navigator.appVersion.indexOf('Android') != -1) {
+ kOS = OS.ANDROID;
+ // From layout/tools/reftest/reftest.js:
+ kOSVersion = SpecialPowers.Services.sysinfo.getProperty('version');
+
+ } else if (navigator.platform.indexOf('Linux') == 0) {
+ // Must be checked after android, as android also has a 'Linux' platform string.
+ kOS = OS.LINUX;
+ }
+
+ var glVendor, glRenderer;
+ [glVendor, glRenderer] = detectDriverInfo();
+ info('GL vendor: ' + glVendor);
+ info('GL renderer: ' + glRenderer);
+
+ if (glRenderer.contains('llvmpipe')) {
+ kDriver = DRIVER.MESA;
+ } else if (glRenderer.contains('Android Emulator')) {
+ kGLDriver = DRIVER.ANDROID_X86_EMULATOR;
+ } else if (glVendor.contains('NVIDIA')) {
+ kDriver = DRIVER.NVIDIA;
+ }
+
+ if (kOS) {
+ info('OS detected as: ' + kOS);
+ info(' Version: ' + kOSVersion);
+ } else {
+ info('OS not detected.');
+ info(' `platform`: ' + navigator.platform);
+ info(' `appVersion`: ' + navigator.appVersion);
+ info(' `userAgent`: ' + navigator.userAgent);
+ }
+ if (kDriver) {
+ info('GL driver detected as: ' + kDriver);
+ } else {
+ info('GL driver not detected.');
+ }
+
+ return {
+ setInfoFunc: setInfoFunc,
+
+ OS: OS,
+ DRIVER: DRIVER,
+ getOS: function() { return kOS; },
+ getDriver: function() { return kDriver; },
+ getOSVersion: function() { return kOSVersion; },
+ };
+})();
+
diff --git a/content/canvas/test/webgl/non-conf-tests/test_webgl_available.html b/content/canvas/test/webgl/non-conf-tests/test_webgl_available.html
new file mode 100644
index 000000000000..1640b0a0f85d
--- /dev/null
+++ b/content/canvas/test/webgl/non-conf-tests/test_webgl_available.html
@@ -0,0 +1,37 @@
+
+
+
+WebGL test: Check that WebGL works (or not) if it should (or should not).
+
+
+
+
+
+
+
+
+
+
+
diff --git a/content/canvas/test/webgl/non-conf-tests/test_webgl_conformance.html b/content/canvas/test/webgl/non-conf-tests/test_webgl_conformance.html
index aad40652d938..a0c3af289f88 100644
--- a/content/canvas/test/webgl/non-conf-tests/test_webgl_conformance.html
+++ b/content/canvas/test/webgl/non-conf-tests/test_webgl_conformance.html
@@ -1,14 +1,17 @@
+
+
WebGL test: 'webgl' context request
+
+
-
+
+
diff --git a/content/canvas/test/webgl/non-conf-tests/webgl-util.js b/content/canvas/test/webgl/non-conf-tests/webgl-util.js
new file mode 100644
index 000000000000..4621adc93b3c
--- /dev/null
+++ b/content/canvas/test/webgl/non-conf-tests/webgl-util.js
@@ -0,0 +1,114 @@
+WebGLUtil = (function() {
+ // ---------------------------------------------------------------------------
+ // Error handling
+
+ function defaultErrorFunc(str) {
+ console.log('Error: ' + str);
+ }
+
+ var gErrorFunc = defaultErrorFunc;
+ function setErrorFunc(func) {
+ gErrorFunc = func;
+ }
+
+ function error(str) {
+ gErrorFunc(str);
+ }
+
+ // ---------------------------------------------------------------------------
+ // WebGL helpers
+
+ function getWebGL(canvasId, requireConformant) {
+ // `requireConformant` will default to falsey if it is not supplied.
+
+ var canvas = document.getElementById(canvasId);
+
+ var gl = null;
+ try {
+ gl = canvas.getContext('webgl');
+ } catch(e) {}
+
+ if (!gl && !requireConformant) {
+ try {
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {}
+ }
+
+ if (!gl) {
+ error('WebGL context could not be retrieved from \'' + canvasId + '\'.');
+ return null;
+ }
+
+ return gl;
+ }
+
+ function getContentFromElem(elem) {
+ var str = "";
+ var k = elem.firstChild;
+ while (k) {
+ if (k.nodeType == 3)
+ str += k.textContent;
+
+ k = k.nextSibling;
+ }
+
+ return str;
+ }
+
+ // Returns a valid shader, or null on errors.
+ function createShaderById(gl, id) {
+ var elem = document.getElementById(id);
+ if (!elem) {
+ error('Failed to create shader from non-existent id \'' + id + '\'.');
+ return null;
+ }
+
+ var src = getContentById(id);
+
+ var shader;
+ if (elem.type == "x-shader/x-fragment") {
+ shader = gl.createShader(gl.FRAGMENT_SHADER);
+ } else if (shaderScript.type == "x-shader/x-vertex") {
+ shader = gl.createShader(gl.VERTEX_SHADER);
+ } else {
+ error('Bad MIME type for shader \'' + id + '\': ' + elem.type + '.');
+ return null;
+ }
+
+ gl.shaderSource(shader, str);
+ 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:\n";
+ str += "Shader program info log:\n" + gl.getProgramInfoLog(prog) + "\n\n";
+ str += "Vert shader log:\n" + gl.getShaderInfoLog(vs) + "\n\n";
+ str += "Frag shader log:\n" + gl.getShaderInfoLog(fs);
+ error(str);
+ return null;
+ }
+
+ return prog;
+ }
+
+ return {
+ setErrorFunc: setErrorFunc,
+
+ getWebGL: getWebGL,
+ createShaderById: createShaderById,
+ createProgramByIds: createProgramByIds,
+ };
+})();