| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| |
| <link rel="import" href="/core/tracks/rect_track.html"> |
| <link rel="import" href="/base/ui.html"> |
| <link rel="import" href="/base/ui/color_scheme.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tv.exportTo('tv.c.tracks', function() { |
| /** |
| * Visualizes a Process's state using a series of rects to represent activity. |
| * @constructor |
| */ |
| var ProcessSummaryTrack = tv.b.ui.define('process-summary-track', |
| tv.c.tracks.RectTrack); |
| |
| ProcessSummaryTrack.buildRectsFromProcess = function(process) { |
| if (!process) |
| return []; |
| |
| var ops = []; |
| // build list of start/end ops for each top level or important slice |
| var pushOp = function(isStart, time, slice) { |
| ops.push({ |
| isStart: isStart, |
| time: time, |
| slice: slice |
| }); |
| }; |
| for (var tid in process.threads) { |
| var sliceGroup = process.threads[tid].sliceGroup; |
| |
| sliceGroup.topLevelSlices.forEach(function(slice) { |
| pushOp(true, slice.start, undefined); |
| pushOp(false, slice.end, undefined); |
| }); |
| sliceGroup.slices.forEach(function(slice) { |
| if (slice.important) { |
| pushOp(true, slice.start, slice); |
| pushOp(false, slice.end, slice); |
| } |
| }); |
| } |
| ops.sort(function(a, b) { return a.time - b.time; }); |
| |
| var rects = []; |
| /** |
| * Build a row of rects which display one way for unimportant activity, |
| * and during important slices, show up as those important slices. |
| * |
| * If an important slice starts in the middle of another, |
| * just drop it on the floor. |
| */ |
| var genericColorId = tv.b.ui.getColorIdForReservedName('generic_work'); |
| var pushRect = function(start, end, slice) { |
| rects.push(new tv.c.tracks.Rect( |
| slice, /* modelItem: show selection state of slice if present */ |
| slice ? slice.title : '', /* title */ |
| slice ? slice.colorId : genericColorId, /* colorId */ |
| start, /* start */ |
| end - start /* duration */)); |
| } |
| var depth = 0; |
| var currentSlice = undefined; |
| var lastStart = undefined; |
| ops.forEach(function(op) { |
| depth += op.isStart ? 1 : -1; |
| |
| if (currentSlice) { |
| // simply find end of current important slice |
| if (!op.isStart && op.slice == currentSlice) { |
| // important slice has ended |
| pushRect(lastStart, op.time, currentSlice); |
| lastStart = depth >= 1 ? op.time : undefined; |
| currentSlice = undefined; |
| } |
| } else { |
| if (op.isStart) { |
| if (depth == 1) { |
| lastStart = op.time; |
| currentSlice = op.slice; |
| } else if (op.slice) { |
| // switch to slice |
| if (op.time != lastStart) { |
| pushRect(lastStart, op.time, undefined); |
| lastStart = op.time; |
| } |
| currentSlice = op.slice; |
| } |
| } else { |
| if (depth == 0) { |
| pushRect(lastStart, op.time, undefined); |
| lastStart = undefined; |
| } |
| } |
| } |
| }); |
| return rects; |
| }; |
| |
| ProcessSummaryTrack.prototype = { |
| __proto__: tv.c.tracks.RectTrack.prototype, |
| |
| decorate: function(viewport) { |
| tv.c.tracks.RectTrack.prototype.decorate.call(this, viewport); |
| }, |
| |
| get process() { |
| return this.process_; |
| }, |
| |
| set process(process) { |
| this.process_ = process; |
| this.rects = ProcessSummaryTrack.buildRectsFromProcess(process); |
| } |
| }; |
| |
| return { |
| ProcessSummaryTrack: ProcessSummaryTrack |
| }; |
| }); |
| </script> |