// Copyright (c) 2012 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 {cr.ui.TabPanel}
*/
var InfoView = cr.ui.define(cr.ui.TabPanel);
InfoView.prototype = {
__proto__: cr.ui.TabPanel.prototype,
decorate: function() {
cr.ui.TabPanel.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 commandLineParts = clientInfo.command_line.split(' ');
commandLineParts.shift(); // Pop off the exe path
var commandLineString = commandLineParts.join(' ')
this.setTable_('client-info', [
{
description: 'Data exported',
value: (new Date()).toLocaleString()
},
{
description: 'Chrome version',
value: clientInfo.version
},
{
description: 'Operating system',
value: clientInfo.operating_system
},
{
description: 'Software rendering list version',
value: clientInfo.blacklist_version
},
{
description: 'Driver bug list version',
value: clientInfo.driver_bug_list_version
},
{
description: 'ANGLE commit id',
value: clientInfo.angle_commit_id
},
{
description: '2D graphics backend',
value: clientInfo.graphics_backend
},
{
description: 'Command Line Args',
value: commandLineString
}]);
} else {
this.setText_('client-info', '... loading...');
}
// Feature map
var featureLabelMap = {
'2d_canvas': 'Canvas',
'gpu_compositing': 'Compositing',
'webgl': 'WebGL',
'multisampling': 'WebGL multisampling',
'flash_3d': 'Flash',
'flash_stage3d': 'Flash Stage3D',
'flash_stage3d_baseline': 'Flash Stage3D Baseline profile',
'texture_sharing': 'Texture Sharing',
'video_decode': 'Video Decode',
'video_encode': 'Video Encode',
'panel_fitting': 'Panel Fitting',
'rasterization': 'Rasterization',
'threaded_rasterization': 'Threaded Rasterization',
'multiple_raster_threads': 'Multiple Raster Threads',
};
var statusMap = {
'disabled_software': {
'label': 'Software only. Hardware acceleration disabled',
'class': 'feature-yellow'
},
'disabled_off': {
'label': 'Disabled',
'class': 'feature-red'
},
'disabled_off_ok': {
'label': 'Disabled',
'class': 'feature-yellow'
},
'unavailable_software': {
'label': 'Software only, hardware acceleration unavailable',
'class': 'feature-yellow'
},
'unavailable_off': {
'label': 'Unavailable',
'class': 'feature-red'
},
'unavailable_off_ok': {
'label': 'Unavailable',
'class': 'feature-yellow'
},
'enabled_readback': {
'label': 'Hardware accelerated but at reduced performance',
'class': 'feature-yellow'
},
'enabled_force': {
'label': 'Hardware accelerated on all pages',
'class': 'feature-green'
},
'enabled': {
'label': 'Hardware accelerated',
'class': 'feature-green'
},
'enabled_on': {
'label': 'Enabled',
'class': 'feature-green'
},
'enabled_force_on': {
'label': 'Force enabled',
'class': '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 workaroundsDiv = this.querySelector('.workarounds-div');
var workaroundsList = this.querySelector('.workarounds-list');
var performanceDiv = this.querySelector('.performance-div');
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 (var featureName in gpuInfo.featureStatus.featureStatus) {
var featureStatus =
gpuInfo.featureStatus.featureStatus[featureName];
var featureEl = document.createElement('li');
var nameEl = document.createElement('span');
if (!featureLabelMap[featureName])
console.log('Missing featureLabel for', featureName);
nameEl.textContent = featureLabelMap[featureName] + ': ';
featureEl.appendChild(nameEl);
var statusEl = document.createElement('span');
var statusInfo = statusMap[featureStatus];
if (!statusInfo) {
console.log('Missing status for ', featureStatus);
statusEl.textContent = 'Unknown';
statusEl.className = 'feature-red';
} else {
statusEl.textContent = statusInfo['label'];
statusEl.className = statusInfo['class'];
}
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;
}
// driver bug workarounds list
if (gpuInfo.featureStatus.workarounds.length) {
workaroundsDiv.hidden = false;
workaroundsList.textContent = '';
for (i = 0; i < gpuInfo.featureStatus.workarounds.length; i++) {
var workaroundEl = document.createElement('li');
workaroundEl.textContent = gpuInfo.featureStatus.workarounds[i];
workaroundsList.appendChild(workaroundEl);
}
} else {
workaroundsDiv.hidden = true;
}
} else {
featureStatusList.textContent = '';
problemsList.hidden = true;
workaroundsList.hidden = true;
}
if (gpuInfo.basic_info)
this.setTable_('basic-info', gpuInfo.basic_info);
else
this.setTable_('basic-info', []);
if (gpuInfo.performance_info) {
performanceDiv.hidden = false;
this.setTable_('performance-info', gpuInfo.performance_info);
} else {
performanceDiv.hidden = true;
}
if (gpuInfo.diagnostics) {
diagnosticsDiv.hidden = false;
diagnosticsLoadingDiv.hidden = true;
$('diagnostics-table').hidden = false;
this.setTable_('diagnostics-table', gpuInfo.diagnostics);
} 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}),
$('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++;
}
if (problem.affectedGpuSettings.length > 0) {
var brNode = document.createElement('br');
problemEl.appendChild(brNode);
var iNode = document.createElement('i');
problemEl.appendChild(iNode);
var headNode = document.createElement('span');
if (problem.tag == 'disabledFeatures')
headNode.textContent = 'Disabled Features: ';
else // problem.tag == 'workarounds'
headNode.textContent = 'Applied Workarounds: ';
iNode.appendChild(headNode);
for (j = 0; j < problem.affectedGpuSettings.length; ++j) {
if (j > 0) {
var separateNode = document.createElement('span');
separateNode.textContent = ', ';
iNode.appendChild(separateNode);
}
var nameNode = document.createElement('span');
if (problem.tag == 'disabledFeatures')
nameNode.classList.add('feature-red');
else // problem.tag == 'workarounds'
nameNode.classList.add('feature-yellow');
nameNode.textContent = problem.affectedGpuSettings[j];
iNode.appendChild(nameNode);
}
}
return problemEl;
},
setText_: function(outputElementId, text) {
var peg = document.getElementById(outputElementId);
peg.textContent = 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
};
});