1<!DOCTYPE html> 2<!-- 3Copyright (c) 2013 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7<link rel="import" href="/tracing/extras/chrome/cc/raster_task.html"> 8<link rel="import" href="/tracing/model/event_set.html"> 9<link rel="import" href="/tracing/ui/analysis/analysis_sub_view.html"> 10<link rel="import" href="/tracing/ui/base/table.html"> 11<link rel="import" href="/tracing/ui/extras/chrome/cc/selection.html"> 12<link rel="import" href="/tracing/value/ui/scalar_span.html"> 13<link rel="import" href="/tracing/value/unit.html"> 14 15<polymer-element name="tr-ui-e-chrome-cc-raster-task-view"> 16 <template> 17 <style> 18 :host { 19 display: flex; 20 flex-direction: column; 21 } 22 #heading { 23 flex: 0 0 auto; 24 } 25 </style> 26 27 <div id="heading"> 28 Rasterization costs in 29 <tr-ui-a-analysis-link id="link"></tr-ui-a-analysis-link> 30 </div> 31 <tr-ui-b-table id="content"></tr-ui-b-table> 32 </template> 33 34 <script> 35 'use strict'; 36 Polymer({ 37 created: function() { 38 this.selection_ = undefined; 39 }, 40 41 set selection(selection) { 42 this.selection_ = selection; 43 44 this.updateContents_(); 45 }, 46 47 updateColumns_: function(hadCpuDurations) { 48 var timeSpanConfig = { 49 unit: tr.v.Unit.byName.timeDurationInMs, 50 ownerDocument: this.ownerDocument 51 }; 52 53 var columns = [ 54 { 55 title: 'Layer', 56 value: function(row) { 57 if (row.isTotals) 58 return 'Totals'; 59 if (row.layer) { 60 var linkEl = document.createElement('tr-ui-a-analysis-link'); 61 linkEl.setSelectionAndContent( 62 function() { 63 return new tr.ui.e.chrome.cc.LayerSelection(costs.layer); 64 }, 65 'Layer ' + row.layerId); 66 return linkEl; 67 } else { 68 return 'Layer ' + row.layerId; 69 } 70 }, 71 width: '250px' 72 }, 73 { 74 title: 'Num Tiles', 75 value: function(row) { return row.numTiles; }, 76 cmp: function(a, b) { return a.numTiles - b.numTiles; } 77 }, 78 { 79 title: 'Num Analysis Tasks', 80 value: function(row) { return row.numAnalysisTasks; }, 81 cmp: function(a, b) { 82 return a.numAnalysisTasks - b.numAnalysisTasks; 83 } 84 }, 85 { 86 title: 'Num Raster Tasks', 87 value: function(row) { return row.numRasterTasks; }, 88 cmp: function(a, b) { return a.numRasterTasks - b.numRasterTasks; } 89 }, 90 { 91 title: 'Wall Duration (ms)', 92 value: function(row) { 93 return tr.v.ui.createScalarSpan(row.duration, timeSpanConfig); 94 }, 95 cmp: function(a, b) { return a.duration - b.duration; } 96 } 97 ]; 98 99 if (hadCpuDurations) { 100 columns.push({ 101 title: 'CPU Duration (ms)', 102 value: function(row) { 103 return tr.v.ui.createScalarSpan(row.cpuDuration, timeSpanConfig); 104 }, 105 cmp: function(a, b) { return a.cpuDuration - b.cpuDuration; } 106 }); 107 } 108 109 var colWidthPercentage; 110 if (columns.length == 1) 111 colWidthPercentage = '100%'; 112 else 113 colWidthPercentage = (100 / (columns.length - 1)).toFixed(3) + '%'; 114 115 for (var i = 1; i < columns.length; i++) 116 columns[i].width = colWidthPercentage; 117 118 this.$.content.tableColumns = columns; 119 this.$.content.sortColumnIndex = columns.length - 1; 120 }, 121 122 updateContents_: function() { 123 var table = this.$.content; 124 125 if (this.selection_.length === 0) { 126 this.$.link.setSelectionAndContent(undefined, ''); 127 table.tableRows = []; 128 table.footerRows = []; 129 table.rebuild(); 130 return; 131 } 132 133 // LTHI link. 134 var lthi = tr.e.cc.getTileFromRasterTaskSlice( 135 this.selection_[0]).containingSnapshot; 136 this.$.link.setSelectionAndContent(function() { 137 return new tr.model.EventSet(lthi); 138 }, lthi.userFriendlyName); 139 140 // Get costs by layer. 141 var costsByLayerId = {}; 142 function getCurrentCostsForLayerId(tile) { 143 var layerId = tile.layerId; 144 var lthi = tile.containingSnapshot; 145 var layer; 146 if (lthi.activeTree) 147 layer = lthi.activeTree.findLayerWithId(layerId); 148 if (layer === undefined && lthi.pendingTree) 149 layer = lthi.pendingTree.findLayerWithId(layerId); 150 if (costsByLayerId[layerId] === undefined) { 151 costsByLayerId[layerId] = { 152 layerId: layerId, 153 layer: layer, 154 numTiles: 0, 155 numAnalysisTasks: 0, 156 numRasterTasks: 0, 157 duration: 0, 158 cpuDuration: 0 159 }; 160 } 161 return costsByLayerId[layerId]; 162 } 163 164 var totalDuration = 0; 165 var totalCpuDuration = 0; 166 var totalNumAnalyzeTasks = 0; 167 var totalNumRasterizeTasks = 0; 168 var hadCpuDurations = false; 169 170 var tilesThatWeHaveSeen = {}; 171 172 this.selection_.forEach(function(slice) { 173 var tile = tr.e.cc.getTileFromRasterTaskSlice(slice); 174 var curCosts = getCurrentCostsForLayerId(tile); 175 176 if (!tilesThatWeHaveSeen[tile.objectInstance.id]) { 177 tilesThatWeHaveSeen[tile.objectInstance.id] = true; 178 curCosts.numTiles += 1; 179 } 180 181 if (tr.e.cc.isSliceDoingAnalysis(slice)) { 182 curCosts.numAnalysisTasks += 1; 183 totalNumAnalyzeTasks += 1; 184 } else { 185 curCosts.numRasterTasks += 1; 186 totalNumRasterizeTasks += 1; 187 } 188 curCosts.duration += slice.duration; 189 totalDuration += slice.duration; 190 if (slice.cpuDuration !== undefined) { 191 curCosts.cpuDuration += slice.cpuDuration; 192 totalCpuDuration += slice.cpuDuration; 193 hadCpuDurations = true; 194 } 195 }); 196 197 // Apply to the table. 198 this.updateColumns_(hadCpuDurations); 199 table.tableRows = tr.b.dictionaryValues(costsByLayerId); 200 table.rebuild(); 201 202 // Footer. 203 table.footerRows = [ 204 { 205 isTotals: true, 206 numTiles: tr.b.dictionaryLength(tilesThatWeHaveSeen), 207 numAnalysisTasks: totalNumAnalyzeTasks, 208 numRasterTasks: totalNumRasterizeTasks, 209 duration: totalDuration, 210 cpuDuration: totalCpuDuration 211 } 212 ]; 213 } 214 }); 215 </script> 216</polymer-element> 217