1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/** 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @fileoverview TimelineModel is a parsed representation of the 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * TraceEvents obtained from base/trace_event in which the begin-end 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * tokens are converted into a hierarchy of processes, threads, 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * subrows, and slices. 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * The building block of the model is a slice. A slice is roughly 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * equivalent to function call executing on a specific thread. As a 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * result, slices may have one or more subslices. 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * A thread contains one or more subrows of slices. Row 0 corresponds to 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the "root" slices, e.g. the topmost slices. Row 1 contains slices that 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * are nested 1 deep in the stack, and so on. We use these subrows to draw 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * nesting tasks. 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsencr.define('gpu', function() { 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * A TimelineSlice represents an interval of time on a given thread 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * associated with a specific trace event. For example, 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * TRACE_EVENT_BEGIN1("x","myArg", 7) at time=0.1ms 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * TRACE_EVENT_END() at time=0.3ms 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Results in a single timeline slice from 0.1 with duration 0.2. 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * All time units are stored in milliseconds. 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @constructor 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function TimelineSlice(title, colorId, start, args) { 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.title = title; 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.start = start; 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.colorId = colorId; 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.args = args; 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.subSlices = []; 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineSlice.prototype = { 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen selected: false, 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen duration: undefined, 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen get end() { 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return this.start + this.duration; 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * A TimelineThread stores all the trace events collected for a particular 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * thread. We organize the slices on a thread by "subrows," where subrow 0 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * has all the root slices, subrow 1 those nested 1 deep, and so on. 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @constructor 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function TimelineThread(parent, tid) { 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.parent = parent; 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.tid = tid; 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.subRows = [[]]; 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineThread.prototype = { 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen getSubrow: function(i) { 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (i >= this.subRows.length) 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.subRows.push([]); 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return this.subRows[i]; 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen updateBounds: function() { 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var slices = this.subRows[0]; 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (slices.length != 0) { 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.minTimestamp = slices[0].start; 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.maxTimestamp = slices[slices.length - 1].end; 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.minTimestamp = undefined; 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.maxTimestamp = undefined; 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * The TimelineProcess represents a single process in the 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * trace. Right now, we keep this around purely for bookkeeping 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * reasons. 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @constructor 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function TimelineProcess(pid) { 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.pid = pid; 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.threads = {}; 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineProcess.prototype = { 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen getThread: function(tid) { 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!this.threads[tid]) 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.threads[tid] = new TimelineThread(this, tid); 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return this.threads[tid]; 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Builds a model from an array of TraceEvent objects. 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @param {Array} events An array of TraceEvents created by 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * TraceEvent.ToJSON(). 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @constructor 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function TimelineModel(events) { 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.processes = {}; 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (events) 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.importEvents(events); 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineModel.prototype = { 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen __proto__: cr.EventTarget.prototype, 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen getProcess: function(pid) { 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!this.processes[pid]) 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.processes[pid] = new TimelineProcess(pid); 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return this.processes[pid]; 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * The import takes an array of json-ified TraceEvents and adds them into 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the TimelineModel as processes, threads, and slices. 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen importEvents: function(events) { 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A ptid is a pid and tid joined together x:y fashion, eg 1024:130 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The ptid is a unique key for a thread in the trace. 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Threadstate 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const numColorIds = 12; 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function ThreadState(tid) { 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.openSlices = []; 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var threadStateByPTID = {}; 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var nameToColorMap = {}; 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function getColor(name) { 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(name in nameToColorMap)) { 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Compute a simplistic hashcode of the string so we get consistent 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // coloring across traces. 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var hash = 0; 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var i = 0; i < name.length; ++i) 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hash = (hash + 37 * hash + name.charCodeAt(i)) % 0xFFFFFFFF; 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen nameToColorMap[name] = hash % numColorIds; 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return nameToColorMap[name]; 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Walk through events 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var eI = 0; eI < events.length; eI++) { 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var event = events[eI]; 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var ptid = event.pid + ':' + event.tid; 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(ptid in threadStateByPTID)) { 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen threadStateByPTID[ptid] = new ThreadState(); 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var state = threadStateByPTID[ptid]; 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (event.ph == 'B') { 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var colorId = getColor(event.name); 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var slice = new TimelineSlice(event.name, colorId, event.ts, 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen event.args); 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen state.openSlices.push(slice); 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (event.ph == 'E') { 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (state.openSlices.length == 0) { 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Ignore E events that that are unmatched. 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var slice = state.openSlices.pop(); 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen slice.duration = event.ts - slice.start; 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Store the slice on the right subrow. 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var thread = this.getProcess(event.pid).getThread(event.tid); 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var subRowIndex = state.openSlices.length; 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen thread.getSubrow(subRowIndex).push(slice); 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Add the slice to the subSlices array of its parent. 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (state.openSlices.length) { 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var parentSlice = state.openSlices[state.openSlices.length - 1]; 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen parentSlice.subSlices.push(slice); 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (event.ph == 'I') { 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(nduca): Implement parsing of immediate events. 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen console.log('Parsing of I-type events not implemented.'); 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen throw new Error('Unrecognized event phase: ' + event.ph + 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen '(' + event.name + ')'); 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.updateBounds(); 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.shiftWorldToMicroseconds(); 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var boost = (this.maxTimestamp - this.minTimestamp) * 0.15; 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.minTimestamp = this.minTimestamp - boost; 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.maxTimestamp = this.maxTimestamp + boost; 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen updateBounds: function() { 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var wmin = Infinity; 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var wmax = -wmin; 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var threads = this.getAllThreads(); 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var tI = 0; tI < threads.length; tI++) { 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var thread = threads[tI]; 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen thread.updateBounds(); 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wmin = Math.min(wmin, thread.minTimestamp); 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wmax = Math.max(wmax, thread.maxTimestamp); 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.minTimestamp = wmin; 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.maxTimestamp = wmax; 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen shiftWorldToMicroseconds: function() { 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var timeBase = this.minTimestamp; 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var threads = this.getAllThreads(); 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var tI = 0; tI < threads.length; tI++) { 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var thread = threads[tI]; 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var tSR = 0; tSR < thread.subRows.length; tSR++) { 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var subRow = thread.subRows[tSR]; 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var tS = 0; tS < subRow.length; tS++) { 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var slice = subRow[tS]; 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen slice.start = (slice.start - timeBase) / 1000; 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen slice.duration /= 1000; 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.updateBounds(); 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen getAllThreads: function() { 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var threads = []; 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var pid in this.processes) { 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var process = this.processes[pid]; 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (var tid in process.threads) { 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen threads.push(process.threads[tid]); 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return threads; 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return { 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineSlice: TimelineSlice, 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineThread: TimelineThread, 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineProcess: TimelineProcess, 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimelineModel: TimelineModel 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}); 254