Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js |
| index 585c9d0b0a957618b08fbe7ecd49486e03af8988..fe1c9e28836fed8d3e85c760eceb7586d197a0c7 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js |
| @@ -76,7 +76,9 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| this._headerLevel1 = buildGroupStyle({shareHeaderLine: false}); |
| this._headerLevel2 = buildGroupStyle({padding: 2, nestingLevel: 1, collapsible: false}); |
| this._staticHeader = buildGroupStyle({collapsible: false}); |
| - this._framesHeader = buildGroupStyle({useFirstLineForOverview: true, shareHeaderLine: true, itemsHeight: 150}); |
| + this._framesHeader = buildGroupStyle({useFirstLineForOverview: true}); |
| + this._screenshotsHeader = |
| + buildGroupStyle({useFirstLineForOverview: true, nestingLevel: 1, collapsible: false, itemsHeight: 150}); |
| this._interactionsHeaderLevel1 = buildGroupStyle({useFirstLineForOverview: true}); |
| this._interactionsHeaderLevel2 = buildGroupStyle({padding: 2, nestingLevel: 1}); |
| @@ -100,7 +102,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| */ |
| entryTitle(entryIndex) { |
| var entryType = this._entryType(entryIndex); |
| - if (entryType === Timeline.TimelineFlameChartEntryType.Event) { |
| + if (entryType === Timeline.TimelineFlameChartDataProvider.EntryType.Event) { |
|
caseq
2017/05/10 18:40:28
nit: consider aliasing EntryType to something.
alph
2017/05/10 19:22:38
Done.
|
| var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); |
| if (event.phase === SDK.TracingModel.Phase.AsyncStepInto || event.phase === SDK.TracingModel.Phase.AsyncStepPast) |
| return event.name + ':' + event.args['step']; |
| @@ -113,10 +115,12 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| return detailsText; |
| return detailsText ? Common.UIString('%s (%s)', name, detailsText) : name; |
| } |
| - if (entryType === Timeline.TimelineFlameChartEntryType.ExtensionEvent) { |
| + if (entryType === Timeline.TimelineFlameChartDataProvider.EntryType.ExtensionEvent) { |
| var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); |
| return event.name; |
| } |
| + if (entryType === Timeline.TimelineFlameChartDataProvider.EntryType.Screenshot) |
| + return ''; |
| var title = this._entryIndexToTitle[entryIndex]; |
| if (!title) { |
| title = Common.UIString('Unexpected entryIndex %d', entryIndex); |
| @@ -147,11 +151,11 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| reset() { |
| this._currentLevel = 0; |
| this._timelineData = null; |
| - /** @type {!Array<!SDK.TracingModel.Event|!TimelineModel.TimelineFrame|!TimelineModel.TimelineIRModel.Phases>} */ |
| + /** @type {!Array<!SDK.FilmStripModel.Frame|!SDK.TracingModel.Event|!TimelineModel.TimelineFrame|!TimelineModel.TimelineIRModel.Phases>} */ |
| this._entryData = []; |
| /** @type {!Array<!SDK.TracingModel.Event>} */ |
| this._entryParent = []; |
| - /** @type {!Array<!Timeline.TimelineFlameChartEntryType>} */ |
| + /** @type {!Array<!Timeline.TimelineFlameChartDataProvider.EntryType>} */ |
| this._entryTypeByLevel = []; |
| /** @type {!Array<string>} */ |
| this._entryIndexToTitle = []; |
| @@ -163,8 +167,8 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| this._asyncColorByInteractionPhase = new Map(); |
| /** @type {!Array<!{title: string, model: !SDK.TracingModel}>} */ |
| this._extensionInfo = []; |
| - /** @type {!Map<!TimelineModel.TimelineFrame, ?Image>} */ |
| - this._frameImageCache = new Map(); |
| + /** @type {!Map<!SDK.FilmStripModel.Frame, ?Image>} */ |
| + this._screenshotImageCache = new Map(); |
| } |
| /** |
| @@ -193,12 +197,12 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| this._timeSpan = this._model.isEmpty() ? 1000 : this._model.maximumRecordTime() - this._minimumBoundary; |
| this._currentLevel = 0; |
| - this._appendFrameBars(this._performanceModel.frames()); |
| + this._appendFrameBars(); |
| this._appendHeader(Common.UIString('Interactions'), this._interactionsHeaderLevel1); |
| this._appendInteractionRecords(); |
| - var eventEntryType = Timeline.TimelineFlameChartEntryType.Event; |
| + var eventEntryType = Timeline.TimelineFlameChartDataProvider.EntryType.Event; |
| var asyncEventGroups = TimelineModel.TimelineModel.AsyncEventGroup; |
| var inputLatencies = this._model.mainThreadAsyncEvents().get(asyncEventGroups.input); |
| @@ -243,15 +247,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| for (let extensionIndex = 0; extensionIndex < this._extensionInfo.length; extensionIndex++) |
| this._innerAppendExtensionEvents(extensionIndex); |
| - /** |
| - * @param {!Timeline.TimelineFlameChartMarker} a |
| - * @param {!Timeline.TimelineFlameChartMarker} b |
| - */ |
| - function compareStartTime(a, b) { |
| - return a.startTime() - b.startTime(); |
| - } |
| - |
| - this._markers.sort(compareStartTime); |
| + this._markers.sort((a, b) => a.startTime() - b.startTime()); |
| this._timelineData.markers = this._markers; |
| this._flowEventIndexById.clear(); |
| @@ -284,7 +280,8 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| clonedHeader.nestingLevel = level; |
| this._appendSyncEvents( |
| events, Timeline.TimelineUIUtils.displayNameForFrame(frame), |
| - /** @type {!PerfUI.FlameChart.GroupStyle} */ (clonedHeader), Timeline.TimelineFlameChartEntryType.Event); |
| + /** @type {!PerfUI.FlameChart.GroupStyle} */ (clonedHeader), |
| + Timeline.TimelineFlameChartDataProvider.EntryType.Event); |
| frame.children.forEach(this._appendFrameEvents.bind(this, level + 1)); |
| } |
| @@ -295,7 +292,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| * @param {boolean=} forceExpanded |
| */ |
| _appendThreadTimelineData(threadTitle, syncEvents, asyncEvents, forceExpanded) { |
| - var entryType = Timeline.TimelineFlameChartEntryType.Event; |
| + var entryType = Timeline.TimelineFlameChartDataProvider.EntryType.Event; |
| this._appendAsyncEvents(asyncEvents); |
| this._appendSyncEvents(syncEvents, threadTitle, this._headerLevel1, entryType, forceExpanded); |
| } |
| @@ -304,11 +301,11 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| * @param {!Array<!SDK.TracingModel.Event>} events |
| * @param {string} title |
| * @param {!PerfUI.FlameChart.GroupStyle} style |
| - * @param {!Timeline.TimelineFlameChartEntryType} entryType |
| + * @param {!Timeline.TimelineFlameChartDataProvider.EntryType} entryType |
| * @param {boolean=} forceExpanded |
| */ |
| _appendSyncEvents(events, title, style, entryType, forceExpanded) { |
| - var isExtension = entryType === Timeline.TimelineFlameChartEntryType.ExtensionEvent; |
| + var isExtension = entryType === Timeline.TimelineFlameChartDataProvider.EntryType.ExtensionEvent; |
| var openEvents = []; |
| var flowEventsEnabled = Runtime.experiments.isEnabled('timelineFlowEvents'); |
| var blackboxingEnabled = !isExtension && Runtime.experiments.isEnabled('blackboxJSFramesOnTimeline'); |
| @@ -383,7 +380,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| * @param {!Map<!TimelineModel.TimelineModel.AsyncEventGroup, !Array<!SDK.TracingModel.AsyncEvent>>} asyncEvents |
| */ |
| _appendAsyncEvents(asyncEvents) { |
| - var entryType = Timeline.TimelineFlameChartEntryType.Event; |
| + var entryType = Timeline.TimelineFlameChartDataProvider.EntryType.Event; |
| var groups = TimelineModel.TimelineModel.AsyncEventGroup; |
| var groupArray = Object.keys(groups).map(key => groups[key]); |
| @@ -404,7 +401,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| * @param {string} header |
| * @param {!Array<!SDK.TracingModel.AsyncEvent>} events |
| * @param {!PerfUI.FlameChart.GroupStyle} style |
| - * @param {!Timeline.TimelineFlameChartEntryType} entryType |
| + * @param {!Timeline.TimelineFlameChartDataProvider.EntryType} entryType |
| */ |
| _appendAsyncEventsGroup(header, events, style, entryType) { |
| var lastUsedTimeByLevel = []; |
| @@ -430,7 +427,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| } |
| _appendGPUEvents() { |
| - var eventType = Timeline.TimelineFlameChartEntryType.Event; |
| + var eventType = Timeline.TimelineFlameChartDataProvider.EntryType.Event; |
| var gpuEvents = this._model.gpuEvents(); |
| if (this._appendSyncEvents(gpuEvents, Common.UIString('GPU'), this._headerLevel1, eventType, false)) |
| ++this._currentLevel; |
| @@ -438,30 +435,45 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| _appendInteractionRecords() { |
| this._performanceModel.interactionRecords().forEach(this._appendSegment, this); |
| - this._entryTypeByLevel[this._currentLevel++] = Timeline.TimelineFlameChartEntryType.InteractionRecord; |
| + this._entryTypeByLevel[this._currentLevel++] = Timeline.TimelineFlameChartDataProvider.EntryType.InteractionRecord; |
| } |
| - /** |
| - * @param {!Array.<!TimelineModel.TimelineFrame>} frames |
| - */ |
| - _appendFrameBars(frames) { |
| - var hasFilmStrip = !!this._performanceModel.filmStripModel().frames().length; |
| + _appendFrameBars() { |
| + var screenshots = this._performanceModel.filmStripModel().frames(); |
| + var hasFilmStrip = !!screenshots.length; |
| this._framesHeader.collapsible = hasFilmStrip; |
| this._appendHeader(Common.UIString('Frames'), this._framesHeader); |
| this._frameGroup = this._timelineData.groups.peekLast(); |
| var style = Timeline.TimelineUIUtils.markerStyleForFrame(); |
| - this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartEntryType.Frame; |
| - for (var frame of frames) { |
| + this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartDataProvider.EntryType.Frame; |
| + for (var frame of this._performanceModel.frames()) { |
| this._markers.push(new Timeline.TimelineFlameChartMarker( |
| frame.startTime, frame.startTime - this._model.minimumRecordTime(), style)); |
| this._appendFrame(frame); |
| } |
| ++this._currentLevel; |
| + if (!hasFilmStrip) |
| + return; |
| + this._appendHeader('', this._screenshotsHeader); |
| + this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartDataProvider.EntryType.Screenshot; |
| + var prevTimestamp; |
| + for (var screenshot of screenshots) { |
| + var index = this._entryData.length; |
| + this._entryData.push(screenshot); |
| + this._timelineData.entryLevels[index] = this._currentLevel; |
| + this._timelineData.entryStartTimes[index] = screenshot.timestamp; |
| + if (prevTimestamp) |
| + this._timelineData.entryTotalTimes[index - 1] = screenshot.timestamp - prevTimestamp; |
| + prevTimestamp = screenshot.timestamp; |
| + } |
| + this._timelineData.entryTotalTimes[this._timelineData.entryTotalTimes.length - 1] = |
| + this._model.maximumRecordTime() - screenshots.peekLast().timestamp; |
|
caseq
2017/05/10 18:40:28
just use prevTimestamp?
alph
2017/05/10 19:22:38
Done.
|
| + ++this._currentLevel; |
| } |
| /** |
| * @param {number} entryIndex |
| - * @return {!Timeline.TimelineFlameChartEntryType} |
| + * @return {!Timeline.TimelineFlameChartDataProvider.EntryType} |
| */ |
| _entryType(entryIndex) { |
| return this._entryTypeByLevel[this._timelineData.entryLevels[entryIndex]]; |
| @@ -477,7 +489,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| var title; |
| var warning; |
| var type = this._entryType(entryIndex); |
| - if (type === Timeline.TimelineFlameChartEntryType.Event) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) { |
| var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); |
| var totalTime = event.duration; |
| var selfTime = event.selfTime; |
| @@ -490,7 +502,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| } |
| title = this.entryTitle(entryIndex); |
| warning = Timeline.TimelineUIUtils.eventWarning(event); |
| - } else if (type === Timeline.TimelineFlameChartEntryType.Frame) { |
| + } else if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) { |
| var frame = /** @type {!TimelineModel.TimelineFrame} */ (this._entryData[entryIndex]); |
| time = Common.UIString( |
| '%s ~ %.0f\xa0fps', Number.preciseMillisToString(frame.duration, 1), (1000 / frame.duration)); |
| @@ -532,7 +544,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| } |
| var type = this._entryType(entryIndex); |
| - if (type === Timeline.TimelineFlameChartEntryType.Event) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) { |
|
caseq
2017/05/10 18:40:28
nit: consider aliasing EntryType to something.
alph
2017/05/10 19:22:38
Done.
|
| var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); |
| if (!SDK.TracingModel.isAsyncPhase(event.phase)) |
| return this._colorForEvent(event); |
| @@ -548,11 +560,11 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| var category = Timeline.TimelineUIUtils.eventStyle(event).category; |
| return patchColorAndCache(this._asyncColorByCategory, category, () => category.color); |
| } |
| - if (type === Timeline.TimelineFlameChartEntryType.Frame) |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) |
| return 'white'; |
| - if (type === Timeline.TimelineFlameChartEntryType.InteractionRecord) |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.InteractionRecord) |
| return 'transparent'; |
| - if (type === Timeline.TimelineFlameChartEntryType.ExtensionEvent) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.ExtensionEvent) { |
| var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); |
| return this._extensionColorGenerator.colorForID(event.name); |
| } |
| @@ -576,40 +588,45 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| context.fillStyle = frame.idle ? 'white' : (frame.hasWarnings() ? '#fad1d1' : '#d7f0d1'); |
| context.fillRect(barX, barY, barWidth, barHeight); |
| - var headerHeight = 17; |
| var frameDurationText = Number.preciseMillisToString(frame.duration, 1); |
| var textWidth = context.measureText(frameDurationText).width; |
| if (textWidth <= barWidth) { |
| - var font = this.entryFont(entryIndex); |
| - if (font) |
| - context.font = font; |
| context.fillStyle = this.textColor(entryIndex); |
| - context.fillText(frameDurationText, barX + (barWidth - textWidth) / 2, barY + headerHeight - 4); |
| + context.fillText(frameDurationText, barX + (barWidth - textWidth) / 2, barY + barHeight - 4); |
| } |
| + } |
| - var imageHeight = barHeight - headerHeight; |
| - if (imageHeight < headerHeight) |
| + /** |
| + * @param {number} entryIndex |
| + * @param {!CanvasRenderingContext2D} context |
| + * @param {number} barX |
| + * @param {number} barY |
| + * @param {number} barWidth |
| + * @param {number} barHeight |
| + */ |
| + async _drawScreenshot(entryIndex, context, barX, barY, barWidth, barHeight) { |
| + var screenshot = /** @type {!SDK.FilmStripModel.Frame} */ (this._entryData[entryIndex]); |
| + if (!this._screenshotImageCache.has(screenshot)) { |
| + this._screenshotImageCache.set(screenshot, null); |
| + var data = await screenshot.imageDataPromise(); |
| + var image = await UI.loadImageFromData(data); |
| + this._screenshotImageCache.set(screenshot, image); |
| + this.dispatchEventToListeners(Timeline.TimelineFlameChartDataProvider.Events.DataChanged); |
| return; |
| - if (!this._frameImageCache.has(frame)) { |
| - this._frameImageCache.set(frame, null); // Mark the image promise is in flight. |
| - var modelFrame = this._performanceModel.filmStripModelFrame(frame); |
| - if (modelFrame) { |
| - modelFrame.imageDataPromise().then(data => UI.loadImageFromData(data)).then(image => { |
| - this._frameImageCache.set(frame, image); |
| - this.dispatchEventToListeners(Timeline.TimelineFlameChartDataProvider.Events.DataChanged); |
| - }); |
| - } |
| } |
| - var image = this._frameImageCache.get(frame); |
| + context.fillStyle = '#eee'; |
| + context.fillRect(barX, barY, barWidth, barHeight); |
| + var image = this._screenshotImageCache.get(screenshot); |
| if (!image) |
| return; |
| - var imageX = barX; |
| - var imageY = barY + headerHeight; |
| + var imageX = barX + 1; |
| + var imageY = barY + 1; |
| + var imageHeight = barHeight - 2; |
| var scale = imageHeight / image.naturalHeight; |
| var imageWidth = image.naturalWidth * scale; |
| context.save(); |
| context.beginPath(); |
| - context.rect(imageX, imageY, barWidth, imageHeight); |
| + context.rect(imageX, imageY, barWidth - 2, imageHeight); |
| context.clip(); |
| context.drawImage(image, imageX, imageY, imageWidth, imageHeight); |
| context.restore(); |
| @@ -631,12 +648,18 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| decorateEntry(entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixels) { |
| var data = this._entryData[entryIndex]; |
| var type = this._entryType(entryIndex); |
| - if (type === Timeline.TimelineFlameChartEntryType.Frame) { |
| + |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) { |
|
caseq
2017/05/10 18:40:28
ditto.
alph
2017/05/10 19:22:38
Done.
|
| this._drawFrame(entryIndex, context, text, barX, barY, barWidth, barHeight); |
| return true; |
| } |
| - if (type === Timeline.TimelineFlameChartEntryType.InteractionRecord) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Screenshot) { |
| + this._drawScreenshot(entryIndex, context, barX, barY, barWidth, barHeight); |
| + return true; |
| + } |
| + |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.InteractionRecord) { |
| var color = Timeline.TimelineUIUtils.interactionPhaseColor( |
| /** @type {!TimelineModel.TimelineIRModel.Phases} */ (data)); |
| context.fillStyle = color; |
| @@ -646,7 +669,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| return false; |
| } |
| - if (type === Timeline.TimelineFlameChartEntryType.Event) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) { |
| var event = /** @type {!SDK.TracingModel.Event} */ (data); |
| if (event.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) { |
| var timeWaitingForMainThread = TimelineModel.TimelineData.forEvent(event).timeWaitingForMainThread; |
| @@ -689,10 +712,12 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| */ |
| forceDecoration(entryIndex) { |
| var type = this._entryType(entryIndex); |
| - if (type === Timeline.TimelineFlameChartEntryType.Frame) |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) |
|
caseq
2017/05/10 18:40:28
ditto.
alph
2017/05/10 19:22:38
Done.
|
| + return true; |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Screenshot) |
| return true; |
| - if (type === Timeline.TimelineFlameChartEntryType.Event) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) { |
| var event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]); |
| return !!TimelineModel.TimelineData.forEvent(event).warning; |
| } |
| @@ -713,7 +738,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| */ |
| _innerAppendExtensionEvents(index) { |
| var entry = this._extensionInfo[index]; |
| - var entryType = Timeline.TimelineFlameChartEntryType.ExtensionEvent; |
| + var entryType = Timeline.TimelineFlameChartDataProvider.EntryType.ExtensionEvent; |
| var allThreads = [].concat(...entry.model.sortedProcesses().map(process => process.sortedThreads())); |
| if (!allThreads.length) |
| return; |
| @@ -845,10 +870,10 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| createSelection(entryIndex) { |
| var type = this._entryType(entryIndex); |
| var timelineSelection = null; |
| - if (type === Timeline.TimelineFlameChartEntryType.Event) { |
| + if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) { |
| timelineSelection = Timeline.TimelineSelection.fromTraceEvent( |
| /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex])); |
| - } else if (type === Timeline.TimelineFlameChartEntryType.Frame) { |
| + } else if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) { |
| timelineSelection = Timeline.TimelineSelection.fromFrame( |
| /** @type {!TimelineModel.TimelineFrame} */ (this._entryData[entryIndex])); |
| } |
| @@ -961,7 +986,7 @@ Timeline.TimelineFlameChartDataProvider = class extends Common.Object { |
| * @return {?SDK.TracingModel.Event} |
| */ |
| eventByIndex(entryIndex) { |
| - return this._entryType(entryIndex) === Timeline.TimelineFlameChartEntryType.Event ? |
| + return this._entryType(entryIndex) === Timeline.TimelineFlameChartDataProvider.EntryType.Event ? |
| /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]) : |
| null; |
| } |
| @@ -981,3 +1006,12 @@ Timeline.TimelineFlameChartDataProvider._indexSymbol = Symbol('index'); |
| Timeline.TimelineFlameChartDataProvider.Events = { |
| DataChanged: Symbol('DataChanged') |
| }; |
| + |
| +/** @enum {symbol} */ |
| +Timeline.TimelineFlameChartDataProvider.EntryType = { |
| + Frame: Symbol('Frame'), |
| + Event: Symbol('Event'), |
| + InteractionRecord: Symbol('InteractionRecord'), |
| + ExtensionEvent: Symbol('ExtensionEvent'), |
| + Screenshot: Symbol('Screenshot'), |
| +}; |