blob: e53f3a85f06d400606cd8fec3a2ddd2f897b2c2f [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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.
4
5
6/**
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.
10 */
11cr.define('gpu', function() {
12 /**
13 * Provides information on the GPU process and underlying graphics hardware.
14 * @constructor
15 * @extends {cr.ui.TabPanel}
16 */
17 var InfoView = cr.ui.define(cr.ui.TabPanel);
18
19 InfoView.prototype = {
20 __proto__: cr.ui.TabPanel.prototype,
21
22 decorate: function() {
23 cr.ui.TabPanel.prototype.decorate.apply(this);
24
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));
30 this.refresh();
31 },
32
33 /**
34 * Updates the view based on its currently known data
35 */
36 refresh: function(data) {
37 // Client info
38 if (browserBridge.clientInfo) {
39 var clientInfo = browserBridge.clientInfo;
40 this.setTable_('client-info', [
41 {
42 description: 'Data exported',
43 value: (new Date()).toLocaleString()
44 },
45 {
46 description: 'Chrome version',
47 value: clientInfo.version
48 },
49 {
50 description: 'Operating system',
51 value: clientInfo.operating_system
52 },
53 {
54 description: 'Software rendering list version',
55 value: clientInfo.blacklist_version
56 },
57 {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010058 description: 'Driver bug list version',
59 value: clientInfo.driver_bug_list_version
60 },
61 {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000062 description: 'ANGLE revision',
63 value: clientInfo.angle_revision
64 },
65 {
66 description: '2D graphics backend',
67 value: clientInfo.graphics_backend
68 }]);
69 } else {
70 this.setText_('client-info', '... loading...');
71 }
72
73 // Feature map
74 var featureLabelMap = {
75 '2d_canvas': 'Canvas',
76 '3d_css': '3D CSS',
77 'css_animation': 'CSS Animation',
78 'compositing': 'Compositing',
79 'webgl': 'WebGL',
80 'multisampling': 'WebGL multisampling',
81 'flash_3d': 'Flash 3D',
82 'flash_stage3d': 'Flash Stage3D',
83 'flash_stage3d_baseline': 'Flash Stage3D Baseline profile',
84 'texture_sharing': 'Texture Sharing',
85 'video_decode': 'Video Decode',
86 'video': 'Video',
87 // GPU Switching
88 'gpu_switching': 'GPU Switching',
89 'panel_fitting': 'Panel Fitting',
90 'force_compositing_mode': 'Force Compositing Mode',
91 'raster': 'Rasterization',
92 };
93 var statusLabelMap = {
94 'disabled_software': 'Software only. Hardware acceleration disabled.',
95 'disabled_software_animated': 'Software animated.',
96 'disabled_off': 'Unavailable. Hardware acceleration disabled.',
97 'software': 'Software rendered. Hardware acceleration not enabled.',
98 'unavailable_off': 'Unavailable. Hardware acceleration unavailable',
99 'unavailable_software':
100 'Software only, hardware acceleration unavailable',
101 'enabled_readback': 'Hardware accelerated, but at reduced performance',
102 'enabled_force': 'Hardware accelerated on all pages',
103 'enabled_threaded': 'Hardware accelerated on demand and threaded',
104 'enabled_force_threaded':
105 'Hardware accelerated on all pages and threaded',
106 'enabled': 'Hardware accelerated',
107 'accelerated': 'Accelerated',
108 'accelerated_threaded': 'Accelerated and threaded',
109 // GPU Switching
110 'gpu_switching_automatic': 'Automatic switching',
111 'gpu_switching_force_discrete': 'Always on discrete GPU',
112 'gpu_switching_force_integrated': 'Always on integrated GPU',
113 'disabled_software_multithreaded': 'Software only, multi-threaded',
114 };
115
116 var statusClassMap = {
117 'disabled_software': 'feature-yellow',
118 'disabled_software_animated': 'feature-yellow',
119 'disabled_off': 'feature-red',
120 'software': 'feature-yellow',
121 'unavailable_off': 'feature-red',
122 'unavailable_software': 'feature-yellow',
123 'enabled_force': 'feature-green',
124 'enabled_readback': 'feature-yellow',
125 'enabled_threaded': 'feature-green',
126 'enabled_force_threaded': 'feature-green',
127 'enabled': 'feature-green',
128 'accelerated': 'feature-green',
129 'accelerated_threaded': 'feature-green',
130 // GPU Switching
131 'gpu_switching_automatic': 'feature-green',
132 'gpu_switching_force_discrete': 'feature-red',
133 'gpu_switching_force_integrated': 'feature-red',
134 'disabled_software_multithreaded': 'feature-yellow',
135 };
136
137 // GPU info, basic
138 var diagnosticsDiv = this.querySelector('.diagnostics');
139 var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading');
140 var featureStatusList = this.querySelector('.feature-status-list');
141 var problemsDiv = this.querySelector('.problems-div');
142 var problemsList = this.querySelector('.problems-list');
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100143 var workaroundsDiv = this.querySelector('.workarounds-div');
144 var workaroundsList = this.querySelector('.workarounds-list');
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000145 var performanceDiv = this.querySelector('.performance-div');
146 var gpuInfo = browserBridge.gpuInfo;
147 var i;
148 if (gpuInfo) {
149 // Not using jstemplate here for blacklist status because we construct
150 // href from data, which jstemplate can't seem to do.
151 if (gpuInfo.featureStatus) {
152 // feature status list
153 featureStatusList.textContent = '';
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +0100154 for (var featureName in gpuInfo.featureStatus.featureStatus) {
155 var featureStatus =
156 gpuInfo.featureStatus.featureStatus[featureName];
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000157 var featureEl = document.createElement('li');
158
159 var nameEl = document.createElement('span');
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +0100160 if (!featureLabelMap[featureName])
161 console.log('Missing featureLabel for', featureName);
162 nameEl.textContent = featureLabelMap[featureName] + ': ';
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000163 featureEl.appendChild(nameEl);
164
165 var statusEl = document.createElement('span');
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +0100166 if (!statusLabelMap[featureStatus])
167 console.log('Missing statusLabel for', featureStatus);
168 if (!statusClassMap[featureStatus])
169 console.log('Missing statusClass for', featureStatus);
170 statusEl.textContent = statusLabelMap[featureStatus];
171 statusEl.className = statusClassMap[featureStatus];
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000172 featureEl.appendChild(statusEl);
173
174 featureStatusList.appendChild(featureEl);
175 }
176
177 // problems list
178 if (gpuInfo.featureStatus.problems.length) {
179 problemsDiv.hidden = false;
180 problemsList.textContent = '';
181 for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) {
182 var problem = gpuInfo.featureStatus.problems[i];
183 var problemEl = this.createProblemEl_(problem);
184 problemsList.appendChild(problemEl);
185 }
186 } else {
187 problemsDiv.hidden = true;
188 }
189
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100190 // driver bug workarounds list
191 if (gpuInfo.featureStatus.workarounds.length) {
192 workaroundsDiv.hidden = false;
193 workaroundsList.textContent = '';
194 for (i = 0; i < gpuInfo.featureStatus.workarounds.length; i++) {
195 var workaroundEl = document.createElement('li');
196 workaroundEl.textContent = gpuInfo.featureStatus.workarounds[i];
197 workaroundsList.appendChild(workaroundEl);
198 }
199 } else {
200 workaroundsDiv.hidden = true;
201 }
202
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000203 } else {
204 featureStatusList.textContent = '';
205 problemsList.hidden = true;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100206 workaroundsList.hidden = true;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000207 }
208 if (gpuInfo.basic_info)
209 this.setTable_('basic-info', gpuInfo.basic_info);
210 else
211 this.setTable_('basic-info', []);
212
213 if (gpuInfo.performance_info) {
214 performanceDiv.hidden = false;
215 this.setTable_('performance-info', gpuInfo.performance_info);
216 } else {
217 performanceDiv.hidden = true;
218 }
219
220 if (gpuInfo.diagnostics) {
221 diagnosticsDiv.hidden = false;
222 diagnosticsLoadingDiv.hidden = true;
223 $('diagnostics-table').hidden = false;
224 this.setTable_('diagnostics-table', gpuInfo.diagnostics);
225 } else if (gpuInfo.diagnostics === null) {
226 // gpu_internals.cc sets diagnostics to null when it is being loaded
227 diagnosticsDiv.hidden = false;
228 diagnosticsLoadingDiv.hidden = false;
229 $('diagnostics-table').hidden = true;
230 } else {
231 diagnosticsDiv.hidden = true;
232 }
233 } else {
234 this.setText_('basic-info', '... loading ...');
235 diagnosticsDiv.hidden = true;
236 featureStatusList.textContent = '';
237 problemsDiv.hidden = true;
238 }
239
240 // Log messages
241 jstProcess(new JsEvalContext({values: browserBridge.logMessages}),
242 $('log-messages'));
243 },
244
245 createProblemEl_: function(problem) {
246 var problemEl;
247 problemEl = document.createElement('li');
248
249 // Description of issue
250 var desc = document.createElement('a');
251 desc.textContent = problem.description;
252 problemEl.appendChild(desc);
253
254 // Spacing ':' element
255 if (problem.crBugs.length + problem.webkitBugs.length > 0) {
256 var tmp = document.createElement('span');
257 tmp.textContent = ': ';
258 problemEl.appendChild(tmp);
259 }
260
261 var nbugs = 0;
262 var j;
263
264 // crBugs
265 for (j = 0; j < problem.crBugs.length; ++j) {
266 if (nbugs > 0) {
267 var tmp = document.createElement('span');
268 tmp.textContent = ', ';
269 problemEl.appendChild(tmp);
270 }
271
272 var link = document.createElement('a');
273 var bugid = parseInt(problem.crBugs[j]);
274 link.textContent = bugid;
275 link.href = 'http://crbug.com/' + bugid;
276 problemEl.appendChild(link);
277 nbugs++;
278 }
279
280 for (j = 0; j < problem.webkitBugs.length; ++j) {
281 if (nbugs > 0) {
282 var tmp = document.createElement('span');
283 tmp.textContent = ', ';
284 problemEl.appendChild(tmp);
285 }
286
287 var link = document.createElement('a');
288 var bugid = parseInt(problem.webkitBugs[j]);
289 link.textContent = bugid;
290
291 link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid;
292 problemEl.appendChild(link);
293 nbugs++;
294 }
295
296 return problemEl;
297 },
298
299 setText_: function(outputElementId, text) {
300 var peg = document.getElementById(outputElementId);
301 peg.textContent = text;
302 },
303
304 setTable_: function(outputElementId, inputData) {
305 var template = jstGetTemplate('info-view-table-template');
306 jstProcess(new JsEvalContext({value: inputData}),
307 template);
308
309 var peg = document.getElementById(outputElementId);
310 if (!peg)
311 throw new Error('Node ' + outputElementId + ' not found');
312
313 peg.innerHTML = '';
314 peg.appendChild(template);
315 }
316 };
317
318 return {
319 InfoView: InfoView
320 };
321});