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 'threaded_rasterization': 'Threaded Rasterization',
97 'multiple_raster_threads': 'Multiple Raster Threads',
101 'disabled_software': {
102 'label': 'Software only. Hardware acceleration disabled',
103 'class': 'feature-yellow'
107 'class': 'feature-red'
111 'class': 'feature-yellow'
113 'unavailable_software': {
114 'label': 'Software only, hardware acceleration unavailable',
115 'class': 'feature-yellow'
118 'label': 'Unavailable',
119 'class': 'feature-red'
121 'unavailable_off_ok': {
122 'label': 'Unavailable',
123 'class': 'feature-yellow'
125 'enabled_readback': {
126 'label': 'Hardware accelerated but at reduced performance',
127 'class': 'feature-yellow'
130 'label': 'Hardware accelerated on all pages',
131 'class': 'feature-green'
134 'label': 'Hardware accelerated',
135 'class': 'feature-green'
139 'class': 'feature-green'
141 'enabled_force_on': {
142 'label': 'Force enabled',
143 'class': 'feature-green'
148 var diagnosticsDiv = this.querySelector('.diagnostics');
149 var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading');
150 var featureStatusList = this.querySelector('.feature-status-list');
151 var problemsDiv = this.querySelector('.problems-div');
152 var problemsList = this.querySelector('.problems-list');
153 var workaroundsDiv = this.querySelector('.workarounds-div');
154 var workaroundsList = this.querySelector('.workarounds-list');
155 var performanceDiv = this.querySelector('.performance-div');
156 var gpuInfo = browserBridge.gpuInfo;
159 // Not using jstemplate here for blacklist status because we construct
160 // href from data, which jstemplate can't seem to do.
161 if (gpuInfo.featureStatus) {
162 // feature status list
163 featureStatusList.textContent = '';
164 for (var featureName in gpuInfo.featureStatus.featureStatus) {
166 gpuInfo.featureStatus.featureStatus[featureName];
167 var featureEl = document.createElement('li');
169 var nameEl = document.createElement('span');
170 if (!featureLabelMap[featureName])
171 console.log('Missing featureLabel for', featureName);
172 nameEl.textContent = featureLabelMap[featureName] + ': ';
173 featureEl.appendChild(nameEl);
175 var statusEl = document.createElement('span');
176 var statusInfo = statusMap[featureStatus];
178 console.log('Missing status for ', featureStatus);
179 statusEl.textContent = 'Unknown';
180 statusEl.className = 'feature-red';
182 statusEl.textContent = statusInfo['label'];
183 statusEl.className = statusInfo['class'];
185 featureEl.appendChild(statusEl);
187 featureStatusList.appendChild(featureEl);
191 if (gpuInfo.featureStatus.problems.length) {
192 problemsDiv.hidden = false;
193 problemsList.textContent = '';
194 for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) {
195 var problem = gpuInfo.featureStatus.problems[i];
196 var problemEl = this.createProblemEl_(problem);
197 problemsList.appendChild(problemEl);
200 problemsDiv.hidden = true;
203 // driver bug workarounds list
204 if (gpuInfo.featureStatus.workarounds.length) {
205 workaroundsDiv.hidden = false;
206 workaroundsList.textContent = '';
207 for (i = 0; i < gpuInfo.featureStatus.workarounds.length; i++) {
208 var workaroundEl = document.createElement('li');
209 workaroundEl.textContent = gpuInfo.featureStatus.workarounds[i];
210 workaroundsList.appendChild(workaroundEl);
213 workaroundsDiv.hidden = true;
217 featureStatusList.textContent = '';
218 problemsList.hidden = true;
219 workaroundsList.hidden = true;
221 if (gpuInfo.basic_info)
222 this.setTable_('basic-info', gpuInfo.basic_info);
224 this.setTable_('basic-info', []);
226 if (gpuInfo.performance_info) {
227 performanceDiv.hidden = false;
228 this.setTable_('performance-info', gpuInfo.performance_info);
230 performanceDiv.hidden = true;
233 if (gpuInfo.diagnostics) {
234 diagnosticsDiv.hidden = false;
235 diagnosticsLoadingDiv.hidden = true;
236 $('diagnostics-table').hidden = false;
237 this.setTable_('diagnostics-table', gpuInfo.diagnostics);
238 } else if (gpuInfo.diagnostics === null) {
239 // gpu_internals.cc sets diagnostics to null when it is being loaded
240 diagnosticsDiv.hidden = false;
241 diagnosticsLoadingDiv.hidden = false;
242 $('diagnostics-table').hidden = true;
244 diagnosticsDiv.hidden = true;
247 this.setText_('basic-info', '... loading ...');
248 diagnosticsDiv.hidden = true;
249 featureStatusList.textContent = '';
250 problemsDiv.hidden = true;
254 jstProcess(new JsEvalContext({values: browserBridge.logMessages}),
258 createProblemEl_: function(problem) {
260 problemEl = document.createElement('li');
262 // Description of issue
263 var desc = document.createElement('a');
264 desc.textContent = problem.description;
265 problemEl.appendChild(desc);
267 // Spacing ':' element
268 if (problem.crBugs.length + problem.webkitBugs.length > 0) {
269 var tmp = document.createElement('span');
270 tmp.textContent = ': ';
271 problemEl.appendChild(tmp);
278 for (j = 0; j < problem.crBugs.length; ++j) {
280 var tmp = document.createElement('span');
281 tmp.textContent = ', ';
282 problemEl.appendChild(tmp);
285 var link = document.createElement('a');
286 var bugid = parseInt(problem.crBugs[j]);
287 link.textContent = bugid;
288 link.href = 'http://crbug.com/' + bugid;
289 problemEl.appendChild(link);
293 for (j = 0; j < problem.webkitBugs.length; ++j) {
295 var tmp = document.createElement('span');
296 tmp.textContent = ', ';
297 problemEl.appendChild(tmp);
300 var link = document.createElement('a');
301 var bugid = parseInt(problem.webkitBugs[j]);
302 link.textContent = bugid;
304 link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid;
305 problemEl.appendChild(link);
309 if (problem.affectedGpuSettings.length > 0) {
310 var brNode = document.createElement('br');
311 problemEl.appendChild(brNode);
313 var iNode = document.createElement('i');
314 problemEl.appendChild(iNode);
316 var headNode = document.createElement('span');
317 if (problem.tag == 'disabledFeatures')
318 headNode.textContent = 'Disabled Features: ';
319 else // problem.tag == 'workarounds'
320 headNode.textContent = 'Applied Workarounds: ';
321 iNode.appendChild(headNode);
322 for (j = 0; j < problem.affectedGpuSettings.length; ++j) {
324 var separateNode = document.createElement('span');
325 separateNode.textContent = ', ';
326 iNode.appendChild(separateNode);
328 var nameNode = document.createElement('span');
329 if (problem.tag == 'disabledFeatures')
330 nameNode.classList.add('feature-red');
331 else // problem.tag == 'workarounds'
332 nameNode.classList.add('feature-yellow');
333 nameNode.textContent = problem.affectedGpuSettings[j];
334 iNode.appendChild(nameNode);
341 setText_: function(outputElementId, text) {
342 var peg = document.getElementById(outputElementId);
343 peg.textContent = text;
346 setTable_: function(outputElementId, inputData) {
347 var template = jstGetTemplate('info-view-table-template');
348 jstProcess(new JsEvalContext({value: inputData}),
351 var peg = document.getElementById(outputElementId);
353 throw new Error('Node ' + outputElementId + ' not found');
356 peg.appendChild(template);