Home | History | Annotate | Download | only in gpu_internals
      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  */
     11 cr.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