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
7base.requireStylesheet('tracks.thread_track');
8
9base.require('tracks.container_track');
10base.require('tracks.slice_track');
11base.require('tracks.slice_group_track');
12base.require('tracks.async_slice_group_track');
13base.require('filter');
14base.require('ui');
15
16base.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