michael@0: DriverInfo = (function() { michael@0: // --------------------------------------------------------------------------- michael@0: // Debug info handling michael@0: michael@0: function defaultInfoFunc(str) { michael@0: console.log('Info: ' + str); michael@0: } michael@0: michael@0: var gInfoFunc = defaultInfoFunc; michael@0: function setInfoFunc(func) { michael@0: gInfoFunc = func; michael@0: } michael@0: michael@0: function info(str) { michael@0: gInfoFunc(str); michael@0: } michael@0: michael@0: // --------------------------------------------------------------------------- michael@0: // OS and driver identification michael@0: // Stolen from content/canvas/test/webgl/test_webgl_conformance_test_suite.html michael@0: function detectDriverInfo() { michael@0: try { michael@0: var cc = SpecialPowers.Cc; michael@0: } catch (e) { michael@0: throw 'No SpecialPowers!'; michael@0: } michael@0: michael@0: const Cc = SpecialPowers.Cc; michael@0: const Ci = SpecialPowers.Ci; michael@0: var doc = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser).parseFromString("", "text/html"); michael@0: michael@0: var canvas = doc.createElement("canvas"); michael@0: canvas.width = 1; michael@0: canvas.height = 1; michael@0: michael@0: var type = ""; michael@0: var gl = null; michael@0: try { michael@0: gl = canvas.getContext("experimental-webgl"); michael@0: } catch(e) {} michael@0: michael@0: if (!gl) { michael@0: info('Failed to create WebGL context for querying driver info.'); michael@0: throw 'WebGL failed'; michael@0: } michael@0: michael@0: var ext = gl.getExtension("WEBGL_debug_renderer_info"); michael@0: // this extension is unconditionally available to chrome. No need to check. michael@0: michael@0: var webglRenderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); michael@0: var webglVendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); michael@0: return [webglVendor, webglRenderer]; michael@0: } michael@0: michael@0: function detectOSInfo() { michael@0: try { michael@0: var cc = SpecialPowers.Cc; michael@0: } catch (e) { michael@0: throw 'No SpecialPowers!'; michael@0: } michael@0: michael@0: const Cc = SpecialPowers.Cc; michael@0: const Ci = SpecialPowers.Ci; michael@0: michael@0: // From reftest.js: michael@0: var runtime = Cc['@mozilla.org/xre/app-info;1'].getService(Ci.nsIXULRuntime); michael@0: michael@0: var os = null; michael@0: var version = null; michael@0: if (navigator.platform.indexOf('Win') == 0) { michael@0: os = OS.WINDOWS; michael@0: michael@0: // code borrowed from browser/modules/test/browser_taskbar_preview.js michael@0: version = SpecialPowers.Services.sysinfo.getProperty('version'); michael@0: version = parseFloat(version); michael@0: // Version 6.0 is Vista, 6.1 is 7. michael@0: michael@0: } else if (navigator.platform.indexOf('Mac') == 0) { michael@0: os = OS.MAC; michael@0: michael@0: var versionMatch = /Mac OS X (\d+.\d+)/.exec(navigator.userAgent); michael@0: version = versionMatch ? parseFloat(versionMatch[1]) : null; michael@0: michael@0: } else if (runtime.widgetToolkit == 'gonk') { michael@0: os = OS.B2G; michael@0: michael@0: } else if (navigator.appVersion.indexOf('Android') != -1) { michael@0: os = OS.ANDROID; michael@0: // From layout/tools/reftest/reftest.js: michael@0: version = SpecialPowers.Services.sysinfo.getProperty('version'); michael@0: michael@0: } else if (navigator.platform.indexOf('Linux') == 0) { michael@0: // Must be checked after android, as android also has a 'Linux' platform string. michael@0: os = OS.LINUX; michael@0: } michael@0: michael@0: return [os, version]; michael@0: } michael@0: michael@0: var OS = { michael@0: WINDOWS: 'windows', michael@0: MAC: 'mac', michael@0: LINUX: 'linux', michael@0: ANDROID: 'android', michael@0: B2G: 'b2g', michael@0: }; michael@0: michael@0: var DRIVER = { michael@0: MESA: 'mesa', michael@0: NVIDIA: 'nvidia', michael@0: ANDROID_X86_EMULATOR: 'android x86 emulator', michael@0: ANGLE: 'angle', michael@0: }; michael@0: michael@0: var kOS = null; michael@0: var kOSVersion = null; michael@0: var kDriver = null; michael@0: michael@0: try { michael@0: [kOS, kOSVersion] = detectOSInfo(); michael@0: } catch (e) { michael@0: // Generally just fails when we don't have SpecialPowers. michael@0: } michael@0: michael@0: try { michael@0: var glVendor, glRenderer; michael@0: [glVendor, glRenderer] = detectDriverInfo(); michael@0: info('GL vendor: ' + glVendor); michael@0: info('GL renderer: ' + glRenderer); michael@0: michael@0: if (glRenderer.contains('llvmpipe')) { michael@0: kDriver = DRIVER.MESA; michael@0: } else if (glRenderer.contains('Android Emulator')) { michael@0: kDriver = DRIVER.ANDROID_X86_EMULATOR; michael@0: } else if (glRenderer.contains('ANGLE')) { michael@0: kDriver = DRIVER.ANGLE; michael@0: } else if (glVendor.contains('NVIDIA')) { michael@0: kDriver = DRIVER.NVIDIA; michael@0: } michael@0: } catch (e) { michael@0: // detectDriverInfo is fallible where WebGL fails. michael@0: } michael@0: michael@0: if (kOS) { michael@0: info('OS detected as: ' + kOS); michael@0: info(' Version: ' + kOSVersion); michael@0: } else { michael@0: info('OS not detected.'); michael@0: info(' `platform`: ' + navigator.platform); michael@0: info(' `appVersion`: ' + navigator.appVersion); michael@0: info(' `userAgent`: ' + navigator.userAgent); michael@0: } michael@0: if (kDriver) { michael@0: info('GL driver detected as: ' + kDriver); michael@0: } else { michael@0: info('GL driver not detected.'); michael@0: } michael@0: michael@0: return { michael@0: setInfoFunc: setInfoFunc, michael@0: michael@0: OS: OS, michael@0: DRIVER: DRIVER, michael@0: getOS: function() { return kOS; }, michael@0: getDriver: function() { return kDriver; }, michael@0: getOSVersion: function() { return kOSVersion; }, michael@0: }; michael@0: })(); michael@0: