// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @fileoverview This view displays information on the current GPU * hardware. Its primary usefulness is to allow users to copy-paste * their data in an easy to read format for bug reports. */ cr.define('gpu', function() { /** * Provides information on the GPU process and underlying graphics hardware. * @constructor * @extends {Tab} */ var InfoView = cr.ui.define(gpu.Tab); InfoView.prototype = { __proto__: gpu.Tab.prototype, decorate: function() { gpu.Tab.prototype.decorate.apply(this); browserBridge.addEventListener('gpuInfoUpdate', this.refresh.bind(this)); browserBridge.addEventListener('logMessagesChange', this.refresh.bind(this)); browserBridge.addEventListener('clientInfoChange', this.refresh.bind(this)); this.refresh(); }, /** * Updates the view based on its currently known data */ refresh: function(data) { // Client info if (browserBridge.clientInfo) { var clientInfo = browserBridge.clientInfo; var chromeVersion = clientInfo.version + ' (' + clientInfo.official + ' ' + clientInfo.cl + ') ' + clientInfo.version_mod; this.setTable_('client-info', [ { description: 'Data exported', value: (new Date()).toLocaleString() }, { description: 'Chrome version', value: chromeVersion }, { description: 'Software rendering list version', value: clientInfo.blacklist_version }]); } else { this.setText_('client-info', '... loading...'); } // Feature map var featureLabelMap = { '2d_canvas': 'Canvas', '3d_css': '3D CSS', 'compositing': 'Compositing', 'webgl': 'WebGL', 'multisampling': 'WebGL multisampling' }; var statusLabelMap = { 'disabled_software': 'Software only. Hardware acceleration disabled.', 'disabled_off': 'Unavailable. Hardware acceleration disabled.', 'software': 'Software rendered. Hardware acceleration not enabled.', 'unavailable_off': 'Unavailable. Hardware acceleration unavailable', 'unavailable_software': 'Software only, hardware acceleration unavailable', 'enabled': 'Hardware accelerated' }; var statusClassMap = { 'disabled_software': 'feature-yellow', 'disabled_off': 'feature-red', 'software': 'feature-yellow', 'unavailable_off': 'feature-red', 'unavailable_software': 'feature-yellow', 'enabled': 'feature-green' }; // GPU info, basic var diagnosticsDiv = this.querySelector('.diagnostics'); var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading'); var featureStatusList = this.querySelector('.feature-status-list'); var problemsDiv = this.querySelector('.problems-div'); var problemsList = this.querySelector('.problems-list'); var gpuInfo = browserBridge.gpuInfo; var i; if (gpuInfo) { // Not using jstemplate here for blacklist status because we construct // href from data, which jstemplate can't seem to do. if (gpuInfo.featureStatus) { // feature status list featureStatusList.textContent = ''; for (i = 0; i < gpuInfo.featureStatus.featureStatus.length; i++) { var feature = gpuInfo.featureStatus.featureStatus[i]; var featureEl = document.createElement('li'); var nameEl = document.createElement('span'); if (!featureLabelMap[feature.name]) console.log('Missing featureLabel for', feature.name); nameEl.textContent = featureLabelMap[feature.name] + ': '; featureEl.appendChild(nameEl); var statusEl = document.createElement('span'); if (!statusLabelMap[feature.status]) console.log('Missing statusLabel for', feature.status); if (!statusClassMap[feature.status]) console.log('Missing statusClass for', feature.status); statusEl.textContent = statusLabelMap[feature.status]; statusEl.className = statusClassMap[feature.status]; featureEl.appendChild(statusEl); featureStatusList.appendChild(featureEl); } // problems list if (gpuInfo.featureStatus.problems.length) { problemsDiv.hidden = false; problemsList.textContent = ''; for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) { var problem = gpuInfo.featureStatus.problems[i]; var problemEl = this.createProblemEl_(problem); problemsList.appendChild(problemEl); } } else { problemsDiv.hidden = true; } } else { featureStatusList.textContent = ''; problemsList.hidden = true; } if (gpuInfo.basic_info) this.setTable_('basic-info', gpuInfo.basic_info); else this.setTable_('basic-info', []); if (gpuInfo.diagnostics) { diagnosticsDiv.hidden = false; diagnosticsLoadingDiv.hidden = true; $('diagnostics-table').hidden = false; this.setTable_('diagnostics-table', gpuInfo.diagnostics); this.querySelector('diagnostics-status').hidden = true; } else if (gpuInfo.diagnostics === null) { // gpu_internals.cc sets diagnostics to null when it is being loaded diagnosticsDiv.hidden = false; diagnosticsLoadingDiv.hidden = false; $('diagnostics-table').hidden = true; } else { diagnosticsDiv.hidden = true; } } else { this.setText_('basic-info', '... loading ...'); diagnosticsDiv.hidden = true; featureStatusList.textContent = ''; problemsDiv.hidden = true; } // Log messages jstProcess(new JsEvalContext({values: browserBridge.logMessages}), document.getElementById('log-messages')); }, createProblemEl_: function(problem) { var problemEl; problemEl = document.createElement('li'); // Description of issue var desc = document.createElement('a'); desc.textContent = problem.description; problemEl.appendChild(desc); // Spacing ':' element if (problem.crBugs.length + problem.webkitBugs.length > 0) { var tmp = document.createElement('span'); tmp.textContent = ': '; problemEl.appendChild(tmp); } var nbugs = 0; var j; // crBugs for (j = 0; j < problem.crBugs.length; ++j) { if (nbugs > 0) { var tmp = document.createElement('span'); tmp.textContent = ', '; problemEl.appendChild(tmp); } var link = document.createElement('a'); var bugid = parseInt(problem.crBugs[j]); link.textContent = bugid; link.href = 'http://crbug.com/' + bugid; problemEl.appendChild(link); nbugs++; } for (j = 0; j < problem.webkitBugs.length; ++j) { if (nbugs > 0) { var tmp = document.createElement('span'); tmp.textContent = ', '; problemEl.appendChild(tmp); } var link = document.createElement('a'); var bugid = parseInt(problem.webkitBugs[j]); link.textContent = bugid; link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid; problemEl.appendChild(link); nbugs++; } return problemEl; }, setText_: function(outputElementId, text) { var peg = document.getElementById(outputElementId); peg.innerText = text; }, setTable_: function(outputElementId, inputData) { var template = jstGetTemplate('info-view-table-template'); jstProcess(new JsEvalContext({value: inputData}), template); var peg = document.getElementById(outputElementId); if (!peg) throw new Error('Node ' + outputElementId + ' not found'); peg.innerHTML = ''; peg.appendChild(template); } }; return { InfoView: InfoView }; });