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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js

Issue 2563383003: DevTools: add extension API to contribute trace events to timeline (Closed)
Patch Set: Review comments + better test Created 4 years 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2014 Google Inc. All rights reserved. 2 * Copyright (C) 2014 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 29 matching lines...) Expand all
40 constructor(model, frameModel, irModel, filters) { 40 constructor(model, frameModel, irModel, filters) {
41 super(); 41 super();
42 this._model = model; 42 this._model = model;
43 this._filters = filters; 43 this._filters = filters;
44 /** @type {?UI.FlameChart.TimelineData} */ 44 /** @type {?UI.FlameChart.TimelineData} */
45 this._timelineData = null; 45 this._timelineData = null;
46 this._frameModel = frameModel; 46 this._frameModel = frameModel;
47 this._irModel = irModel; 47 this._irModel = irModel;
48 this._consoleColorGenerator = 48 this._consoleColorGenerator =
49 new UI.FlameChart.ColorGenerator({min: 30, max: 55}, {min: 70, max: 100, count: 6}, 50, 0.7); 49 new UI.FlameChart.ColorGenerator({min: 30, max: 55}, {min: 70, max: 100, count: 6}, 50, 0.7);
50 this._extensionColorGenerator =
51 new UI.FlameChart.ColorGenerator({min: 210, max: 300}, {min: 70, max: 10 0, count: 6}, 70, 0.7);
50 const font = this.font(); 52 const font = this.font();
51 53
52 this._headerLevel1 = { 54 this._headerLevel1 = {
53 padding: 4, 55 padding: 4,
54 height: 17, 56 height: 17,
55 collapsible: true, 57 collapsible: true,
56 color: UI.themeSupport.patchColor('#222', UI.ThemeSupport.ColorUsage.Foreg round), 58 color: UI.themeSupport.patchColor('#222', UI.ThemeSupport.ColorUsage.Foreg round),
57 font: font, 59 font: font,
58 backgroundColor: UI.themeSupport.patchColor('white', UI.ThemeSupport.Color Usage.Background), 60 backgroundColor: UI.themeSupport.patchColor('white', UI.ThemeSupport.Color Usage.Background),
59 nestingLevel: 0 61 nestingLevel: 0
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 } 97 }
96 98
97 /** 99 /**
98 * @override 100 * @override
99 * @param {number} entryIndex 101 * @param {number} entryIndex
100 * @return {?string} 102 * @return {?string}
101 */ 103 */
102 entryTitle(entryIndex) { 104 entryTitle(entryIndex) {
103 var entryType = this._entryType(entryIndex); 105 var entryType = this._entryType(entryIndex);
104 if (entryType === Timeline.TimelineFlameChartEntryType.Event) { 106 if (entryType === Timeline.TimelineFlameChartEntryType.Event) {
105 var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryI ndex]); 107 const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entr yIndex]);
106 if (event.phase === SDK.TracingModel.Phase.AsyncStepInto || event.phase == = SDK.TracingModel.Phase.AsyncStepPast) 108 if (event.phase === SDK.TracingModel.Phase.AsyncStepInto || event.phase == = SDK.TracingModel.Phase.AsyncStepPast)
107 return event.name + ':' + event.args['step']; 109 return event.name + ':' + event.args['step'];
108 if (event._blackboxRoot) 110 if (event._blackboxRoot)
109 return Common.UIString('Blackboxed'); 111 return Common.UIString('Blackboxed');
110 var name = Timeline.TimelineUIUtils.eventStyle(event).title; 112 var name = Timeline.TimelineUIUtils.eventStyle(event).title;
111 // TODO(yurys): support event dividers 113 // TODO(yurys): support event dividers
112 var detailsText = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(e vent, this._model.targetByEvent(event)); 114 var detailsText = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(e vent, this._model.targetByEvent(event));
113 if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame && detai lsText) 115 if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame && detai lsText)
114 return detailsText; 116 return detailsText;
115 return detailsText ? Common.UIString('%s (%s)', name, detailsText) : name; 117 return detailsText ? Common.UIString('%s (%s)', name, detailsText) : name;
116 } 118 }
119 if (entryType === Timeline.TimelineFlameChartEntryType.ExtensionEvent) {
120 const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entr yIndex]);
121 return event.name;
122 }
117 var title = this._entryIndexToTitle[entryIndex]; 123 var title = this._entryIndexToTitle[entryIndex];
118 if (!title) { 124 if (!title) {
119 title = Common.UIString('Unexpected entryIndex %d', entryIndex); 125 title = Common.UIString('Unexpected entryIndex %d', entryIndex);
120 console.error(title); 126 console.error(title);
121 } 127 }
122 return title; 128 return title;
123 } 129 }
124 130
125 /** 131 /**
126 * @override 132 * @override
(...skipping 19 matching lines...) Expand all
146 /** @type {!Array<!Timeline.TimelineFlameChartEntryType>} */ 152 /** @type {!Array<!Timeline.TimelineFlameChartEntryType>} */
147 this._entryTypeByLevel = []; 153 this._entryTypeByLevel = [];
148 /** @type {!Array<string>} */ 154 /** @type {!Array<string>} */
149 this._entryIndexToTitle = []; 155 this._entryIndexToTitle = [];
150 /** @type {!Array<!Timeline.TimelineFlameChartMarker>} */ 156 /** @type {!Array<!Timeline.TimelineFlameChartMarker>} */
151 this._markers = []; 157 this._markers = [];
152 /** @type {!Map<!Timeline.TimelineCategory, string>} */ 158 /** @type {!Map<!Timeline.TimelineCategory, string>} */
153 this._asyncColorByCategory = new Map(); 159 this._asyncColorByCategory = new Map();
154 /** @type {!Map<!TimelineModel.TimelineIRModel.Phases, string>} */ 160 /** @type {!Map<!TimelineModel.TimelineIRModel.Phases, string>} */
155 this._asyncColorByInteractionPhase = new Map(); 161 this._asyncColorByInteractionPhase = new Map();
162 /** @type {!Array<!{title: string, model: !SDK.TracingModel}>} */
163 this._extensionInfo = [];
156 } 164 }
157 165
158 /** 166 /**
159 * @override 167 * @override
160 * @return {!UI.FlameChart.TimelineData} 168 * @return {!UI.FlameChart.TimelineData}
161 */ 169 */
162 timelineData() { 170 timelineData() {
163 if (this._timelineData) 171 if (this._timelineData)
164 return this._timelineData; 172 return this._timelineData;
165 173
166 this._timelineData = new UI.FlameChart.TimelineData([], [], [], []); 174 this._timelineData = new UI.FlameChart.TimelineData([], [], [], []);
167 175
168 this._minimumBoundary = this._model.minimumRecordTime(); 176 this._minimumBoundary = this._model.minimumRecordTime();
169 this._timeSpan = this._model.isEmpty() ? 1000 : this._model.maximumRecordTim e() - this._minimumBoundary; 177 this._timeSpan = this._model.isEmpty() ? 1000 : this._model.maximumRecordTim e() - this._minimumBoundary;
170 this._currentLevel = 0; 178 this._currentLevel = 0;
171 this._appendFrameBars(this._frameModel.frames()); 179 this._appendFrameBars(this._frameModel.frames());
172 180
173 this._appendHeader(Common.UIString('Interactions'), this._interactionsHeader Level1); 181 this._appendHeader(Common.UIString('Interactions'), this._interactionsHeader Level1);
174 this._appendInteractionRecords(); 182 this._appendInteractionRecords();
175 183
184 var eventEntryType = Timeline.TimelineFlameChartEntryType.Event;
185
176 var asyncEventGroups = TimelineModel.TimelineModel.AsyncEventGroup; 186 var asyncEventGroups = TimelineModel.TimelineModel.AsyncEventGroup;
177 var inputLatencies = this._model.mainThreadAsyncEvents().get(asyncEventGroup s.input); 187 var inputLatencies = this._model.mainThreadAsyncEvents().get(asyncEventGroup s.input);
178 if (inputLatencies && inputLatencies.length) { 188 if (inputLatencies && inputLatencies.length) {
179 var title = Timeline.TimelineUIUtils.titleForAsyncEventGroup(asyncEventGro ups.input); 189 var title = Timeline.TimelineUIUtils.titleForAsyncEventGroup(asyncEventGro ups.input);
180 this._appendAsyncEventsGroup(title, inputLatencies, this._interactionsHead erLevel2); 190 this._appendAsyncEventsGroup(title, inputLatencies, this._interactionsHead erLevel2, eventEntryType);
181 } 191 }
182 var animations = this._model.mainThreadAsyncEvents().get(asyncEventGroups.an imation); 192 var animations = this._model.mainThreadAsyncEvents().get(asyncEventGroups.an imation);
183 if (animations && animations.length) { 193 if (animations && animations.length) {
184 var title = Timeline.TimelineUIUtils.titleForAsyncEventGroup(asyncEventGro ups.animation); 194 var title = Timeline.TimelineUIUtils.titleForAsyncEventGroup(asyncEventGro ups.animation);
185 this._appendAsyncEventsGroup(title, animations, this._interactionsHeaderLe vel2); 195 this._appendAsyncEventsGroup(title, animations, this._interactionsHeaderLe vel2, eventEntryType);
186 } 196 }
187 var threads = this._model.virtualThreads(); 197 var threads = this._model.virtualThreads();
188 if (!Runtime.experiments.isEnabled('timelinePerFrameTrack')) { 198 if (!Runtime.experiments.isEnabled('timelinePerFrameTrack')) {
189 this._appendThreadTimelineData( 199 this._appendThreadTimelineData(
190 Common.UIString('Main'), this._model.mainThreadEvents(), this._model.m ainThreadAsyncEvents(), true); 200 Common.UIString('Main'), this._model.mainThreadEvents(), this._model.m ainThreadAsyncEvents(), true);
191 } else { 201 } else {
192 this._appendThreadTimelineData( 202 this._appendThreadTimelineData(
193 Common.UIString('Page'), this._model.eventsForFrame(TimelineModel.Time lineModel.PageFrame.mainFrameId), 203 Common.UIString('Page'), this._model.eventsForFrame(TimelineModel.Time lineModel.PageFrame.mainFrameId),
194 this._model.mainThreadAsyncEvents(), true); 204 this._model.mainThreadAsyncEvents(), true);
195 for (var frame of this._model.rootFrames()) { 205 for (var frame of this._model.rootFrames()) {
196 // Ignore top frame itself, since it should be part of page events. 206 // Ignore top frame itself, since it should be part of page events.
197 frame.children.forEach(this._appendFrameEvents.bind(this, 0)); 207 frame.children.forEach(this._appendFrameEvents.bind(this, 0));
198 } 208 }
199 } 209 }
200 var compositorThreads = threads.filter(thread => thread.name.startsWith('Com positorTileWorker')); 210 var compositorThreads = threads.filter(thread => thread.name.startsWith('Com positorTileWorker'));
201 var otherThreads = threads.filter(thread => !thread.name.startsWith('Composi torTileWorker')); 211 var otherThreads = threads.filter(thread => !thread.name.startsWith('Composi torTileWorker'));
202 if (compositorThreads.length) { 212 if (compositorThreads.length) {
203 this._appendHeader(Common.UIString('Raster'), this._headerLevel1); 213 this._appendHeader(Common.UIString('Raster'), this._headerLevel1);
204 for (var i = 0; i < compositorThreads.length; ++i) { 214 for (var i = 0; i < compositorThreads.length; ++i) {
205 this._appendSyncEvents( 215 this._appendSyncEvents(
206 compositorThreads[i].events, Common.UIString('Rasterizer Thread %d', i), this._headerLevel2); 216 compositorThreads[i].events, Common.UIString('Rasterizer Thread %d', i), this._headerLevel2,
217 eventEntryType);
207 } 218 }
208 } 219 }
209 this._appendGPUEvents(); 220 this._appendGPUEvents();
210 221
211 otherThreads.forEach( 222 otherThreads.forEach(
212 thread => this._appendThreadTimelineData(thread.name, thread.events, thr ead.asyncEventsByGroup)); 223 thread => this._appendThreadTimelineData(
224 thread.name || Common.UIString('Thread %d', thread.id), thread.event s, thread.asyncEventsByGroup));
225
226 for (let extensionIndex = 0; extensionIndex < this._extensionInfo.length; ex tensionIndex++)
227 this._innerAppendExtensionEvents(extensionIndex);
213 228
214 /** 229 /**
215 * @param {!Timeline.TimelineFlameChartMarker} a 230 * @param {!Timeline.TimelineFlameChartMarker} a
216 * @param {!Timeline.TimelineFlameChartMarker} b 231 * @param {!Timeline.TimelineFlameChartMarker} b
217 */ 232 */
218 function compareStartTime(a, b) { 233 function compareStartTime(a, b) {
219 return a.startTime() - b.startTime(); 234 return a.startTime() - b.startTime();
220 } 235 }
221 236
222 this._markers.sort(compareStartTime); 237 this._markers.sort(compareStartTime);
223 this._timelineData.markers = this._markers; 238 this._timelineData.markers = this._markers;
224 239
225 return this._timelineData; 240 return this._timelineData;
226 } 241 }
227 242
228 /** 243 /**
229 * @param {number} level 244 * @param {number} level
230 * @param {!TimelineModel.TimelineModel.PageFrame} frame 245 * @param {!TimelineModel.TimelineModel.PageFrame} frame
231 */ 246 */
232 _appendFrameEvents(level, frame) { 247 _appendFrameEvents(level, frame) {
233 var events = this._model.eventsForFrame(frame.id); 248 var events = this._model.eventsForFrame(frame.id);
234 var clonedHeader = Object.assign({}, this._headerLevel1); 249 var clonedHeader = Object.assign({}, this._headerLevel1);
235 clonedHeader.nestingLevel = level; 250 clonedHeader.nestingLevel = level;
236 this._appendSyncEvents( 251 this._appendSyncEvents(
237 events, Timeline.TimelineUIUtils.displayNameForFrame(frame), 252 events, Timeline.TimelineUIUtils.displayNameForFrame(frame),
238 /** @type {!UI.FlameChart.GroupStyle} */ (clonedHeader)); 253 /** @type {!UI.FlameChart.GroupStyle} */ (clonedHeader), Timeline.Timeli neFlameChartEntryType.Event);
239 frame.children.forEach(this._appendFrameEvents.bind(this, level + 1)); 254 frame.children.forEach(this._appendFrameEvents.bind(this, level + 1));
240 } 255 }
241 256
242 /** 257 /**
243 * @param {string} threadTitle 258 * @param {string} threadTitle
244 * @param {!Array<!SDK.TracingModel.Event>} syncEvents 259 * @param {!Array<!SDK.TracingModel.Event>} syncEvents
245 * @param {!Map<!TimelineModel.TimelineModel.AsyncEventGroup, !Array<!SDK.Trac ingModel.AsyncEvent>>} asyncEvents 260 * @param {!Map<!TimelineModel.TimelineModel.AsyncEventGroup, !Array<!SDK.Trac ingModel.AsyncEvent>>} asyncEvents
246 * @param {boolean=} forceExpanded 261 * @param {boolean=} forceExpanded
247 */ 262 */
248 _appendThreadTimelineData(threadTitle, syncEvents, asyncEvents, forceExpanded) { 263 _appendThreadTimelineData(threadTitle, syncEvents, asyncEvents, forceExpanded) {
264 var entryType = Timeline.TimelineFlameChartEntryType.Event;
249 this._appendAsyncEvents(asyncEvents); 265 this._appendAsyncEvents(asyncEvents);
250 this._appendSyncEvents(syncEvents, threadTitle, this._headerLevel1, forceExp anded); 266 this._appendSyncEvents(syncEvents, threadTitle, this._headerLevel1, entryTyp e, forceExpanded);
251 } 267 }
252 268
253 /** 269 /**
254 * @param {!Array<!SDK.TracingModel.Event>} events 270 * @param {!Array<!SDK.TracingModel.Event>} events
255 * @param {string} title 271 * @param {string} title
256 * @param {!UI.FlameChart.GroupStyle} style 272 * @param {!UI.FlameChart.GroupStyle} style
273 * @param {!Timeline.TimelineFlameChartEntryType} entryType
257 * @param {boolean=} forceExpanded 274 * @param {boolean=} forceExpanded
258 */ 275 */
259 _appendSyncEvents(events, title, style, forceExpanded) { 276 _appendSyncEvents(events, title, style, entryType, forceExpanded) {
277 var isExtension = entryType === Timeline.TimelineFlameChartEntryType.Extensi onEvent;
260 var openEvents = []; 278 var openEvents = [];
261 var blackboxingEnabled = Runtime.experiments.isEnabled('blackboxJSFramesOnTi meline'); 279 var blackboxingEnabled = !isExtension && Runtime.experiments.isEnabled('blac kboxJSFramesOnTimeline');
262 var maxStackDepth = 0; 280 var maxStackDepth = 0;
263 for (var i = 0; i < events.length; ++i) { 281 for (var i = 0; i < events.length; ++i) {
264 var e = events[i]; 282 var e = events[i];
265 if (TimelineModel.TimelineModel.isMarkerEvent(e)) { 283 if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e)) {
266 this._markers.push(new Timeline.TimelineFlameChartMarker( 284 this._markers.push(new Timeline.TimelineFlameChartMarker(
267 e.startTime, e.startTime - this._model.minimumRecordTime(), 285 e.startTime, e.startTime - this._model.minimumRecordTime(),
268 Timeline.TimelineUIUtils.markerStyleForEvent(e))); 286 Timeline.TimelineUIUtils.markerStyleForEvent(e)));
269 } 287 }
270 if (!SDK.TracingModel.isFlowPhase(e.phase)) { 288 if (!SDK.TracingModel.isFlowPhase(e.phase)) {
271 if (!e.endTime && e.phase !== SDK.TracingModel.Phase.Instant) 289 if (!e.endTime && e.phase !== SDK.TracingModel.Phase.Instant)
272 continue; 290 continue;
273 if (SDK.TracingModel.isAsyncPhase(e.phase)) 291 if (SDK.TracingModel.isAsyncPhase(e.phase))
274 continue; 292 continue;
275 if (!this._isVisible(e)) 293 if (!isExtension && !this._isVisible(e))
276 continue; 294 continue;
277 } 295 }
278 while (openEvents.length && openEvents.peekLast().endTime <= e.startTime) 296 while (openEvents.length && openEvents.peekLast().endTime <= e.startTime)
279 openEvents.pop(); 297 openEvents.pop();
280 e._blackboxRoot = false; 298 e._blackboxRoot = false;
281 if (blackboxingEnabled && this._isBlackboxedEvent(e)) { 299 if (blackboxingEnabled && this._isBlackboxedEvent(e)) {
282 var parent = openEvents.peekLast(); 300 var parent = openEvents.peekLast();
283 if (parent && parent._blackboxRoot) 301 if (parent && parent._blackboxRoot)
284 continue; 302 continue;
285 e._blackboxRoot = true; 303 e._blackboxRoot = true;
286 } 304 }
287 if (title) { 305 if (title) {
288 this._appendHeader(title, style, forceExpanded); 306 this._appendHeader(title, style, forceExpanded);
289 title = ''; 307 title = '';
290 } 308 }
291 309
292 var level = this._currentLevel + openEvents.length; 310 var level = this._currentLevel + openEvents.length;
293 this._appendEvent(e, level); 311 this._appendEvent(e, level);
312 if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e))
313 this._timelineData.entryTotalTimes[this._entryData.length] = undefined;
314
294 maxStackDepth = Math.max(maxStackDepth, openEvents.length + 1); 315 maxStackDepth = Math.max(maxStackDepth, openEvents.length + 1);
295 if (e.endTime) 316 if (e.endTime)
296 openEvents.push(e); 317 openEvents.push(e);
297 } 318 }
298 this._entryTypeByLevel.length = this._currentLevel + maxStackDepth; 319 this._entryTypeByLevel.length = this._currentLevel + maxStackDepth;
299 this._entryTypeByLevel.fill(Timeline.TimelineFlameChartEntryType.Event, this ._currentLevel); 320 this._entryTypeByLevel.fill(entryType, this._currentLevel);
300 this._currentLevel += maxStackDepth; 321 this._currentLevel += maxStackDepth;
301 } 322 }
302 323
303 /** 324 /**
304 * @param {!SDK.TracingModel.Event} event 325 * @param {!SDK.TracingModel.Event} event
305 * @return {boolean} 326 * @return {boolean}
306 */ 327 */
307 _isBlackboxedEvent(event) { 328 _isBlackboxedEvent(event) {
308 if (event.name !== TimelineModel.TimelineModel.RecordType.JSFrame) 329 if (event.name !== TimelineModel.TimelineModel.RecordType.JSFrame)
309 return false; 330 return false;
310 var url = event.args['data']['url']; 331 var url = event.args['data']['url'];
311 return url && this._isBlackboxedURL(url); 332 return url && this._isBlackboxedURL(url);
312 } 333 }
313 334
314 /** 335 /**
315 * @param {string} url 336 * @param {string} url
316 * @return {boolean} 337 * @return {boolean}
317 */ 338 */
318 _isBlackboxedURL(url) { 339 _isBlackboxedURL(url) {
319 return Bindings.blackboxManager.isBlackboxedURL(url); 340 return Bindings.blackboxManager.isBlackboxedURL(url);
320 } 341 }
321 342
322 /** 343 /**
323 * @param {!Map<!TimelineModel.TimelineModel.AsyncEventGroup, !Array<!SDK.Trac ingModel.AsyncEvent>>} asyncEvents 344 * @param {!Map<!TimelineModel.TimelineModel.AsyncEventGroup, !Array<!SDK.Trac ingModel.AsyncEvent>>} asyncEvents
324 */ 345 */
325 _appendAsyncEvents(asyncEvents) { 346 _appendAsyncEvents(asyncEvents) {
347 var entryType = Timeline.TimelineFlameChartEntryType.Event;
326 var groups = TimelineModel.TimelineModel.AsyncEventGroup; 348 var groups = TimelineModel.TimelineModel.AsyncEventGroup;
327 var groupArray = Object.keys(groups).map(key => groups[key]); 349 var groupArray = Object.keys(groups).map(key => groups[key]);
328 350
329 groupArray.remove(groups.animation); 351 groupArray.remove(groups.animation);
330 groupArray.remove(groups.input); 352 groupArray.remove(groups.input);
331 353
332 for (var groupIndex = 0; groupIndex < groupArray.length; ++groupIndex) { 354 for (var groupIndex = 0; groupIndex < groupArray.length; ++groupIndex) {
333 var group = groupArray[groupIndex]; 355 var group = groupArray[groupIndex];
334 var events = asyncEvents.get(group); 356 var events = asyncEvents.get(group);
335 if (!events) 357 if (!events)
336 continue; 358 continue;
337 var title = Timeline.TimelineUIUtils.titleForAsyncEventGroup(group); 359 var title = Timeline.TimelineUIUtils.titleForAsyncEventGroup(group);
338 this._appendAsyncEventsGroup(title, events, this._headerLevel1); 360 this._appendAsyncEventsGroup(title, events, this._headerLevel1, entryType) ;
339 } 361 }
340 } 362 }
341 363
342 /** 364 /**
343 * @param {string} header 365 * @param {string} header
344 * @param {!Array<!SDK.TracingModel.AsyncEvent>} events 366 * @param {!Array<!SDK.TracingModel.AsyncEvent>} events
345 * @param {!UI.FlameChart.GroupStyle} style 367 * @param {!UI.FlameChart.GroupStyle} style
368 * @param {!Timeline.TimelineFlameChartEntryType} entryType
346 */ 369 */
347 _appendAsyncEventsGroup(header, events, style) { 370 _appendAsyncEventsGroup(header, events, style, entryType) {
348 var lastUsedTimeByLevel = []; 371 var lastUsedTimeByLevel = [];
349 var groupHeaderAppended = false; 372 var groupHeaderAppended = false;
350 for (var i = 0; i < events.length; ++i) { 373 for (var i = 0; i < events.length; ++i) {
351 var asyncEvent = events[i]; 374 var asyncEvent = events[i];
352 if (!this._isVisible(asyncEvent)) 375 if (!this._isVisible(asyncEvent))
353 continue; 376 continue;
354 if (!groupHeaderAppended) { 377 if (!groupHeaderAppended) {
355 this._appendHeader(header, style); 378 this._appendHeader(header, style);
356 groupHeaderAppended = true; 379 groupHeaderAppended = true;
357 } 380 }
358 var startTime = asyncEvent.startTime; 381 var startTime = asyncEvent.startTime;
359 var level; 382 var level;
360 for (level = 0; level < lastUsedTimeByLevel.length && lastUsedTimeByLevel[ level] > startTime; ++level) { 383 for (level = 0; level < lastUsedTimeByLevel.length && lastUsedTimeByLevel[ level] > startTime; ++level) {
361 } 384 }
362 this._appendAsyncEvent(asyncEvent, this._currentLevel + level); 385 this._appendAsyncEvent(asyncEvent, this._currentLevel + level);
363 lastUsedTimeByLevel[level] = asyncEvent.endTime; 386 lastUsedTimeByLevel[level] = asyncEvent.endTime;
364 } 387 }
365 this._entryTypeByLevel.length = this._currentLevel + lastUsedTimeByLevel.len gth; 388 this._entryTypeByLevel.length = this._currentLevel + lastUsedTimeByLevel.len gth;
366 this._entryTypeByLevel.fill(Timeline.TimelineFlameChartEntryType.Event, this ._currentLevel); 389 this._entryTypeByLevel.fill(entryType, this._currentLevel);
367 this._currentLevel += lastUsedTimeByLevel.length; 390 this._currentLevel += lastUsedTimeByLevel.length;
368 } 391 }
369 392
370 _appendGPUEvents() { 393 _appendGPUEvents() {
371 if (this._appendSyncEvents(this._model.gpuEvents(), Common.UIString('GPU'), this._headerLevel1, false)) 394 const eventType = Timeline.TimelineFlameChartEntryType.Event
395 const gpuEvents = this._model.gpuEvents();
396 if (this._appendSyncEvents(gpuEvents, Common.UIString('GPU'), this._headerLe vel1, eventType, false))
372 ++this._currentLevel; 397 ++this._currentLevel;
373 } 398 }
374 399
375 _appendInteractionRecords() { 400 _appendInteractionRecords() {
376 this._irModel.interactionRecords().forEach(this._appendSegment, this); 401 this._irModel.interactionRecords().forEach(this._appendSegment, this);
377 this._entryTypeByLevel[this._currentLevel++] = Timeline.TimelineFlameChartEn tryType.InteractionRecord; 402 this._entryTypeByLevel[this._currentLevel++] = Timeline.TimelineFlameChartEn tryType.InteractionRecord;
378 } 403 }
379 404
380 /** 405 /**
381 * @param {!Array.<!TimelineModel.TimelineFrame>} frames 406 * @param {!Array.<!TimelineModel.TimelineFrame>} frames
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 return patchColorAndCache( 502 return patchColorAndCache(
478 this._asyncColorByInteractionPhase, phase, Timeline.TimelineUIUtils. interactionPhaseColor); 503 this._asyncColorByInteractionPhase, phase, Timeline.TimelineUIUtils. interactionPhaseColor);
479 } 504 }
480 var category = Timeline.TimelineUIUtils.eventStyle(event).category; 505 var category = Timeline.TimelineUIUtils.eventStyle(event).category;
481 return patchColorAndCache(this._asyncColorByCategory, category, () => cate gory.color); 506 return patchColorAndCache(this._asyncColorByCategory, category, () => cate gory.color);
482 } 507 }
483 if (type === Timeline.TimelineFlameChartEntryType.Frame) 508 if (type === Timeline.TimelineFlameChartEntryType.Frame)
484 return 'white'; 509 return 'white';
485 if (type === Timeline.TimelineFlameChartEntryType.InteractionRecord) 510 if (type === Timeline.TimelineFlameChartEntryType.InteractionRecord)
486 return 'transparent'; 511 return 'transparent';
512 if (type === Timeline.TimelineFlameChartEntryType.ExtensionEvent) {
513 var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryI ndex]);
514 return this._extensionColorGenerator.colorForID(event.name);
515 }
487 return ''; 516 return '';
488 } 517 }
489 518
490 /** 519 /**
491 * @override 520 * @override
492 * @param {number} entryIndex 521 * @param {number} entryIndex
493 * @param {!CanvasRenderingContext2D} context 522 * @param {!CanvasRenderingContext2D} context
494 * @param {?string} text 523 * @param {?string} text
495 * @param {number} barX 524 * @param {number} barX
496 * @param {number} barY 525 * @param {number} barY
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 */ 604 */
576 forceDecoration(entryIndex) { 605 forceDecoration(entryIndex) {
577 var type = this._entryType(entryIndex); 606 var type = this._entryType(entryIndex);
578 return type === Timeline.TimelineFlameChartEntryType.Frame || 607 return type === Timeline.TimelineFlameChartEntryType.Frame ||
579 type === Timeline.TimelineFlameChartEntryType.Event && 608 type === Timeline.TimelineFlameChartEntryType.Event &&
580 !!TimelineModel.TimelineData.forEvent(/** @type {!SDK.TracingModel.Event } */ (this._entryData[entryIndex])) 609 !!TimelineModel.TimelineData.forEvent(/** @type {!SDK.TracingModel.Event } */ (this._entryData[entryIndex]))
581 .warning; 610 .warning;
582 } 611 }
583 612
584 /** 613 /**
614 * @param {!{title: string, model: !SDK.TracingModel}} entry
615 */
616 appendExtensionEvents(entry) {
617 this._extensionInfo.push(entry);
618 if (this._timelineData)
619 this._innerAppendExtensionEvents(this._extensionInfo.length - 1);
620 }
621
622 /**
623 * @param {number} index
624 */
625 _innerAppendExtensionEvents(index) {
626 var entry = this._extensionInfo[index];
627 var entryType = Timeline.TimelineFlameChartEntryType.ExtensionEvent;
628 var allThreads = [].concat(...entry.model.sortedProcesses().map(process => p rocess.sortedThreads()));
629 if (!allThreads.length)
630 return;
631
632 this._appendHeader(entry.title, this._headerLevel1);
633 for (let thread of allThreads) {
634 this._appendAsyncEventsGroup(thread.name(), thread.asyncEvents(), this._he aderLevel2, entryType);
635 this._appendSyncEvents(thread.events(), thread.name(), this._headerLevel2, entryType, false);
636 }
637 }
638
639 /**
585 * @param {string} title 640 * @param {string} title
586 * @param {!UI.FlameChart.GroupStyle} style 641 * @param {!UI.FlameChart.GroupStyle} style
587 * @param {boolean=} expanded 642 * @param {boolean=} expanded
588 */ 643 */
589 _appendHeader(title, style, expanded) { 644 _appendHeader(title, style, expanded) {
590 this._timelineData.groups.push({startLevel: this._currentLevel, name: title, expanded: expanded, style: style}); 645 this._timelineData.groups.push({startLevel: this._currentLevel, name: title, expanded: expanded, style: style});
591 } 646 }
592 647
593 /** 648 /**
594 * @param {!SDK.TracingModel.Event} event 649 * @param {!SDK.TracingModel.Event} event
595 * @param {number} level 650 * @param {number} level
596 */ 651 */
597 _appendEvent(event, level) { 652 _appendEvent(event, level) {
598 var index = this._entryData.length; 653 var index = this._entryData.length;
599 this._entryData.push(event); 654 this._entryData.push(event);
600 this._timelineData.entryLevels[index] = level; 655 this._timelineData.entryLevels[index] = level;
601 var duration; 656 this._timelineData.entryTotalTimes[index] =
602 if (TimelineModel.TimelineModel.isMarkerEvent(event)) 657 event.duration || Timeline.TimelineFlameChartDataProvider.InstantEventVi sibleDurationMs;
603 duration = undefined;
604 else
605 duration = event.duration || Timeline.TimelineFlameChartDataProvider.Insta ntEventVisibleDurationMs;
606 this._timelineData.entryTotalTimes[index] = duration;
607 this._timelineData.entryStartTimes[index] = event.startTime; 658 this._timelineData.entryStartTimes[index] = event.startTime;
608 } 659 }
609 660
610 /** 661 /**
611 * @param {!SDK.TracingModel.AsyncEvent} asyncEvent 662 * @param {!SDK.TracingModel.AsyncEvent} asyncEvent
612 * @param {number} level 663 * @param {number} level
613 */ 664 */
614 _appendAsyncEvent(asyncEvent, level) { 665 _appendAsyncEvent(asyncEvent, level) {
615 if (SDK.TracingModel.isNestableAsyncPhase(asyncEvent.phase)) { 666 if (SDK.TracingModel.isNestableAsyncPhase(asyncEvent.phase)) {
616 // FIXME: also add steps once we support event nesting in the FlameChart. 667 // FIXME: also add steps once we support event nesting in the FlameChart.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 * @return {boolean} 757 * @return {boolean}
707 */ 758 */
708 _isVisible(event) { 759 _isVisible(event) {
709 return this._filters.every(function(filter) { 760 return this._filters.every(function(filter) {
710 return filter.accept(event); 761 return filter.accept(event);
711 }); 762 });
712 } 763 }
713 }; 764 };
714 765
715 Timeline.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs = 0.001; 766 Timeline.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs = 0.001;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698