diff --git a/browser/devtools/jar.mn b/browser/devtools/jar.mn index b8999907a87e..55c1c4410675 100644 --- a/browser/devtools/jar.mn +++ b/browser/devtools/jar.mn @@ -93,6 +93,7 @@ browser.jar: content/browser/devtools/performance/views/overview.js (performance/views/overview.js) content/browser/devtools/performance/views/details.js (performance/views/details.js) content/browser/devtools/performance/views/call-tree.js (performance/views/call-tree.js) + content/browser/devtools/performance/views/waterfall.js (performance/views/waterfall.js) #endif content/browser/devtools/responsivedesign/resize-commands.js (responsivedesign/resize-commands.js) content/browser/devtools/commandline.css (commandline/commandline.css) diff --git a/browser/devtools/performance/controller.js b/browser/devtools/performance/controller.js index b18b6e24ee77..c5e600776081 100644 --- a/browser/devtools/performance/controller.js +++ b/browser/devtools/performance/controller.js @@ -23,6 +23,10 @@ devtools.lazyRequireGetter(this, "L10N", "devtools/profiler/global", true); devtools.lazyImporter(this, "LineGraphWidget", "resource:///modules/devtools/Graphs.jsm"); +devtools.lazyRequireGetter(this, "Waterfall", + "devtools/timeline/waterfall", true); +devtools.lazyRequireGetter(this, "MarkerDetails", + "devtools/timeline/marker-details", true); devtools.lazyRequireGetter(this, "CallView", "devtools/profiler/tree-view", true); devtools.lazyRequireGetter(this, "ThreadNode", @@ -47,8 +51,14 @@ const EVENTS = { // Emitted by the OverviewView when a selection range has been removed OVERVIEW_RANGE_CLEARED: "Performance:UI:OverviewRangeCleared", + // Emitted by the DetailsView when a subview is selected + DETAILS_VIEW_SELECTED: "Performance:UI:DetailsViewSelected", + // Emitted by the CallTreeView when a call tree has been rendered - CALL_TREE_RENDERED: "Performance:UI:CallTreeRendered" + CALL_TREE_RENDERED: "Performance:UI:CallTreeRendered", + + // Emitted by the WaterfallView when it has been rendered + WATERFALL_RENDERED: "Performance:UI:WaterfallRendered" }; /** @@ -112,6 +122,7 @@ let PerformanceController = { PerformanceView.on(EVENTS.UI_START_RECORDING, this.startRecording); PerformanceView.on(EVENTS.UI_STOP_RECORDING, this.stopRecording); gFront.on("ticks", this._onTimelineData); + gFront.on("markers", this._onTimelineData); }, /** @@ -120,6 +131,8 @@ let PerformanceController = { destroy: function() { PerformanceView.off(EVENTS.UI_START_RECORDING, this.startRecording); PerformanceView.off(EVENTS.UI_STOP_RECORDING, this.stopRecording); + gFront.off("ticks", this._onTimelineData); + gFront.off("markers", this._onTimelineData); }, /** @@ -127,8 +140,12 @@ let PerformanceController = { * when the front is starting to record. */ startRecording: Task.async(function *() { - yield gFront.startRecording(); - this.emit(EVENTS.RECORDING_STARTED); + // Save local start time for use with faking the endTime + // if not returned from the timeline actor + this._localStartTime = performance.now(); + + let startTime = this._startTime = yield gFront.startRecording(); + this.emit(EVENTS.RECORDING_STARTED, startTime); }), /** @@ -137,6 +154,12 @@ let PerformanceController = { */ stopRecording: Task.async(function *() { let results = yield gFront.stopRecording(); + // If `endTime` is not yielded from timeline actor (< Fx36), + // fake an endTime + if (!results.endTime) { + this._endTime = results.endTime = this._startTime + (performance.now() - this._localStartTime); + } + this.emit(EVENTS.RECORDING_STOPPED, results); }), diff --git a/browser/devtools/performance/modules/front.js b/browser/devtools/performance/modules/front.js index ffd1fda724d0..723008acf14e 100644 --- a/browser/devtools/performance/modules/front.js +++ b/browser/devtools/performance/modules/front.js @@ -237,7 +237,12 @@ PerformanceFront.prototype = { // The timeline actor is target-dependent, so just make sure // it's recording. let withMemory = showTimelineMemory(); - yield this._request("timeline", "start", { withTicks: true, withMemory: withMemory }); + + // Return start time from timeline actor + let startTime = yield this._request("timeline", "start", { withTicks: true, withMemory: withMemory }); + this._startTime = startTime; + + return { startTime }; }), /** @@ -254,12 +259,13 @@ PerformanceFront.prototype = { filterSamples(profilerData, this._profilingStartTime); offsetSampleTimes(profilerData, this._profilingStartTime); - yield this._request("timeline", "stop"); + let endTime = this._endTime = yield this._request("timeline", "stop"); // Join all the acquired data and return it for outside consumers. return { recordingDuration: profilerData.currentTime - this._profilingStartTime, - profilerData: profilerData + profilerData: profilerData, + endTime: endTime }; }), diff --git a/browser/devtools/performance/performance.xul b/browser/devtools/performance/performance.xul index e4759486596e..a6fbb7dc3085 100644 --- a/browser/devtools/performance/performance.xul +++ b/browser/devtools/performance/performance.xul @@ -19,6 +19,7 @@