| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 /** | 6 /** |
| 7 * @fileoverview TimelineView visualizes GPU_TRACE events using the | 7 * @fileoverview TimelineView visualizes GPU_TRACE events using the |
| 8 * gpu.Timeline component. | 8 * gpu.Timeline component. |
| 9 */ | 9 */ |
| 10 cr.define('gpu', function() { | 10 cr.define('gpu', function() { |
| 11 function tsRound(ts) { | 11 function tsRound(ts) { |
| 12 return Math.round(ts * 100.0) / 100.0; | 12 return Math.round(ts * 1000.0) / 1000.0; |
| 13 } | 13 } |
| 14 function getPadding(text, width) { | 14 function getPadding(text, width) { |
| 15 width = width || 0; | 15 width = width || 0; |
| 16 | 16 |
| 17 if (typeof text != 'string') | 17 if (typeof text != 'string') |
| 18 text = String(text); | 18 text = String(text); |
| 19 | 19 |
| 20 if (text.length >= width) | 20 if (text.length >= width) |
| 21 return ''; | 21 return ''; |
| 22 | 22 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 38 * TimelineView | 38 * TimelineView |
| 39 * @constructor | 39 * @constructor |
| 40 * @extends {gpu.Tab} | 40 * @extends {gpu.Tab} |
| 41 */ | 41 */ |
| 42 TimelineView = cr.ui.define(gpu.Tab); | 42 TimelineView = cr.ui.define(gpu.Tab); |
| 43 | 43 |
| 44 TimelineView.prototype = { | 44 TimelineView.prototype = { |
| 45 __proto__: gpu.Tab.prototype, | 45 __proto__: gpu.Tab.prototype, |
| 46 | 46 |
| 47 decorate: function() { | 47 decorate: function() { |
| 48 tracingController.addEventListener('traceBegun', this.refresh.bind(this)); | 48 tracingController.addEventListener('traceBegun', |
| 49 tracingController.addEventListener('traceEnded', this.refresh.bind(this)); | 49 this.setNeedsRefresh_.bind(this)); |
| 50 tracingController.addEventListener('traceEnded', |
| 51 this.setNeedsRefresh_.bind(this)); |
| 50 this.addEventListener('selectedChange', this.onViewSelectedChange_); | 52 this.addEventListener('selectedChange', this.onViewSelectedChange_); |
| 51 | 53 |
| 52 this.refresh(); | 54 this.setNeedsRefresh_(); |
| 53 }, | 55 }, |
| 54 | 56 |
| 55 onViewSelectedChange_: function() { | 57 onViewSelectedChange_: function() { |
| 56 if (this.selected) { | 58 if (this.selected) { |
| 57 if (tracingController.traceEvents.length == 0) { | 59 if (!tracingController.traceEvents.length) { |
| 58 tracingController.beginTracing(); | 60 tracingController.beginTracing(); |
| 59 } | 61 } |
| 60 if (this.needsRefreshOnShow_) { | 62 if (this.needsRefreshOnShow_) { |
| 61 this.needsRefreshOnShow_ = false; | |
| 62 this.refresh(); | 63 this.refresh(); |
| 63 } | 64 } |
| 64 } | 65 } |
| 65 }, | 66 }, |
| 66 | 67 |
| 68 setNeedsRefresh_: function() { |
| 69 if (!this.selected) { |
| 70 this.needsRefreshOnShow_ = true; |
| 71 return; |
| 72 } else { |
| 73 this.refresh(); |
| 74 } |
| 75 }, |
| 76 |
| 67 /** | 77 /** |
| 68 * Updates the view based on its currently known data | 78 * Updates the view based on its currently known data |
| 69 */ | 79 */ |
| 70 refresh: function() { | 80 refresh: function() { |
| 71 if (this.parentNode.selectedTab != this) { | 81 this.needsRefreshOnShow_ = false; |
| 72 this.needsRefreshOnShow_ = true; | |
| 73 } | |
| 74 | 82 |
| 75 console.log('TimelineView.refresh'); | 83 console.log('TimelineView.refresh'); |
| 76 var events = tracingController.traceEvents; | 84 var events = tracingController.traceEvents; |
| 77 this.timelineModel_ = new gpu.TimelineModel(events); | 85 this.timelineModel_ = new gpu.TimelineModel(events); |
| 78 | 86 |
| 79 // remove old timeline | 87 // remove old timeline |
| 80 var timelineContainer = $('timeline-view-timeline-container'); | 88 var timelineContainer = $('timeline-view-timeline-container'); |
| 81 timelineContainer.textContent = ''; | 89 timelineContainer.textContent = ''; |
| 82 | 90 |
| 83 // create new timeline if needed | 91 // create new timeline if needed |
| (...skipping 14 matching lines...) Expand all Loading... |
| 98 console.log('selection changed'); | 106 console.log('selection changed'); |
| 99 var timeline = this.timeline_; | 107 var timeline = this.timeline_; |
| 100 var selection = timeline.selection; | 108 var selection = timeline.selection; |
| 101 if (!selection.length) { | 109 if (!selection.length) { |
| 102 var outputDiv = $('timeline-selection-summary'); | 110 var outputDiv = $('timeline-selection-summary'); |
| 103 outputDiv.textContent = timeline.keyHelp; | 111 outputDiv.textContent = timeline.keyHelp; |
| 104 return; | 112 return; |
| 105 } | 113 } |
| 106 | 114 |
| 107 var text = ''; | 115 var text = ''; |
| 108 var tsLo = Math.min.apply(Math, selection.map( | 116 if (selection.length == 1) { |
| 109 function(s) {return s.slice.start;})); | 117 var c0Width = 10; |
| 110 var tsHi = Math.max.apply(Math, selection.map( | 118 var slice = selection[0].slice; |
| 111 function(s) {return s.slice.end;})); | 119 text = 'Selected item:\n'; |
| 120 text += leftAlign('Title', c0Width) + ': ' + slice.title + '\n'; |
| 121 text += leftAlign('Start', c0Width) + ': ' + |
| 122 tsRound(slice.start) + ' ms\n'; |
| 123 text += leftAlign('Duration', c0Width) + ': ' + |
| 124 tsRound(slice.duration) + ' ms\n'; |
| 112 | 125 |
| 113 // compute total selection duration | 126 var n = 0; |
| 114 var titles = selection.map(function(i) { return i.slice.title; }); | 127 for (var argName in slice.args) { |
| 128 n += 1; |
| 129 } |
| 130 if (n > 0) { |
| 131 text += leftAlign('Args', c0Width) + ':\n'; |
| 132 for (var argName in slice.args) { |
| 133 var argVal = slice.args[argName]; |
| 134 text += leftAlign(' ' + argName, c0Width) + ': ' + argVal + '\n'; |
| 135 } |
| 136 } |
| 137 } else { |
| 138 var c0Width = 55; |
| 139 var c1Width = 12; |
| 140 var c2Width = 5; |
| 141 text = 'Selection summary:\n'; |
| 142 var tsLo = Math.min.apply(Math, selection.map( |
| 143 function(s) {return s.slice.start;})); |
| 144 var tsHi = Math.max.apply(Math, selection.map( |
| 145 function(s) {return s.slice.end;})); |
| 115 | 146 |
| 116 var slicesByTitle = {}; | 147 // compute total selection duration |
| 117 for (var i = 0; i < selection.length; i++) { | 148 var titles = selection.map(function(i) { return i.slice.title; }); |
| 118 var slice = selection[i].slice; | |
| 119 if (!slicesByTitle[slice.title]) | |
| 120 slicesByTitle[slice.title] = { | |
| 121 slices: [] | |
| 122 }; | |
| 123 slicesByTitle[slice.title].slices.push(slice); | |
| 124 } | |
| 125 var totalDuration = 0; | |
| 126 for (var sliceGroupTitle in slicesByTitle) { | |
| 127 var sliceGroup = slicesByTitle[sliceGroupTitle]; | |
| 128 var duration = 0; | |
| 129 for (i = 0; i < sliceGroup.slices.length; i++) | |
| 130 duration += sliceGroup.slices[i].duration; | |
| 131 totalDuration += duration; | |
| 132 | 149 |
| 133 text += ' ' + | 150 var slicesByTitle = {}; |
| 134 leftAlign(sliceGroupTitle, 55) + ': ' + | 151 for (var i = 0; i < selection.length; i++) { |
| 135 rightAlign(tsRound(duration) + 'ms', 12) + ' ' + | 152 var slice = selection[i].slice; |
| 136 rightAlign(String(sliceGroup.slices.length), 5) + ' occurrences' + | 153 if (!slicesByTitle[slice.title]) |
| 154 slicesByTitle[slice.title] = { |
| 155 slices: [] |
| 156 }; |
| 157 slicesByTitle[slice.title].slices.push(slice); |
| 158 } |
| 159 var totalDuration = 0; |
| 160 for (var sliceGroupTitle in slicesByTitle) { |
| 161 var sliceGroup = slicesByTitle[sliceGroupTitle]; |
| 162 var duration = 0; |
| 163 for (i = 0; i < sliceGroup.slices.length; i++) |
| 164 duration += sliceGroup.slices[i].duration; |
| 165 totalDuration += duration; |
| 166 |
| 167 text += ' ' + |
| 168 leftAlign(sliceGroupTitle, c0Width) + ': ' + |
| 169 rightAlign(tsRound(duration) + 'ms', c1Width) + ' ' + |
| 170 rightAlign(String(sliceGroup.slices.length), c2Width) + |
| 171 ' occurrences' + '\n'; |
| 172 } |
| 173 |
| 174 text += leftAlign('*Totals', c0Width) + ' : ' + |
| 175 rightAlign(tsRound(totalDuration) + 'ms', c1Width) + ' ' + |
| 176 rightAlign(String(selection.length), c2Width) + ' occurrences' + |
| 177 '\n'; |
| 178 |
| 179 text += '\n'; |
| 180 |
| 181 text += leftAlign('Selection start', c0Width) + ' : ' + |
| 182 rightAlign(tsRound(tsLo) + 'ms', c1Width) + |
| 183 '\n'; |
| 184 text += leftAlign('Selection extent', c0Width) + ' : ' + |
| 185 rightAlign(tsRound(tsHi - tsLo) + 'ms', c1Width) + |
| 137 '\n'; | 186 '\n'; |
| 138 } | 187 } |
| 139 | 188 |
| 140 text += leftAlign('*Totals', 55) + ' : ' + | |
| 141 rightAlign(tsRound(totalDuration) + 'ms', 12) + ' ' + | |
| 142 rightAlign(String(selection.length), 5) + ' occurrences' + | |
| 143 '\n'; | |
| 144 | |
| 145 text += '\n'; | |
| 146 | |
| 147 text += leftAlign('Selection start', 55) + ' : ' + | |
| 148 rightAlign(tsRound(tsLo) + 'ms', 12) + | |
| 149 '\n'; | |
| 150 text += leftAlign('Selection extent', 55) + ' : ' + | |
| 151 rightAlign(tsRound(tsHi - tsLo) + 'ms', 12) + | |
| 152 '\n'; | |
| 153 | |
| 154 // done | 189 // done |
| 155 var outputDiv = $('timeline-selection-summary'); | 190 var outputDiv = $('timeline-selection-summary'); |
| 156 outputDiv.innerHTML = text; | 191 outputDiv.innerHTML = text; |
| 157 } | 192 } |
| 158 }; | 193 }; |
| 159 | 194 |
| 160 return { | 195 return { |
| 161 TimelineView: TimelineView | 196 TimelineView: TimelineView |
| 162 }; | 197 }; |
| 163 }); | 198 }); |
| OLD | NEW |