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