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 'use strict'; 6 7 base.requireStylesheet('tracks.thread_track'); 8 9 base.require('tracks.container_track'); 10 base.require('tracks.slice_track'); 11 base.require('tracks.slice_group_track'); 12 base.require('tracks.async_slice_group_track'); 13 base.require('filter'); 14 base.require('ui'); 15 16 base.exportTo('tracing.tracks', function() { 17 18 /** 19 * Visualizes a Thread using a series of of SliceTracks. 20 * @constructor 21 */ 22 var ThreadTrack = tracing.ui.define(tracing.tracks.ContainerTrack); 23 ThreadTrack.prototype = { 24 __proto__: tracing.tracks.ContainerTrack.prototype, 25 26 decorate: function() { 27 this.classList.add('thread-track'); 28 this.categoryFilter_ = new tracing.Filter(); 29 }, 30 31 get thread() { 32 return this.thread_; 33 }, 34 35 set thread(thread) { 36 this.thread_ = thread; 37 this.updateChildTracks_(); 38 }, 39 40 get tooltip() { 41 return this.tooltip_; 42 }, 43 44 set tooltip(value) { 45 this.tooltip_ = value; 46 this.updateChildTracks_(); 47 }, 48 49 get heading() { 50 return this.heading_; 51 }, 52 53 set heading(h) { 54 this.heading_ = h; 55 this.updateChildTracks_(); 56 }, 57 58 applyCategoryFilter_: function() { 59 this.updateVisibility_(); 60 }, 61 62 updateChildTracks_: function() { 63 this.detach(); 64 if (this.thread_) { 65 var cpuTrack = new tracing.tracks.SliceTrack(); 66 cpuTrack.heading = ''; 67 cpuTrack.slices = this.thread_.cpuSlices; 68 cpuTrack.height = '4px'; 69 cpuTrack.decorateHit = function(hit) { 70 hit.thread = this.thread_; 71 } 72 this.addTrack_(cpuTrack); 73 74 var asyncTrack = new tracing.tracks.AsyncSliceGroupTrack(); 75 asyncTrack.categoryFilter = this.categoryFilter; 76 asyncTrack.decorateHit = function(hit) { 77 // TODO(simonjam): figure out how to associate subSlice hits back 78 // to their parent slice. 79 } 80 asyncTrack.group = this.thread_.asyncSlices; 81 this.addTrack_(asyncTrack); 82 83 var track = new tracing.tracks.SliceGroupTrack(); 84 track.decorateHit = function(hit) { 85 hit.thread = this.thread_; 86 } 87 track.group = this.thread_; 88 this.addTrack_(track); 89 90 if (this.thread_.samples.length) { 91 var samplesTrack = new tracing.tracks.SliceTrack(); 92 samplesTrack.group = this.thread_; 93 samplesTrack.slices = this.thread_.samples; 94 samplesTrack.decorateHit = function(hit) { 95 // TODO(johnmccutchan): Figure out what else should be associated 96 // with the hit. 97 hit.thread = this.thread_; 98 } 99 this.addTrack_(samplesTrack); 100 } 101 102 this.updateVisibility_(); 103 } 104 this.addControlButtonElements_(this.tracks_.length >= 4); 105 }, 106 107 updateVisibility_: function() { 108 if (!this.categoryFilter.matchThread(this.thread)) { 109 this.visible = false; 110 return; 111 } 112 var shouldBeVisible = false; 113 for (var i = 0; i < this.tracks_.length; ++i) { 114 var track = this.tracks_[i]; 115 if (track.visible) { 116 shouldBeVisible = true; 117 if (i >= 1) { 118 track.heading = this.heading_; 119 track.tooltip = this.tooltip_; 120 break; 121 } 122 } 123 } 124 this.visible = shouldBeVisible; 125 }, 126 127 collapsedDidChange: function(collapsed) { 128 if (collapsed) { 129 var h = parseInt(this.tracks_[0].height); 130 for (var i = 0; i < this.tracks_.length; ++i) { 131 if (h > 2) { 132 this.tracks_[i].height = Math.floor(h) + 'px'; 133 } else { 134 this.tracks_[i].style.display = 'none'; 135 } 136 h = h * 0.5; 137 } 138 } else { 139 for (var i = 0; i < this.tracks_.length; ++i) { 140 this.tracks_[i].height = this.tracks_[0].height; 141 this.tracks_[i].style.display = ''; 142 } 143 } 144 } 145 }; 146 147 return { 148 ThreadTrack: ThreadTrack 149 }; 150 }); 151