1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * @fileoverview This view displays information on the current GPU
8 * hardware. Its primary usefulness is to allow users to copy-paste
9 * their data in an easy to read format for bug reports.
11 cr.define('gpu', function() {
13 * Provides information on the GPU process and underlying graphics hardware.
15 * @extends {cr.ui.TabPanel}
17 var InfoView = cr.ui.define(cr.ui.TabPanel);
19 InfoView.prototype = {
20 __proto__: cr.ui.TabPanel.prototype,
22 decorate: function() {
23 cr.ui.TabPanel.prototype.decorate.apply(this);
25 browserBridge.addEventListener('gpuInfoUpdate', this.refresh.bind(this));
26 browserBridge.addEventListener('logMessagesChange',
27 this.refresh.bind(this));
28 browserBridge.addEventListener('clientInfoChange',
29 this.refresh.bind(this));
34 * Updates the view based on its currently known data
36 refresh: function(data) {
38 if (browserBridge.clientInfo) {
39 var clientInfo = browserBridge.clientInfo;
41 var commandLineParts = clientInfo.command_line.split(' ');
42 commandLineParts.shift(); // Pop off the exe path
43 var commandLineString = commandLineParts.join(' ')
45 this.setTable_('client-info', [
47 description: 'Data exported',
48 value: (new Date()).toLocaleString()
51 description: 'Chrome version',
52 value: clientInfo.version
55 description: 'Operating system',
56 value: clientInfo.operating_system
59 description: 'Software rendering list version',
60 value: clientInfo.blacklist_version
63 description: 'Driver bug list version',
64 value: clientInfo.driver_bug_list_version
67 description: 'ANGLE commit id',
68 value: clientInfo.angle_commit_id
71 description: '2D graphics backend',
72 value: clientInfo.graphics_backend
75 description: 'Command Line Args',
76 value: commandLineString
79 this.setText_('client-info', '... loading...');
83 var featureLabelMap = {
84 '2d_canvas': 'Canvas',
85 'gpu_compositing': 'Compositing',
87 'multisampling': 'WebGL multisampling',
89 'flash_stage3d': 'Flash Stage3D',
90 'flash_stage3d_baseline': 'Flash Stage3D Baseline profile',
91 'texture_sharing': 'Texture Sharing',
92 'video_decode': 'Video Decode',
93 'video_encode': 'Video Encode',
94 'panel_fitting': 'Panel Fitting',
95 'rasterization': 'Rasterization',
96 'multiple_raster_threads': 'Multiple Raster Threads',
100 'disabled_software': {
101 'label': 'Software only. Hardware acceleration disabled',
102 'class': 'feature-yellow'
106 'class': 'feature-red'
110 'class': 'feature-yellow'
112 'unavailable_software': {
113 'label': 'Software only, hardware acceleration unavailable',
114 'class': 'feature-yellow'
117 'label': 'Unavailable',
118 'class': 'feature-red'
120 'unavailable_off_ok': {
121 'label': 'Unavailable',
122 'class': 'feature-yellow'
124 'enabled_readback': {
125 'label': 'Hardware accelerated but at reduced performance',
126 'class': 'feature-yellow'
129 'label': 'Hardware accelerated on all pages',
130 'class': 'feature-green'
133 'label': 'Hardware accelerated',
134 'class': 'feature-green'
138 'class': 'feature-green'
140 'enabled_force_on': {
141 'label': 'Force enabled',
142 'class': 'feature-green'
147 var diagnosticsDiv = this.querySelector('.diagnostics');
148 var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading');
149 var featureStatusList = this.querySelector('.feature-status-list');
150 var problemsDiv = this.querySelector('.problems-div');
151 var problemsList = this.querySelector('.problems-list');
152 var workaroundsDiv = this.querySelector('.workarounds-div');
153 var workaroundsList = this.querySelector('.workarounds-list');
154 var gpuInfo = browserBridge.gpuInfo;
157 // Not using jstemplate here for blacklist status because we construct
158 // href from data, which jstemplate can't seem to do.
159 if (gpuInfo.featureStatus) {
160 // feature status list
161 featureStatusList.textContent = '';
162 for (var featureName in gpuInfo.featureStatus.featureStatus) {
164 gpuInfo.featureStatus.featureStatus[featureName];
165 var featureEl = document.createElement('li');
167 var nameEl = document.createElement('span');
168 if (!featureLabelMap[featureName])
169 console.log('Missing featureLabel for', featureName);
170 nameEl.textContent = featureLabelMap[featureName] + ': ';
171 featureEl.appendChild(nameEl);
173 var statusEl = document.createElement('span');
174 var statusInfo = statusMap[featureStatus];
176 console.log('Missing status for ', featureStatus);
177 statusEl.textContent = 'Unknown';
178 statusEl.className = 'feature-red';
180 statusEl.textContent = statusInfo['label'];
181 statusEl.className = statusInfo['class'];
183 featureEl.appendChild(statusEl);
185 featureStatusList.appendChild(featureEl);
189 if (gpuInfo.featureStatus.problems.length) {
190 problemsDiv.hidden = false;
191 problemsList.textContent = '';
192 for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) {
193 var problem = gpuInfo.featureStatus.problems[i];
194 var problemEl = this.createProblemEl_(problem);
195 problemsList.appendChild(problemEl);
198 problemsDiv.hidden = true;
201 // driver bug workarounds list
202 if (gpuInfo.featureStatus.workarounds.length) {
203 workaroundsDiv.hidden = false;
204 workaroundsList.textContent = '';
205 for (i = 0; i < gpuInfo.featureStatus.workarounds.length; i++) {
206 var workaroundEl = document.createElement('li');
207 workaroundEl.textContent = gpuInfo.featureStatus.workarounds[i];
208 workaroundsList.appendChild(workaroundEl);
211 workaroundsDiv.hidden = true;
215 featureStatusList.textContent = '';
216 problemsList.hidden = true;
217 workaroundsList.hidden = true;
219 if (gpuInfo.basic_info)
220 this.setTable_('basic-info', gpuInfo.basic_info);
222 this.setTable_('basic-info', []);
224 if (gpuInfo.diagnostics) {
225 diagnosticsDiv.hidden = false;
226 diagnosticsLoadingDiv.hidden = true;
227 $('diagnostics-table').hidden = false;
228 this.setTable_('diagnostics-table', gpuInfo.diagnostics);
229 } else if (gpuInfo.diagnostics === null) {
230 // gpu_internals.cc sets diagnostics to null when it is being loaded
231 diagnosticsDiv.hidden = false;
232 diagnosticsLoadingDiv.hidden = false;
233 $('diagnostics-table').hidden = true;
235 diagnosticsDiv.hidden = true;
238 this.setText_('basic-info', '... loading ...');
239 diagnosticsDiv.hidden = true;
240 featureStatusList.textContent = '';
241 problemsDiv.hidden = true;
245 jstProcess(new JsEvalContext({values: browserBridge.logMessages}),
249 createProblemEl_: function(problem) {
251 problemEl = document.createElement('li');
253 // Description of issue
254 var desc = document.createElement('a');
255 desc.textContent = problem.description;
256 problemEl.appendChild(desc);
258 // Spacing ':' element
259 if (problem.crBugs.length + problem.webkitBugs.length > 0) {
260 var tmp = document.createElement('span');
261 tmp.textContent = ': ';
262 problemEl.appendChild(tmp);
269 for (j = 0; j < problem.crBugs.length; ++j) {
271 var tmp = document.createElement('span');
272 tmp.textContent = ', ';
273 problemEl.appendChild(tmp);
276 var link = document.createElement('a');
277 var bugid = parseInt(problem.crBugs[j]);
278 link.textContent = bugid;
279 link.href = 'http://crbug.com/' + bugid;
280 problemEl.appendChild(link);
284 for (j = 0; j < problem.webkitBugs.length; ++j) {
286 var tmp = document.createElement('span');
287 tmp.textContent = ', ';
288 problemEl.appendChild(tmp);
291 var link = document.createElement('a');
292 var bugid = parseInt(problem.webkitBugs[j]);
293 link.textContent = bugid;
295 link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid;
296 problemEl.appendChild(link);
300 if (problem.affectedGpuSettings.length > 0) {
301 var brNode = document.createElement('br');
302 problemEl.appendChild(brNode);
304 var iNode = document.createElement('i');
305 problemEl.appendChild(iNode);
307 var headNode = document.createElement('span');
308 if (problem.tag == 'disabledFeatures')
309 headNode.textContent = 'Disabled Features: ';
310 else // problem.tag == 'workarounds'
311 headNode.textContent = 'Applied Workarounds: ';
312 iNode.appendChild(headNode);
313 for (j = 0; j < problem.affectedGpuSettings.length; ++j) {
315 var separateNode = document.createElement('span');
316 separateNode.textContent = ', ';
317 iNode.appendChild(separateNode);
319 var nameNode = document.createElement('span');
320 if (problem.tag == 'disabledFeatures')
321 nameNode.classList.add('feature-red');
322 else // problem.tag == 'workarounds'
323 nameNode.classList.add('feature-yellow');
324 nameNode.textContent = problem.affectedGpuSettings[j];
325 iNode.appendChild(nameNode);
332 setText_: function(outputElementId, text) {
333 var peg = document.getElementById(outputElementId);
334 peg.textContent = text;
337 setTable_: function(outputElementId, inputData) {
338 var template = jstGetTemplate('info-view-table-template');
339 jstProcess(new JsEvalContext({value: inputData}),
342 var peg = document.getElementById(outputElementId);
344 throw new Error('Node ' + outputElementId + ' not found');
347 peg.appendChild(template);