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 8<link rel="stylesheet" href="/tracing/ui/tracks/thread_track.css"> 9 10<link rel="import" href="/tracing/base/iteration_helpers.html"> 11<link rel="import" href="/tracing/core/filter.html"> 12<link rel="import" href="/tracing/model/event_set.html"> 13<link rel="import" href="/tracing/ui/base/ui.html"> 14<link rel="import" href="/tracing/ui/tracks/async_slice_group_track.html"> 15<link rel="import" href="/tracing/ui/tracks/container_track.html"> 16<link rel="import" href="/tracing/ui/tracks/sample_track.html"> 17<link rel="import" href="/tracing/ui/tracks/slice_group_track.html"> 18<link rel="import" href="/tracing/ui/tracks/slice_track.html"> 19 20<script> 21'use strict'; 22 23tr.exportTo('tr.ui.tracks', function() { 24 /** 25 * Visualizes a Thread using a series of SliceTracks. 26 * @constructor 27 */ 28 var ThreadTrack = tr.ui.b.define('thread-track', 29 tr.ui.tracks.ContainerTrack); 30 ThreadTrack.prototype = { 31 __proto__: tr.ui.tracks.ContainerTrack.prototype, 32 33 decorate: function(viewport) { 34 tr.ui.tracks.ContainerTrack.prototype.decorate.call(this, viewport); 35 this.classList.add('thread-track'); 36 }, 37 38 get thread() { 39 return this.thread_; 40 }, 41 42 set thread(thread) { 43 this.thread_ = thread; 44 this.updateContents_(); 45 }, 46 47 get hasVisibleContent() { 48 return this.tracks_.length > 0; 49 }, 50 51 get eventContainer() { 52 return this.thread; 53 }, 54 55 addContainersToTrackMap: function(containerToTrackMap) { 56 tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply( 57 this, arguments); 58 containerToTrackMap.addContainer(this.thread, this); 59 }, 60 61 updateContents_: function() { 62 this.detach(); 63 64 if (!this.thread_) 65 return; 66 67 this.heading = this.thread_.userFriendlyName + ': '; 68 this.tooltip = this.thread_.userFriendlyDetails; 69 70 if (this.thread_.asyncSliceGroup.length) 71 this.appendAsyncSliceTracks_(); 72 73 this.appendThreadSamplesTracks_(); 74 75 if (this.thread_.timeSlices) { 76 var timeSlicesTrack = new tr.ui.tracks.SliceTrack(this.viewport); 77 timeSlicesTrack.heading = ''; 78 timeSlicesTrack.height = tr.ui.b.THIN_SLICE_HEIGHT + 'px'; 79 timeSlicesTrack.slices = this.thread_.timeSlices; 80 if (timeSlicesTrack.hasVisibleContent) 81 this.appendChild(timeSlicesTrack); 82 } 83 84 if (this.thread_.sliceGroup.length) { 85 var track = new tr.ui.tracks.SliceGroupTrack(this.viewport); 86 track.heading = this.thread_.userFriendlyName; 87 track.tooltip = this.thread_.userFriendlyDetails; 88 track.group = this.thread_.sliceGroup; 89 if (track.hasVisibleContent) 90 this.appendChild(track); 91 } 92 }, 93 94 appendAsyncSliceTracks_: function() { 95 var subGroups = this.thread_.asyncSliceGroup.viewSubGroups; 96 subGroups.forEach(function(subGroup) { 97 var asyncTrack = new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport); 98 var title = subGroup.slices[0].viewSubGroupTitle; 99 asyncTrack.group = subGroup; 100 asyncTrack.heading = title; 101 if (asyncTrack.hasVisibleContent) 102 this.appendChild(asyncTrack); 103 }, this); 104 }, 105 106 appendThreadSamplesTracks_: function() { 107 var threadSamples = this.thread_.samples; 108 if (threadSamples === undefined || threadSamples.length === 0) 109 return; 110 var samplesByTitle = {}; 111 threadSamples.forEach(function(sample) { 112 if (samplesByTitle[sample.title] === undefined) 113 samplesByTitle[sample.title] = []; 114 samplesByTitle[sample.title].push(sample); 115 }); 116 117 var sampleTitles = tr.b.dictionaryKeys(samplesByTitle); 118 sampleTitles.sort(); 119 120 sampleTitles.forEach(function(sampleTitle) { 121 var samples = samplesByTitle[sampleTitle]; 122 var samplesTrack = new tr.ui.tracks.SampleTrack(this.viewport); 123 samplesTrack.group = this.thread_; 124 samplesTrack.samples = samples; 125 samplesTrack.heading = this.thread_.userFriendlyName + ': ' + 126 sampleTitle; 127 samplesTrack.tooltip = this.thread_.userFriendlyDetails; 128 samplesTrack.selectionGenerator = function() { 129 var selection = new tr.model.EventSet(); 130 for (var i = 0; i < samplesTrack.samples.length; i++) { 131 selection.push(samplesTrack.samples[i]); 132 } 133 return selection; 134 }; 135 this.appendChild(samplesTrack); 136 }, this); 137 }, 138 139 collapsedDidChange: function(collapsed) { 140 if (collapsed) { 141 var h = parseInt(this.tracks[0].height); 142 for (var i = 0; i < this.tracks.length; ++i) { 143 if (h > 2) { 144 this.tracks[i].height = Math.floor(h) + 'px'; 145 } else { 146 this.tracks[i].style.display = 'none'; 147 } 148 h = h * 0.5; 149 } 150 } else { 151 for (var i = 0; i < this.tracks.length; ++i) { 152 this.tracks[i].height = this.tracks[0].height; 153 this.tracks[i].style.display = ''; 154 } 155 } 156 } 157 }; 158 159 return { 160 ThreadTrack: ThreadTrack 161 }; 162}); 163</script> 164