Home | History | Annotate | Download | only in gpu
      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.
      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 {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 
     41         var commandLineParts = clientInfo.command_line.split(' ');
     42         commandLineParts.shift(); // Pop off the exe path
     43         var commandLineString = commandLineParts.join(' ')
     44 
     45         this.setTable_('client-info', [
     46           {
     47             description: 'Data exported',
     48             value: (new Date()).toLocaleString()
     49           },
     50           {
     51             description: 'Chrome version',
     52             value: clientInfo.version
     53           },
     54           {
     55             description: 'Operating system',
     56             value: clientInfo.operating_system
     57           },
     58           {
     59             description: 'Software rendering list version',
     60             value: clientInfo.blacklist_version
     61           },
     62           {
     63             description: 'Driver bug list version',
     64             value: clientInfo.driver_bug_list_version
     65           },
     66           {
     67             description: 'ANGLE commit id',
     68             value: clientInfo.angle_commit_id
     69           },
     70           {
     71             description: '2D graphics backend',
     72             value: clientInfo.graphics_backend
     73           },
     74           {
     75             description: 'Command Line Args',
     76             value: commandLineString
     77           }]);
     78       } else {
     79         this.setText_('client-info', '... loading...');
     80       }
     81 
     82       // Feature map
     83       var featureLabelMap = {
     84         '2d_canvas': 'Canvas',
     85         'gpu_compositing': 'Compositing',
     86         'webgl': 'WebGL',
     87         'multisampling': 'WebGL multisampling',
     88         'flash_3d': 'Flash',
     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       };
     98 
     99       var statusMap =  {
    100         'disabled_software': {
    101           'label': 'Software only. Hardware acceleration disabled',
    102           'class': 'feature-yellow'
    103         },
    104         'disabled_software_threaded': {
    105           'label': 'Software only, threaded. Hardware acceleration disabled',
    106           'class': 'feature-yellow'
    107         },
    108         'disabled_off': {
    109           'label': 'Disabled',
    110           'class': 'feature-red'
    111         },
    112         'disabled_off_ok': {
    113           'label': 'Disabled',
    114           'class': 'feature-yellow'
    115         },
    116         'unavailable_software': {
    117           'label': 'Software only, hardware acceleration unavailable',
    118           'class': 'feature-yellow'
    119         },
    120         'unavailable_software_threaded': {
    121           'label': 'Software only, threaded. Hardware acceleration unavailable',
    122           'class': 'feature-yellow'
    123         },
    124         'unavailable_off': {
    125           'label': 'Unavailable',
    126           'class': 'feature-red'
    127         },
    128         'unavailable_off_ok': {
    129           'label': 'Unavailable',
    130           'class': 'feature-yellow'
    131         },
    132         'enabled_readback': {
    133           'label': 'Hardware accelerated but at reduced performance',
    134           'class': 'feature-yellow'
    135         },
    136         'enabled_force': {
    137           'label': 'Hardware accelerated on all pages',
    138           'class': 'feature-green'
    139         },
    140         'enabled_threaded': {
    141           'label': 'Hardware accelerated and threaded',
    142           'class': 'feature-green'
    143         },
    144         'enabled': {
    145           'label': 'Hardware accelerated',
    146           'class': 'feature-green'
    147         },
    148         'enabled_on': {
    149           'label': 'Enabled',
    150           'class': 'feature-green'
    151         }
    152       };
    153 
    154       // GPU info, basic
    155       var diagnosticsDiv = this.querySelector('.diagnostics');
    156       var diagnosticsLoadingDiv = this.querySelector('.diagnostics-loading');
    157       var featureStatusList = this.querySelector('.feature-status-list');
    158       var problemsDiv = this.querySelector('.problems-div');
    159       var problemsList = this.querySelector('.problems-list');
    160       var workaroundsDiv = this.querySelector('.workarounds-div');
    161       var workaroundsList = this.querySelector('.workarounds-list');
    162       var performanceDiv = this.querySelector('.performance-div');
    163       var gpuInfo = browserBridge.gpuInfo;
    164       var i;
    165       if (gpuInfo) {
    166         // Not using jstemplate here for blacklist status because we construct
    167         // href from data, which jstemplate can't seem to do.
    168         if (gpuInfo.featureStatus) {
    169           // feature status list
    170           featureStatusList.textContent = '';
    171           for (var featureName in gpuInfo.featureStatus.featureStatus) {
    172             var featureStatus =
    173                 gpuInfo.featureStatus.featureStatus[featureName];
    174             var featureEl = document.createElement('li');
    175 
    176             var nameEl = document.createElement('span');
    177             if (!featureLabelMap[featureName])
    178               console.log('Missing featureLabel for', featureName);
    179             nameEl.textContent = featureLabelMap[featureName] + ': ';
    180             featureEl.appendChild(nameEl);
    181 
    182             var statusEl = document.createElement('span');
    183             var statusInfo = statusMap[featureStatus];
    184             if (!statusInfo) {
    185               console.log('Missing status for ', featureStatus);
    186               statusEl.textContent = 'Unknown';
    187               statusEl.className = 'feature-red';
    188             } else {
    189               statusEl.textContent = statusInfo['label'];
    190               statusEl.className = statusInfo['class'];
    191             }
    192             featureEl.appendChild(statusEl);
    193 
    194             featureStatusList.appendChild(featureEl);
    195           }
    196 
    197           // problems list
    198           if (gpuInfo.featureStatus.problems.length) {
    199             problemsDiv.hidden = false;
    200             problemsList.textContent = '';
    201             for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) {
    202               var problem = gpuInfo.featureStatus.problems[i];
    203               var problemEl = this.createProblemEl_(problem);
    204               problemsList.appendChild(problemEl);
    205             }
    206           } else {
    207             problemsDiv.hidden = true;
    208           }
    209 
    210           // driver bug workarounds list
    211           if (gpuInfo.featureStatus.workarounds.length) {
    212             workaroundsDiv.hidden = false;
    213             workaroundsList.textContent = '';
    214             for (i = 0; i < gpuInfo.featureStatus.workarounds.length; i++) {
    215               var workaroundEl = document.createElement('li');
    216               workaroundEl.textContent = gpuInfo.featureStatus.workarounds[i];
    217               workaroundsList.appendChild(workaroundEl);
    218             }
    219           } else {
    220             workaroundsDiv.hidden = true;
    221           }
    222 
    223         } else {
    224           featureStatusList.textContent = '';
    225           problemsList.hidden = true;
    226           workaroundsList.hidden = true;
    227         }
    228         if (gpuInfo.basic_info)
    229           this.setTable_('basic-info', gpuInfo.basic_info);
    230         else
    231           this.setTable_('basic-info', []);
    232 
    233         if (gpuInfo.performance_info) {
    234           performanceDiv.hidden = false;
    235           this.setTable_('performance-info', gpuInfo.performance_info);
    236         } else {
    237           performanceDiv.hidden = true;
    238         }
    239 
    240         if (gpuInfo.diagnostics) {
    241           diagnosticsDiv.hidden = false;
    242           diagnosticsLoadingDiv.hidden = true;
    243           $('diagnostics-table').hidden = false;
    244           this.setTable_('diagnostics-table', gpuInfo.diagnostics);
    245         } else if (gpuInfo.diagnostics === null) {
    246           // gpu_internals.cc sets diagnostics to null when it is being loaded
    247           diagnosticsDiv.hidden = false;
    248           diagnosticsLoadingDiv.hidden = false;
    249           $('diagnostics-table').hidden = true;
    250         } else {
    251           diagnosticsDiv.hidden = true;
    252         }
    253       } else {
    254         this.setText_('basic-info', '... loading ...');
    255         diagnosticsDiv.hidden = true;
    256         featureStatusList.textContent = '';
    257         problemsDiv.hidden = true;
    258       }
    259 
    260       // Log messages
    261       jstProcess(new JsEvalContext({values: browserBridge.logMessages}),
    262                  $('log-messages'));
    263     },
    264 
    265     createProblemEl_: function(problem) {
    266       var problemEl;
    267       problemEl = document.createElement('li');
    268 
    269       // Description of issue
    270       var desc = document.createElement('a');
    271       desc.textContent = problem.description;
    272       problemEl.appendChild(desc);
    273 
    274       // Spacing ':' element
    275       if (problem.crBugs.length + problem.webkitBugs.length > 0) {
    276         var tmp = document.createElement('span');
    277         tmp.textContent = ': ';
    278         problemEl.appendChild(tmp);
    279       }
    280 
    281       var nbugs = 0;
    282       var j;
    283 
    284       // crBugs
    285       for (j = 0; j < problem.crBugs.length; ++j) {
    286         if (nbugs > 0) {
    287           var tmp = document.createElement('span');
    288           tmp.textContent = ', ';
    289           problemEl.appendChild(tmp);
    290         }
    291 
    292         var link = document.createElement('a');
    293         var bugid = parseInt(problem.crBugs[j]);
    294         link.textContent = bugid;
    295         link.href = 'http://crbug.com/' + bugid;
    296         problemEl.appendChild(link);
    297         nbugs++;
    298       }
    299 
    300       for (j = 0; j < problem.webkitBugs.length; ++j) {
    301         if (nbugs > 0) {
    302           var tmp = document.createElement('span');
    303           tmp.textContent = ', ';
    304           problemEl.appendChild(tmp);
    305         }
    306 
    307         var link = document.createElement('a');
    308         var bugid = parseInt(problem.webkitBugs[j]);
    309         link.textContent = bugid;
    310 
    311         link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid;
    312         problemEl.appendChild(link);
    313         nbugs++;
    314       }
    315 
    316       if (problem.affectedGpuSettings.length > 0) {
    317         var brNode = document.createElement('br');
    318         problemEl.appendChild(brNode);
    319 
    320         var iNode = document.createElement('i');
    321         problemEl.appendChild(iNode);
    322 
    323         var headNode = document.createElement('span');
    324         if (problem.tag == 'disabledFeatures')
    325           headNode.textContent = 'Disabled Features: ';
    326         else  // problem.tag == 'workarounds'
    327           headNode.textContent = 'Applied Workarounds: ';
    328         iNode.appendChild(headNode);
    329         for (j = 0; j < problem.affectedGpuSettings.length; ++j) {
    330           if (j > 0) {
    331             var separateNode = document.createElement('span');
    332             separateNode.textContent = ', ';
    333             iNode.appendChild(separateNode);
    334           }
    335           var nameNode = document.createElement('span');
    336           if (problem.tag == 'disabledFeatures')
    337             nameNode.classList.add('feature-red');
    338           else  // problem.tag == 'workarounds'
    339             nameNode.classList.add('feature-yellow');
    340           nameNode.textContent = problem.affectedGpuSettings[j];
    341           iNode.appendChild(nameNode);
    342         }
    343       }
    344 
    345       return problemEl;
    346     },
    347 
    348     setText_: function(outputElementId, text) {
    349       var peg = document.getElementById(outputElementId);
    350       peg.textContent = text;
    351     },
    352 
    353     setTable_: function(outputElementId, inputData) {
    354       var template = jstGetTemplate('info-view-table-template');
    355       jstProcess(new JsEvalContext({value: inputData}),
    356                  template);
    357 
    358       var peg = document.getElementById(outputElementId);
    359       if (!peg)
    360         throw new Error('Node ' + outputElementId + ' not found');
    361 
    362       peg.innerHTML = '';
    363       peg.appendChild(template);
    364     }
    365   };
    366 
    367   return {
    368     InfoView: InfoView
    369   };
    370 });
    371