Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: Source/devtools/front_end/TimelineTracingView.js

Issue 212683005: Timeline Trace viewer prototype (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebased, extracted model into a file of its own Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 /**
8 * @constructor
9 * @implements {WebInspector.TimelineModeView}
10 * @implements {WebInspector.FlameChartDelegate}
11 * @extends {WebInspector.VBox}
12 * @param {!WebInspector.TimelineModeViewDelegate} delegate
13 */
14 WebInspector.TimelineTracingView = function(delegate)
15 {
16 WebInspector.VBox.call(this);
17 this._delegate = delegate;
18 this._tracingModel = new WebInspector.TracingModel();
19 this.element.classList.add("timeline-flamechart");
20 this.registerRequiredCSS("flameChart.css");
21 this._delegate = delegate;
22 this._dataProvider = new WebInspector.TraceViewFlameChartDataProvider(this._ tracingModel);
23 this._mainView = new WebInspector.FlameChart(this._dataProvider, this, true, true);
24 this._mainView.show(this.element);
25 this._mainView.addEventListener(WebInspector.FlameChart.Events.EntrySelected , this._onEntrySelected, this);
26 }
27
28 WebInspector.TimelineTracingView.prototype = {
29 timelineStarted: function()
30 {
31 if (this._recordingTrace)
32 return;
33 if (!this._boundTraceEventListener)
34 this._boundTraceEventListener = this._onTraceEventsCollected.bind(th is);
35 this._recordingTrace = true;
36 WebInspector.tracingAgent.addEventListener(WebInspector.TracingAgent.Eve nts.EventsCollected, this._boundTraceEventListener);
37 this._tracingModel.reset();
38 WebInspector.tracingAgent.start("", "");
39 },
40
41 timelineStopped: function()
42 {
43 if (!this._recordingTrace)
44 return;
45
46 /**
47 * @this {WebInspector.TimelineTracingView}
48 */
49 function onTraceDataComplete()
50 {
51 WebInspector.tracingAgent.removeEventListener(WebInspector.TracingAg ent.Events.EventsCollected, this._boundTraceEventListener);
52 this.refreshRecords(null);
53 }
54 WebInspector.tracingAgent.stop(onTraceDataComplete.bind(this));
55 this._recordingTrace = false;
56 },
57
58 /**
59 * @param {!WebInspector.Event} event
60 */
61 _onTraceEventsCollected: function(event)
62 {
63 var events = /** @type {!Array.<!WebInspector.TracingAgent.Event>} */ (e vent.data);
64 this._tracingModel.addEvents(events);
65 },
66
67 /**
68 * @param {number} windowStartTime
69 * @param {number} windowEndTime
70 */
71 requestWindowTimes: function(windowStartTime, windowEndTime)
72 {
73 this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
74 },
75
76 wasShown: function()
77 {
78 this._mainView._scheduleUpdate();
79 },
80
81 reset: function()
82 {
83 this._dataProvider.reset();
84 this._mainView.setWindowTimes(0, Infinity);
85 },
86
87 /**
88 * @param {?RegExp} textFilter
89 */
90 refreshRecords: function(textFilter)
91 {
92 this._dataProvider.reset();
93 this._mainView._scheduleUpdate();
94 },
95
96 /**
97 * @param {!WebInspector.TimelineModel.Record} record
98 */
99 addRecord: function(record) {},
100
101 /**
102 * @param {?WebInspector.TimelineModel.Record} record
103 * @param {string=} regex
104 * @param {boolean=} selectRecord
105 */
106 highlightSearchResult: function(record, regex, selectRecord) {},
107
108 /**
109 * @param {number} startTime
110 * @param {number} endTime
111 */
112 setWindowTimes: function(startTime, endTime)
113 {
114 this._mainView.setWindowTimes(startTime, endTime);
115 },
116
117 /**
118 * @param {number} width
119 */
120 setSidebarSize: function(width) {},
121
122 /**
123 * @param {?WebInspector.TimelineModel.Record} record
124 */
125 setSelectedRecord: function(record) {},
126
127 /**
128 * @param {!WebInspector.Event} event
129 */
130 _onEntrySelected: function(event)
131 {
132 },
133
134 __proto__: WebInspector.VBox.prototype
135 };
136
137 /**
138 * @constructor
139 * @implements {WebInspector.FlameChartDataProvider}
140 * @param {!WebInspector.TracingModel} model
141 */
142 WebInspector.TraceViewFlameChartDataProvider = function(model)
143 {
144 WebInspector.FlameChartDataProvider.call(this);
145 this._model = model;
146 this._font = "bold 12px " + WebInspector.fontFamily();
147 this._palette = new WebInspector.TraceViewPalette();
148 var dummyEventPayload = {
149 cat: "dummy",
150 pid: 0,
151 tid: 0,
152 ts: 0,
153 ph: "dummy",
154 name: "dummy",
155 args: {},
156 dur: 0,
157 id: 0,
158 s: ""
159 }
160 this._processHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPa yload, 0);
161 this._threadHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPay load, 0);
162 }
163
164 WebInspector.TraceViewFlameChartDataProvider.prototype = {
165 /**
166 * @return {number}
167 */
168 barHeight: function()
169 {
170 return 20;
171 },
172
173 /**
174 * @return {number}
175 */
176 textBaseline: function()
177 {
178 return 6;
179 },
180
181 /**
182 * @return {number}
183 */
184 textPadding: function()
185 {
186 return 5;
187 },
188
189 /**
190 * @param {number} entryIndex
191 * @return {string}
192 */
193 entryFont: function(entryIndex)
194 {
195 return this._font;
196 },
197
198 /**
199 * @param {number} entryIndex
200 * @return {?string}
201 */
202 entryTitle: function(entryIndex)
203 {
204 var record = this._records[entryIndex];
205 if (record === this._threadHeaderRecord || record === this._processHeade rRecord)
206 return this._headerTitles[entryIndex]
207 return record.name;
208 },
209
210 /**
211 * @param {number} startTime
212 * @param {number} endTime
213 * @return {?Array.<number>}
214 */
215 dividerOffsets: function(startTime, endTime)
216 {
217 return null;
218 },
219
220 reset: function()
221 {
222 this._timelineData = null;
223 /** @type {!Array.<!WebInspector.TracingModel.Event>} */
224 this._records = [];
225 },
226
227 /**
228 * @return {!WebInspector.FlameChart.TimelineData}
229 */
230 timelineData: function()
231 {
232 if (this._timelineData)
233 return this._timelineData;
234
235 /**
236 * @type {?WebInspector.FlameChart.TimelineData}
237 */
238 this._timelineData = {
239 entryLevels: [],
240 entryTotalTimes: [],
241 entryOffsets: []
242 };
243
244 this._currentLevel = 0;
245 this._headerTitles = {};
246 this._zeroTime = this._model.minimumRecordTime() || 0;
247 this._timeSpan = Math.max((this._model.maximumRecordTime() || 0) - this. _zeroTime, 1000000);
248 var processes = this._model.sortedProcesses();
249 for (var i = 0; i < processes.length; ++i) {
250 this._appendHeaderRecord(processes[i].name(), this._processHeaderRec ord);
251 var threads = processes[i].sortedThreads();
252 for (var j = 0; j < threads.length; ++j) {
253 this._appendHeaderRecord(threads[j].name(), this._threadHeaderRe cord);
254 var events = threads[j].events();
255 for (var k = 0; k < events.length; ++k) {
256 if (events[k].duration)
257 this._appendRecord(events[k]);
258 }
259 this._currentLevel += threads[j].maxStackDepth();
260 }
261 ++this._currentLevel;
262 }
263 return this._timelineData;
264 },
265
266 /**
267 * @return {number}
268 */
269 zeroTime: function()
270 {
271 return this._toTimelineTime(this._zeroTime);
272 },
273
274 /**
275 * @return {number}
276 */
277 totalTime: function()
278 {
279 return this._toTimelineTime(this._timeSpan);
280 },
281
282 /**
283 * @return {number}
284 */
285 maxStackDepth: function()
286 {
287 return this._currentLevel;
288 },
289
290 /**
291 * @param {number} entryIndex
292 * @return {?Array.<!{title: string, text: string}>}
293 */
294 prepareHighlightedEntryInfo: function(entryIndex)
295 {
296 return null;
297 },
298
299 /**
300 * @param {number} entryIndex
301 * @return {boolean}
302 */
303 canJumpToEntry: function(entryIndex)
304 {
305 return false;
306 },
307
308 /**
309 * @param {number} entryIndex
310 * @return {!string}
311 */
312 entryColor: function(entryIndex)
313 {
314 var record = this._records[entryIndex];
315 if (record === this._processHeaderRecord)
316 return "#555";
317 if (record === this._threadHeaderRecord)
318 return "#777";
319 return this._palette.colorForString(record.name);
320 },
321
322
323 /**
324 * @param {number} entryIndex
325 * @param {!CanvasRenderingContext2D} context
326 * @param {?string} text
327 * @param {number} barX
328 * @param {number} barY
329 * @param {number} barWidth
330 * @param {number} barHeight
331 * @param {function(number):number} offsetToPosition
332 * @return {boolean}
333 */
334 decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, bar Height, offsetToPosition)
335 {
336 return false;
337 },
338
339 /**
340 * @param {number} entryIndex
341 * @return {boolean}
342 */
343 forceDecoration: function(entryIndex)
344 {
345 return false;
346 },
347
348 /**
349 * @param {number} entryIndex
350 * @return {?{startTimeOffset: number, endTimeOffset: number}}
351 */
352 highlightTimeRange: function(entryIndex)
353 {
354 return null;
355 },
356
357 /**
358 * @return {number}
359 */
360 paddingLeft: function()
361 {
362 return 0;
363 },
364
365 /**
366 * @param {number} entryIndex
367 * @return {!string}
368 */
369 textColor: function(entryIndex)
370 {
371 return "white";
372 },
373
374 /**
375 * @param {string} title
376 * @param {!WebInspector.TracingModel.Event} record
377 */
378 _appendHeaderRecord: function(title, record)
379 {
380 var index = this._records.length;
381 this._records.push(record);
382 this._timelineData.entryLevels[index] = this._currentLevel++;
383 this._timelineData.entryTotalTimes[index] = this.totalTime();
384 this._timelineData.entryOffsets[index] = this._toTimelineTime(0);
385 this._headerTitles[index] = title;
386 },
387
388 /**
389 * @param {!WebInspector.TracingModel.Event} record
390 */
391 _appendRecord: function(record)
392 {
393 var index = this._records.length;
394 this._records.push(record);
395 this._timelineData.entryLevels[index] = this._currentLevel + record.leve l;
396 this._timelineData.entryTotalTimes[index] = this._toTimelineTime(record. duration);
397 this._timelineData.entryOffsets[index] = this._toTimelineTime(record.sta rtTime - this._zeroTime);
398 },
399
400 /**
401 * @param {number} time
402 * @return {number}
403 */
404 _toTimelineTime: function(time)
405 {
406 return time / 1000;
407 }
408 }
409
410 // The below logic is shamelessly stolen from https://code.google.com/p/trace-vi ewer/source/browse/trunk/trace_viewer/tracing/color_scheme.js
411
412 /**
413 * @constructor
414 */
415 WebInspector.TraceViewPalette = function()
416 {
417 this._palette = WebInspector.TraceViewPalette._paletteBase.map(WebInspector. TraceViewPalette._rgbToString);
418 }
419
420 WebInspector.TraceViewPalette._paletteBase = [
421 [138, 113, 152],
422 [175, 112, 133],
423 [127, 135, 225],
424 [93, 81, 137],
425 [116, 143, 119],
426 [178, 214, 122],
427 [87, 109, 147],
428 [119, 155, 95],
429 [114, 180, 160],
430 [132, 85, 103],
431 [157, 210, 150],
432 [148, 94, 86],
433 [164, 108, 138],
434 [139, 191, 150],
435 [110, 99, 145],
436 [80, 129, 109],
437 [125, 140, 149],
438 [93, 124, 132],
439 [140, 85, 140],
440 [104, 163, 162],
441 [132, 141, 178],
442 [131, 105, 147],
443 [135, 183, 98],
444 [152, 134, 177],
445 [141, 188, 141],
446 [133, 160, 210],
447 [126, 186, 148],
448 [112, 198, 205],
449 [180, 122, 195],
450 [203, 144, 152]
451 ];
452
453 /**
454 * @param {string} string
455 * @return {number}
456 */
457 WebInspector.TraceViewPalette._stringHash = function(string)
458 {
459 var hash = 0;
460 for (var i = 0; i < string.length; ++i)
461 hash = (hash + 37 * hash + 11 * string.charCodeAt(i)) % 0xFFFFFFFF;
462 return hash;
463 }
464
465 /**
466 * @param {!Array.<number>} rgb
467 * @return {string}
468 */
469 WebInspector.TraceViewPalette._rgbToString = function(rgb)
470 {
471 return "rgb(" + rgb.join(",") + ")";
472 }
473
474 WebInspector.TraceViewPalette.prototype = {
475 /**
476 * @param {string} string
477 * @return {string}
478 */
479 colorForString: function(string)
480 {
481 var hash = WebInspector.TraceViewPalette._stringHash(string);
482 return this._palette[hash % this._palette.length];
483 }
484 };
OLDNEW
« no previous file with comments | « Source/devtools/front_end/TimelinePowerGraph.js ('k') | Source/devtools/front_end/TimelineView.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698