12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Use of this source code is governed by a BSD-style license that can be 32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// found in the LICENSE file. 42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis'use strict'; 62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.sorted_array_utils'); 866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('tracing.tracks.container_track'); 92da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui'); 102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1188448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.exportTo('tracing.tracks', function() { 122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 1488448d9ae4dfff1805045790ef5f32495d62abccJeff Brown * A track that displays a SliceGroup. 152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @constructor 1688448d9ae4dfff1805045790ef5f32495d62abccJeff Brown * @extends {ContainerTrack} 172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var SliceGroupTrack = ui.define( 2066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 'slice-group-track', tracing.tracks.ContainerTrack); 212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2288448d9ae4dfff1805045790ef5f32495d62abccJeff Brown SliceGroupTrack.prototype = { 232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2488448d9ae4dfff1805045790ef5f32495d62abccJeff Brown __proto__: tracing.tracks.ContainerTrack.prototype, 252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis decorate: function(viewport) { 2766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis tracing.tracks.ContainerTrack.prototype.decorate.call(this, viewport); 2888448d9ae4dfff1805045790ef5f32495d62abccJeff Brown this.classList.add('slice-group-track'); 2966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.tooltip_ = ''; 3066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.heading_ = ''; 312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis get group() { 342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return this.group_; 352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set group(g) { 382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.group_ = g; 3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateContents_(); 4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get heading() { 4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.heading_; 442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set heading(h) { 4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.heading_ = h; 4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateContents_(); 4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get tooltip() { 5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.tooltip_; 532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set tooltip(t) { 5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.tooltip_ = t; 5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateContents_(); 582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set decorateHit(f) { 612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.decorateHit_ = f; 6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateContents_(); 632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis addSliceTrack_: function(slices) { 6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var track = new tracing.tracks.SliceTrack(this.viewport); 672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis track.slices = slices; 682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis track.decorateHit = this.decorateHit_; 6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis track.categoryFilter_ = this.categoryFilter; 7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.appendChild(track); 712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return track; 722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get subRows() { 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return base.asArray(this.children).map(function(sliceTrack) { 7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return sliceTrack.slices; 7766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }); 7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 7966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get hasVisibleContent() { 8166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.children.length > 0; 8266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 8366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 8466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis updateContents_: function() { 852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!this.group_) { 8666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateHeadingAndTooltip_(); 872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slices = tracing.filterSliceArray(this.categoryFilter, 912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.group_.slices); 9266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (this.areArrayContentsSame_(this.filteredSlices_, slices)) { 9366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateHeadingAndTooltip_(); 942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.filteredSlices_ = slices; 9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.detach(); 10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!slices.length) 10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return; 10266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var subRows = this.buildSubRows_(slices); 10366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis for (var srI = 0; srI < subRows.length; srI++) { 10466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var subRow = subRows[srI]; 10566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!subRow.length) 10666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis continue; 10766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.addSliceTrack_(subRow); 1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 10966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.updateHeadingAndTooltip_(); 11066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 11166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 11266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis updateHeadingAndTooltip_: function() { 11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!this.firstChild) 11466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return; 11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.firstChild.heading = this.heading_; 11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.firstChild.tooltip = this.tooltip_; 1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Breaks up the list of slices into N rows, each of which is a list of 1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * slices that are non overlapping. 1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis buildSubRows_: function(slices) { 1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // This function works by walking through slices by start time. 1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // The basic idea here is to insert each slice as deep into the subrow 1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // list as it can go such that every subSlice is fully contained by its 1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // parent slice. 1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Visually, if we start with this: 1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 0: [ a ] 1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1: [ b ] 1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2: [c][d] 1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // To place this slice: 1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // [e] 1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // We first check row 2's last item, [d]. [e] wont fit into [d] (they dont 1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // even intersect). So we go to row 1. That gives us [b], and [d] wont fit 1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // into that either. So, we go to row 0 and its last slice, [a]. That can 1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // completely contain [e], so that means we should add [e] as a subchild 1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // of [a]. That puts it on row 1, yielding: 1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 0: [ a ] 1432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1: [ b ][e] 1442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2: [c][d] 1452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // If we then get this slice: 1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // [f] 1482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // We do the same deepest-to-shallowest walk of the subrows trying to fit 1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // it. This time, it doesn't fit in any open slice. So, we simply append 1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // it to row 0: 1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 0: [ a ] [f] 1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1: [ b ][e] 1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2: [c][d] 1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!slices.length) 1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return []; 1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var ops = []; 1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < slices.length; i++) { 1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slices[i].subSlices) 1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slices[i].subSlices.splice(0, 1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slices[i].subSlices.length); 1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ops.push(i); 1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ops.sort(function(ix, iy) { 1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var x = slices[ix]; 1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var y = slices[iy]; 1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (x.start != y.start) 1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return x.start - y.start; 1706e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis 1716e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // Elements get inserted into the slices array in order of when the 1726e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // slices end. Because slices must be properly nested, we break 1736e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // start-time ties by assuming that the elements appearing earlier in 1746e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // the slices array (and thus ending earlier) start later. 1756e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis return iy - ix; 1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }); 1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var subRows = [[]]; 1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.badSlices_ = []; // TODO(simonjam): Connect this again. 1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < ops.length; i++) { 1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var op = ops[i]; 1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slice = slices[op]; 1842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Try to fit the slice into the existing subrows. 1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var inserted = false; 1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var j = subRows.length - 1; j >= 0; j--) { 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (subRows[j].length == 0) 1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var insertedSlice = subRows[j][subRows[j].length - 1]; 1922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slice.start < insertedSlice.start) { 1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.badSlices_.push(slice); 1942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis inserted = true; 1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slice.start >= insertedSlice.start && 1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.end <= insertedSlice.end) { 1982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Insert it into subRow j + 1. 1992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis while (subRows.length <= j + 1) 2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis subRows.push([]); 2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis subRows[j + 1].push(slice); 2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (insertedSlice.subSlices) 2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis insertedSlice.subSlices.push(slice); 2042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis inserted = true; 2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis break; 2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (inserted) 2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 2102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Append it to subRow[0] as a root. 2122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis subRows[0].push(slice); 2132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return subRows; 2162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis areArrayContentsSame_: function(a, b) { 2192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!a || !b) 2202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!a.length || !b.length) 2222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (a.length != b.length) 2242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < a.length; ++i) { 2262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (a[i] != b[i]) 2272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return true; 2302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return { 23488448d9ae4dfff1805045790ef5f32495d62abccJeff Brown SliceGroupTrack: SliceGroupTrack 2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis}); 237