1<!DOCTYPE html>
2<!--
3Copyright (c) 2015 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="import" href="/tracing/base/color_scheme.html">
9<link rel="import" href="/tracing/ui/base/ui.html">
10<link rel="import" href="/tracing/ui/tracks/rect_track.html">
11
12<script>
13'use strict';
14
15tr.exportTo('tr.ui.tracks', function() {
16  var ColorScheme = tr.b.ColorScheme;
17
18  /**
19   * Visualizes a Process's state using a series of rects to represent activity.
20   * @constructor
21   */
22  var ProcessSummaryTrack = tr.ui.b.define('process-summary-track',
23                                           tr.ui.tracks.RectTrack);
24
25  ProcessSummaryTrack.buildRectsFromProcess = function(process) {
26    if (!process)
27      return [];
28
29    var ops = [];
30    // build list of start/end ops for each top level or important slice
31    var pushOp = function(isStart, time, slice) {
32      ops.push({
33        isStart: isStart,
34        time: time,
35        slice: slice
36      });
37    };
38    for (var tid in process.threads) {
39      var sliceGroup = process.threads[tid].sliceGroup;
40
41      sliceGroup.topLevelSlices.forEach(function(slice) {
42        pushOp(true, slice.start, undefined);
43        pushOp(false, slice.end, undefined);
44      });
45      sliceGroup.slices.forEach(function(slice) {
46        if (slice.important) {
47          pushOp(true, slice.start, slice);
48          pushOp(false, slice.end, slice);
49        }
50      });
51    }
52    ops.sort(function(a, b) { return a.time - b.time; });
53
54    var rects = [];
55    /**
56     * Build a row of rects which display one way for unimportant activity,
57     * and during important slices, show up as those important slices.
58     *
59     * If an important slice starts in the middle of another,
60     * just drop it on the floor.
61     */
62    var genericColorId = ColorScheme.getColorIdForReservedName('generic_work');
63    var pushRect = function(start, end, slice) {
64      rects.push(new tr.ui.tracks.Rect(
65          slice, /* modelItem: show selection state of slice if present */
66          slice ? slice.title : '', /* title */
67          slice ? slice.colorId : genericColorId, /* colorId */
68          start, /* start */
69          end - start /* duration */));
70    }
71    var depth = 0;
72    var currentSlice = undefined;
73    var lastStart = undefined;
74    ops.forEach(function(op) {
75      depth += op.isStart ? 1 : -1;
76
77      if (currentSlice) {
78        // simply find end of current important slice
79        if (!op.isStart && op.slice == currentSlice) {
80          // important slice has ended
81          pushRect(lastStart, op.time, currentSlice);
82          lastStart = depth >= 1 ? op.time : undefined;
83          currentSlice = undefined;
84        }
85      } else {
86        if (op.isStart) {
87          if (depth == 1) {
88            lastStart = op.time;
89            currentSlice = op.slice;
90          } else if (op.slice) {
91            // switch to slice
92            if (op.time != lastStart) {
93              pushRect(lastStart, op.time, undefined);
94              lastStart = op.time;
95            }
96            currentSlice = op.slice;
97          }
98        } else {
99          if (depth == 0) {
100            pushRect(lastStart, op.time, undefined);
101            lastStart = undefined;
102          }
103        }
104      }
105    });
106    return rects;
107  };
108
109  ProcessSummaryTrack.prototype = {
110    __proto__: tr.ui.tracks.RectTrack.prototype,
111
112    decorate: function(viewport) {
113      tr.ui.tracks.RectTrack.prototype.decorate.call(this, viewport);
114    },
115
116    get process() {
117      return this.process_;
118    },
119
120    set process(process) {
121      this.process_ = process;
122      this.rects = ProcessSummaryTrack.buildRectsFromProcess(process);
123    }
124  };
125
126  return {
127    ProcessSummaryTrack: ProcessSummaryTrack
128  };
129});
130</script>
131