• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2011 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 {Tab}
16   */
17  var InfoView = cr.ui.define(gpu.Tab);
18
19  InfoView.prototype = {
20    __proto__: gpu.Tab.prototype,
21
22    decorate: function() {
23      gpu.Tab.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        var chromeVersion = clientInfo.version +
41            ' (' + clientInfo.official +
42            ' ' + clientInfo.cl +
43            ') ' + clientInfo.version_mod;
44        this.setTable_('client-info', [
45          {
46            description: 'Data exported',
47            value: (new Date()).toLocaleString()
48          },
49          {
50            description: 'Chrome version',
51            value: chromeVersion
52          },
53          {
54            description: 'Software rendering list version',
55            value: clientInfo.blacklist_version
56          }]);
57      } else {
58        this.setText_('client-info', '... loading...');
59      }
60
61      // Feature map
62      var featureLabelMap = {
63        '2d_canvas': 'Canvas',
64        '3d_css': '3D CSS',
65        'compositing': 'Compositing',
66        'webgl': 'WebGL',
67        'multisampling': 'WebGL multisampling'
68      };
69      var statusLabelMap = {
70        'disabled_software': 'Software only. Hardware acceleration disabled.',
71        'disabled_off': 'Unavailable. Hardware acceleration disabled.',
72        'software': 'Software rendered. Hardware acceleration not enabled.',
73        'unavailable_off': 'Unavailable. Hardware acceleration unavailable',
74        'unavailable_software':
75            'Software only, hardware acceleration unavailable',
76        'enabled': 'Hardware accelerated'
77      };
78      var statusClassMap = {
79        'disabled_software': 'feature-yellow',
80        'disabled_off': 'feature-red',
81        'software': 'feature-yellow',
82        'unavailable_off': 'feature-red',
83        'unavailable_software': 'feature-yellow',
84        'enabled': 'feature-green'
85      };
86
87      // GPU info, basic
88      var diagnosticsDiv = this.querySelector('.diagnostics');
89      var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading');
90      var featureStatusList = this.querySelector('.feature-status-list');
91      var problemsDiv = this.querySelector('.problems-div');
92      var problemsList = this.querySelector('.problems-list');
93      var gpuInfo = browserBridge.gpuInfo;
94      var i;
95      if (gpuInfo) {
96        // Not using jstemplate here for blacklist status because we construct
97        // href from data, which jstemplate can't seem to do.
98        if (gpuInfo.featureStatus) {
99          // feature status list
100          featureStatusList.textContent = '';
101          for (i = 0; i < gpuInfo.featureStatus.featureStatus.length;
102               i++) {
103            var feature = gpuInfo.featureStatus.featureStatus[i];
104            var featureEl = document.createElement('li');
105
106            var nameEl = document.createElement('span');
107            if (!featureLabelMap[feature.name])
108              console.log('Missing featureLabel for', feature.name);
109            nameEl.textContent = featureLabelMap[feature.name] + ': ';
110            featureEl.appendChild(nameEl);
111
112            var statusEl = document.createElement('span');
113            if (!statusLabelMap[feature.status])
114              console.log('Missing statusLabel for', feature.status);
115            if (!statusClassMap[feature.status])
116              console.log('Missing statusClass for', feature.status);
117            statusEl.textContent = statusLabelMap[feature.status];
118            statusEl.className = statusClassMap[feature.status];
119            featureEl.appendChild(statusEl);
120
121            featureStatusList.appendChild(featureEl);
122          }
123
124          // problems list
125          if (gpuInfo.featureStatus.problems.length) {
126            problemsDiv.hidden = false;
127            problemsList.textContent = '';
128            for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) {
129              var problem = gpuInfo.featureStatus.problems[i];
130              var problemEl = this.createProblemEl_(problem);
131              problemsList.appendChild(problemEl);
132            }
133          } else {
134            problemsDiv.hidden = true;
135          }
136
137        } else {
138          featureStatusList.textContent = '';
139          problemsList.hidden = true;
140        }
141        if (gpuInfo.basic_info)
142          this.setTable_('basic-info', gpuInfo.basic_info);
143        else
144          this.setTable_('basic-info', []);
145
146        if (gpuInfo.diagnostics) {
147          diagnosticsDiv.hidden = false;
148          diagnosticsLoadingDiv.hidden = true;
149          $('diagnostics-table').hidden = false;
150          this.setTable_('diagnostics-table', gpuInfo.diagnostics);
151          this.querySelector('diagnostics-status').hidden = true;
152        } else if (gpuInfo.diagnostics === null) {
153          // gpu_internals.cc sets diagnostics to null when it is being loaded
154          diagnosticsDiv.hidden = false;
155          diagnosticsLoadingDiv.hidden = false;
156          $('diagnostics-table').hidden = true;
157        } else {
158          diagnosticsDiv.hidden = true;
159        }
160      } else {
161        this.setText_('basic-info', '... loading ...');
162        diagnosticsDiv.hidden = true;
163        featureStatusList.textContent = '';
164        problemsDiv.hidden = true;
165      }
166
167      // Log messages
168      jstProcess(new JsEvalContext({values: browserBridge.logMessages}),
169                 document.getElementById('log-messages'));
170    },
171
172    createProblemEl_: function(problem) {
173      var problemEl;
174      problemEl = document.createElement('li');
175
176      // Description of issue
177      var desc = document.createElement('a');
178      desc.textContent = problem.description;
179      problemEl.appendChild(desc);
180
181      // Spacing ':' element
182      if (problem.crBugs.length + problem.webkitBugs.length > 0) {
183        var tmp = document.createElement('span');
184        tmp.textContent = ': ';
185        problemEl.appendChild(tmp);
186      }
187
188      var nbugs = 0;
189      var j;
190
191      // crBugs
192      for (j = 0; j < problem.crBugs.length; ++j) {
193        if (nbugs > 0) {
194          var tmp = document.createElement('span');
195          tmp.textContent = ', ';
196          problemEl.appendChild(tmp);
197        }
198
199        var link = document.createElement('a');
200        var bugid = parseInt(problem.crBugs[j]);
201        link.textContent = bugid;
202        link.href = 'http://crbug.com/' + bugid;
203        problemEl.appendChild(link);
204        nbugs++;
205      }
206
207      for (j = 0; j < problem.webkitBugs.length; ++j) {
208        if (nbugs > 0) {
209          var tmp = document.createElement('span');
210          tmp.textContent = ', ';
211          problemEl.appendChild(tmp);
212        }
213
214        var link = document.createElement('a');
215        var bugid = parseInt(problem.webkitBugs[j]);
216        link.textContent = bugid;
217
218        link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid;
219        problemEl.appendChild(link);
220        nbugs++;
221      }
222
223      return problemEl;
224    },
225
226    setText_: function(outputElementId, text) {
227      var peg = document.getElementById(outputElementId);
228      peg.innerText = text;
229    },
230
231    setTable_: function(outputElementId, inputData) {
232      var template = jstGetTemplate('info-view-table-template');
233      jstProcess(new JsEvalContext({value: inputData}),
234                 template);
235
236      var peg = document.getElementById(outputElementId);
237      if (!peg)
238        throw new Error('Node ' + outputElementId + ' not found');
239
240      peg.innerHTML = '';
241      peg.appendChild(template);
242    }
243  };
244
245  return {
246    InfoView: InfoView
247  };
248});
249