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
);