stat.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Generated by CoffeeScript 1.10.0
  2. (function() {
  3. var collect, loaded, wait;
  4. collect = function() {
  5. var battery, batteryManager, data, documentElement, getAntialias, getAttrib, getCaveatContext, getContext, getContextByName, getEndian, getExtensions, getParams, getShaderPrecisions, getWebglInfo, isPresent, orientation, paramNames, ref, ref1, ref2, request, screen, vendorName, vendors;
  6. vendors = [null, 'webkit', 'moz', 'ms', 'o'];
  7. vendorName = function(name, vendor) {
  8. if ((vendor != null) && vendor.length > 0) {
  9. return vendor + name[0].toUpperCase() + name.substr(1);
  10. } else {
  11. return name;
  12. }
  13. };
  14. getAttrib = function(obj, name) {
  15. var i, len, prop, vendor;
  16. if (obj != null) {
  17. for (i = 0, len = vendors.length; i < len; i++) {
  18. vendor = vendors[i];
  19. prop = vendorName(name, vendor);
  20. if (obj[prop] != null) {
  21. return obj[prop];
  22. }
  23. }
  24. }
  25. };
  26. isPresent = function(obj, name) {
  27. return getAttrib(obj, name) != null;
  28. };
  29. getShaderPrecisions = function(ctx) {
  30. var getFormat, getStageFormat;
  31. getFormat = function(stage, type) {
  32. var format;
  33. format = ctx.getShaderPrecisionFormat(stage, type);
  34. return {
  35. rangeMin: format.rangeMin,
  36. rangeMax: format.rangeMax,
  37. precision: format.precision
  38. };
  39. };
  40. getStageFormat = function(stage) {
  41. return {
  42. LOW_FLOAT: getFormat(stage, ctx.LOW_FLOAT),
  43. MEDIUM_FLOAT: getFormat(stage, ctx.MEDIUM_FLOAT),
  44. HIGH_FLOAT: getFormat(stage, ctx.HIGH_FLOAT),
  45. LOW_INT: getFormat(stage, ctx.LOW_INT),
  46. MEDIUM_INT: getFormat(stage, ctx.MEDIUM_INT),
  47. HIGH_INT: getFormat(stage, ctx.HIGH_INT)
  48. };
  49. };
  50. return {
  51. VERTEX_SHADER: getStageFormat(ctx.VERTEX_SHADER),
  52. FRAGMENT_SHADER: getStageFormat(ctx.FRAGMENT_SHADER)
  53. };
  54. };
  55. getParams = function(ctx, names) {
  56. var enumValue, i, len, name, param, paramItem, params;
  57. params = {};
  58. for (i = 0, len = names.length; i < len; i++) {
  59. name = names[i];
  60. enumValue = ctx[name];
  61. if (enumValue != null) {
  62. param = ctx.getParameter(enumValue);
  63. if (param instanceof Float32Array || param instanceof Int32Array) {
  64. params[name] = (function() {
  65. var j, len1, results;
  66. results = [];
  67. for (j = 0, len1 = param.length; j < len1; j++) {
  68. paramItem = param[j];
  69. results.push(paramItem);
  70. }
  71. return results;
  72. })();
  73. } else {
  74. params[name] = param;
  75. }
  76. }
  77. }
  78. return params;
  79. };
  80. getExtensions = function(ctx) {
  81. var capabilities, ext, extname, i, len, supported;
  82. supported = ctx.getSupportedExtensions();
  83. capabilities = {};
  84. for (i = 0, len = supported.length; i < len; i++) {
  85. extname = supported[i];
  86. if (extname.match('texture_filter_anisotropic')) {
  87. ext = ctx.getExtension(extname);
  88. capabilities[extname] = {
  89. MAX_TEXTURE_MAX_ANISOTROPY_EXT: ctx.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT)
  90. };
  91. } else if (extname.match('OES_standard_derivatives')) {
  92. ext = ctx.getExtension(extname);
  93. capabilities[extname] = {
  94. FRAGMENT_SHADER_DERIVATIVE_HINT_OES: ctx.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES)
  95. };
  96. } else if (extname.match('WEBGL_draw_buffers')) {
  97. ext = ctx.getExtension(extname);
  98. capabilities[extname] = {
  99. MAX_COLOR_ATTACHMENTS_WEBGL: ctx.getParameter(ext.MAX_COLOR_ATTACHMENTS_WEBGL),
  100. MAX_DRAW_BUFFERS_WEBGL: ctx.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL)
  101. };
  102. } else if (extname.match('WEBGL_debug_renderer_info')) {
  103. ext = ctx.getExtension(extname);
  104. if (ext != null) {
  105. capabilities[extname] = {
  106. UNMASKED_VENDOR_WEBGL: ctx.getParameter(ext.UNMASKED_VENDOR_WEBGL),
  107. UNMASKED_RENDERER_WEBGL: ctx.getParameter(ext.UNMASKED_RENDERER_WEBGL)
  108. };
  109. }
  110. } else if (extname.match('WEBGL_compressed_texture_astc')) {
  111. ext = ctx.getExtension(extname);
  112. if ((ext != null) && (ext.getSupportedProfiles != null)) {
  113. capabilities[extname] = {
  114. supportedProfiles: ext.getSupportedProfiles()
  115. };
  116. }
  117. }
  118. }
  119. return {
  120. supported: supported,
  121. capabilities: capabilities
  122. };
  123. };
  124. getContext = function(info, canvas, name, perfCaveat) {
  125. var ctx, error;
  126. if (perfCaveat == null) {
  127. perfCaveat = false;
  128. }
  129. try {
  130. ctx = canvas.getContext(name, {
  131. stencil: true,
  132. failIfMajorPerformanceCaveat: perfCaveat
  133. });
  134. if (ctx != null) {
  135. info.name = name;
  136. info.supported = true;
  137. }
  138. return ctx;
  139. } catch (error) {
  140. return null;
  141. }
  142. };
  143. getContextByName = function(info, canvas, name, perfCaveat) {
  144. var ctx;
  145. if (perfCaveat == null) {
  146. perfCaveat = false;
  147. }
  148. ctx = getContext(info, canvas, name, perfCaveat);
  149. if (ctx == null) {
  150. ctx = getContext(info, canvas, 'experimental-' + name, perfCaveat);
  151. }
  152. return ctx;
  153. };
  154. getCaveatContext = function(info, canvas, name) {
  155. var ctx;
  156. ctx = getContextByName(info, canvas, name, true);
  157. if (ctx != null) {
  158. if (ctx.getContextAttributes().failIfMajorPerformanceCaveat != null) {
  159. info.perfCaveat = false;
  160. } else {
  161. info.perfCaveat = null;
  162. }
  163. return ctx;
  164. } else {
  165. ctx = getContextByName(info, canvas, name, false);
  166. if (ctx != null) {
  167. info.perfCaveat = true;
  168. return ctx;
  169. } else {
  170. return null;
  171. }
  172. }
  173. };
  174. getAntialias = function(ctx) {
  175. return ctx.getContextAttributes().antialias;
  176. };
  177. getWebglInfo = function(name, paramNames) {
  178. var canvas, ctx, info;
  179. canvas = document.createElement('canvas');
  180. info = {
  181. supported: false
  182. };
  183. if ((canvas != null) && (canvas.getContext != null)) {
  184. ctx = getCaveatContext(info, canvas, name);
  185. if (ctx != null) {
  186. ctx.enable(ctx.SAMPLE_ALPHA_TO_COVERAGE);
  187. ctx.enable(ctx.SAMPLE_COVERAGE);
  188. info.antialias = getAntialias(ctx);
  189. info.params = getParams(ctx, paramNames);
  190. info.extensions = getExtensions(ctx);
  191. if (ctx.getShaderPrecisionFormat != null) {
  192. info.shaderPrecision = getShaderPrecisions(ctx);
  193. } else {
  194. info.shaderPrecision = null;
  195. }
  196. }
  197. }
  198. return info;
  199. };
  200. getEndian = function() {
  201. var buffer, byteView, intView;
  202. if (window.ArrayBuffer != null) {
  203. buffer = new ArrayBuffer(4);
  204. intView = new Uint32Array(buffer);
  205. byteView = new Uint8Array(buffer);
  206. intView[0] = 1;
  207. if (byteView[0] === 1) {
  208. return 'little';
  209. } else {
  210. return 'big';
  211. }
  212. } else {
  213. return 'unknown';
  214. }
  215. };
  216. paramNames = {};
  217. paramNames.webgl = 'ALIASED_LINE_WIDTH_RANGE\nALIASED_POINT_SIZE_RANGE\nALPHA_BITS\nBLUE_BITS\nDEPTH_BITS\nGREEN_BITS\nMAX_COMBINED_TEXTURE_IMAGE_UNITS\nMAX_CUBE_MAP_TEXTURE_SIZE\nMAX_FRAGMENT_UNIFORM_VECTORS\nMAX_RENDERBUFFER_SIZE\nMAX_TEXTURE_IMAGE_UNITS\nMAX_TEXTURE_SIZE\nMAX_VARYING_VECTORS\nMAX_VERTEX_ATTRIBS\nMAX_VERTEX_TEXTURE_IMAGE_UNITS\nMAX_VERTEX_UNIFORM_VECTORS\nMAX_VIEWPORT_DIMS\nRED_BITS\nSAMPLE_COVERAGE_VALUE\nSAMPLES\nSTENCIL_BITS\nSUBPIXEL_BITS\nVENDOR\nRENDERER\nVERSION\nSHADING_LANGUAGE_VERSION\nCOMPRESSED_TEXTURE_FORMATS\nSAMPLE_BUFFERS'.split('\n');
  218. paramNames.webgl2new = 'MAX_3D_TEXTURE_SIZE\nMAX_ARRAY_TEXTURE_LAYERS\nMAX_COLOR_ATTACHMENTS\nMAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS\nMAX_COMBINED_UNIFORM_BLOCKS\nMAX_COMBINED_VERTEX_UNIFORM_COMPONENTS\nMAX_DRAW_BUFFERS\nMAX_ELEMENT_INDEX\nMAX_ELEMENTS_INDICES\nMAX_ELEMENTS_VERTICES\nMAX_FRAGMENT_INPUT_COMPONENTS\nMAX_FRAGMENT_UNIFORM_BLOCKS\nMAX_FRAGMENT_UNIFORM_COMPONENTS\nMAX_PROGRAM_TEXEL_OFFSET\nMAX_SAMPLES\nMAX_SERVER_WAIT_TIMEOUT\nMAX_TEXTURE_LOD_BIAS\nMAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS\nMAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS\nMAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS\nMAX_UNIFORM_BLOCK_SIZE\nMAX_UNIFORM_BUFFER_BINDINGS\nMAX_VARYING_COMPONENTS\nMAX_VERTEX_OUTPUT_COMPONENTS\nMAX_VERTEX_UNIFORM_BLOCKS\nMAX_VERTEX_UNIFORM_COMPONENTS\nMIN_PROGRAM_TEXEL_OFFSET'.split('\n');
  219. paramNames.webgl2 = paramNames.webgl.concat(paramNames.webgl2new);
  220. screen = (ref = window.screen) != null ? ref : {};
  221. orientation = (ref1 = screen.orientation) != null ? ref1 : {};
  222. documentElement = (ref2 = document.documentElement) != null ? ref2 : {};
  223. batteryManager = getAttrib(navigator, 'battery');
  224. if (batteryManager != null) {
  225. battery = {
  226. charging: batteryManager.charging,
  227. level: batteryManager.level,
  228. chargingTime: batteryManager.chargingTime,
  229. dischargingTime: batteryManager.dischargingTime
  230. };
  231. } else {
  232. battery = null;
  233. }
  234. data = {
  235. statVersion: '4.0',
  236. endian: getEndian(),
  237. webgl: getWebglInfo('webgl', paramNames.webgl),
  238. webgl2: getWebglInfo('webgl2', paramNames.webgl2),
  239. requestAnimationFrame: isPresent(window, 'requestAnimationFrame'),
  240. fullscreen: isPresent(document, 'cancelFullScreen'),
  241. pointerlock: isPresent(document.body, 'requestPointerLock'),
  242. gamepads: isPresent(navigator, 'getGamepads'),
  243. webAudioData: isPresent(window, 'AudioContext'),
  244. websocket: isPresent(window, 'WebSocket'),
  245. webworker: isPresent(window, 'Worker'),
  246. webRTC: {
  247. support: isPresent(window, 'RTCPeerConnection'),
  248. data: isPresent(window, 'RTCDataChannelEvent')
  249. },
  250. page: {
  251. referrer: document.referrer,
  252. location: document.location.href,
  253. navigator: {
  254. doNotTrack: navigator.doNotTrack,
  255. hardwareConcurrency: navigator.hardwareConcurrency,
  256. platform: navigator.platform,
  257. vendor: navigator.vendor,
  258. maxTouchPoints: navigator.maxTouchPoints,
  259. battery: battery
  260. },
  261. document: {
  262. clientWidth: documentElement.clientWidth,
  263. clientHeight: documentElement.clientHeight
  264. },
  265. window: {
  266. innerWidth: window.innerWidth,
  267. innerHeight: window.innerHeight,
  268. outerWidth: window.outerWidth,
  269. outerHeight: window.outerHeight,
  270. devicePixelRatio: window.devicePixelRatio
  271. },
  272. screen: {
  273. availTop: screen.availTop,
  274. availLeft: screen.availLeft,
  275. availWidth: screen.availWidth,
  276. availHeight: screen.availHeight,
  277. width: screen.width,
  278. height: screen.height,
  279. colorDepth: screen.colorDepth,
  280. pixelDepth: screen.pixelDepth,
  281. orientation: {
  282. type: orientation.type,
  283. angle: orientation.angle
  284. }
  285. }
  286. }
  287. };
  288. };
  289. loaded = false;
  290. wait = function() {
  291. if (!loaded) {
  292. loaded = true;
  293. return setTimeout(collect, 1);
  294. }
  295. };
  296. if (document.readyState === 'complete') {
  297. wait();
  298. } else {
  299. if (document.addEventListener != null) {
  300. document.addEventListener('DOMContentLoaded', wait, false);
  301. window.addEventListener('load', wait, false);
  302. } else if (document.attachEvent != null) {
  303. window.attachEvent('onload', wait);
  304. } else {
  305. wait();
  306. }
  307. }
  308. }).call(this);