Bug 1107949 - framerate actor now continues recording in e10s after a page refresh. r=vp
authorJordan Santell <jsantell@gmail.com>
Mon, 09 Feb 2015 17:17:43 -0800
changeset 242516 bba3baa6b36e3eb41c9ba53318b9059fbd2d6766
parent 242515 19e0922d6d0c762fb6d275dc3a559bd5b20f8af2
child 242517 d7ce14fb3ee9bb52983d23604d49ba54df25f625
push id660
push usermichael.l.comella@gmail.com
push dateThu, 12 Feb 2015 18:55:31 +0000
reviewersvp
bugs1107949
milestone38.0a1
Bug 1107949 - framerate actor now continues recording in e10s after a page refresh. r=vp
browser/devtools/performance/test/browser.ini
browser/devtools/performance/test/browser_perf-refresh.js
browser/devtools/performance/test/head.js
toolkit/devtools/server/actors/framerate.js
--- a/browser/devtools/performance/test/browser.ini
+++ b/browser/devtools/performance/test/browser.ini
@@ -57,16 +57,17 @@ support-files =
 [browser_perf-overview-render-03.js]
 [browser_perf-overview-selection-01.js]
 [browser_perf-overview-selection-02.js]
 [browser_perf-overview-selection-03.js]
 [browser_perf-overview-time-interval.js]
 [browser_perf-shared-connection-02.js]
 [browser_perf-shared-connection-03.js]
 [browser_perf-states.js]
+[browser_perf-refresh.js]
 [browser_perf-ui-recording.js]
 [browser_perf-recording-notices-01.js]
 [browser_perf-recording-notices-02.js]
 [browser_perf_recordings-io-01.js]
 [browser_perf_recordings-io-02.js]
 [browser_perf_recordings-io-03.js]
 [browser_perf_recordings-io-04.js]
 # [browser_perf-range-changed-render.js] bug 1130669 crash
new file mode 100644
--- /dev/null
+++ b/browser/devtools/performance/test/browser_perf-refresh.js
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Rough test that the recording still continues after a refresh.
+ */
+function spawnTest () {
+  let { panel, target } = yield initPerformance(SIMPLE_URL);
+  let { EVENTS, PerformanceController } = panel.panelWin;
+
+  // Enable memory to test all the overview graphs.
+  Services.prefs.setBoolPref(MEMORY_PREF, true);
+
+  yield startRecording(panel);
+
+  yield reload(target)
+
+  let rec = PerformanceController.getCurrentRecording();
+  let { markers, memory, ticks } = rec.getAllData();
+  // Store current length of items
+  let markersLength = markers.length;
+  let memoryLength = memory.length;
+  let ticksLength = ticks.length;
+
+  ok(rec.isRecording(), "RecordingModel should still be recording after reload");
+
+  yield busyWait(100);
+  yield waitUntil(() => rec.getMarkers().length > markersLength);
+  yield waitUntil(() => rec.getMemory().length > memoryLength);
+  yield waitUntil(() => rec.getTicks().length > ticksLength);
+  ok("Markers, memory and ticks continue after reload");
+
+  yield stopRecording(panel);
+
+  let { allocations, profile, frames } = rec.getAllData();
+  ok(allocations, "allocations exist after refresh");
+  ok(profile, "profile exists after refresh");
+  ok(frames, "frames exist after refresh");
+
+  yield teardown(panel);
+  finish();
+}
--- a/browser/devtools/performance/test/head.js
+++ b/browser/devtools/performance/test/head.js
@@ -412,8 +412,13 @@ function getSourceActor(aSources, aURL) 
 }
 
 /**
  * Fires a key event, like "VK_UP", "VK_DOWN", etc.
  */
 function fireKey (e) {
   EventUtils.synthesizeKey(e, {});
 }
+
+function reload (aTarget, aEvent = "navigate") {
+  aTarget.activeTab.reload();
+  return once(aTarget, aEvent);
+}
--- a/toolkit/devtools/server/actors/framerate.js
+++ b/toolkit/devtools/server/actors/framerate.js
@@ -15,36 +15,39 @@ const {method, custom, Arg, Option, RetV
 /**
  * A very simple utility for monitoring framerate.
  */
 let FramerateActor = exports.FramerateActor = protocol.ActorClass({
   typeName: "framerate",
   initialize: function(conn, tabActor) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this.tabActor = tabActor;
-    this._chromeWin = getChromeWin(tabActor.window);
+    this._contentWin = tabActor.window;
     this._onRefreshDriverTick = this._onRefreshDriverTick.bind(this);
+    this._onGlobalCreated = this._onGlobalCreated.bind(this);
+    on(this.tabActor, "window-ready", this._onGlobalCreated);
   },
   destroy: function(conn) {
+    off(this.tabActor, "window-ready", this._onGlobalCreated);
     protocol.Actor.prototype.destroy.call(this, conn);
     this.stopRecording();
   },
 
   /**
    * Starts monitoring framerate, storing the frames per second.
    */
   startRecording: method(function() {
     if (this._recording) {
       return;
     }
     this._recording = true;
     this._ticks = [];
 
-    this._startTime = this._chromeWin.performance.now();
-    this._rafID = this._chromeWin.requestAnimationFrame(this._onRefreshDriverTick);
+    this._startTime = this._contentWin.performance.now();
+    this._rafID = this._contentWin.requestAnimationFrame(this._onRefreshDriverTick);
   }, {
   }),
 
   /**
    * Stops monitoring framerate, returning the recorded values.
    */
   stopRecording: method(function(beginAt = 0, endAt = Number.MAX_SAFE_INTEGER) {
     if (!this._recording) {
@@ -60,17 +63,17 @@ let FramerateActor = exports.FramerateAc
     },
     response: { ticks: RetVal("array:number") }
   }),
 
   /**
    * Stops monitoring framerate, without returning the recorded values.
    */
   cancelRecording: method(function() {
-    this._chromeWin.cancelAnimationFrame(this._rafID);
+    this._contentWin.cancelAnimationFrame(this._rafID);
     this._recording = false;
     this._ticks = null;
     this._rafID = -1;
   }, {
   }),
 
   /**
    * Returns whether this actor is currently active.
@@ -99,22 +102,37 @@ let FramerateActor = exports.FramerateAc
 
   /**
    * Function invoked along with the refresh driver.
    */
   _onRefreshDriverTick: function() {
     if (!this._recording) {
       return;
     }
-    this._rafID = this._chromeWin.requestAnimationFrame(this._onRefreshDriverTick);
+    this._rafID = this._contentWin.requestAnimationFrame(this._onRefreshDriverTick);
 
     // Store the amount of time passed since the recording started.
-    let currentTime = this._chromeWin.performance.now();
-    let elapsedTime = currentTime - this._startTime;
-    this._ticks.push(elapsedTime);
+    let currentTime = this._contentWin.performance.now();
+
+    // Store _elapsedTime so we can use this as a new starting time on a page refresh
+    // to normalize times.
+    this._elapsedTime = currentTime - this._startTime;
+    this._ticks.push(this._elapsedTime);
+  },
+
+  /**
+   * When the content window for the tab actor is created.
+   */
+  _onGlobalCreated: function (win) {
+    if (this._recording) {
+      // Set _startTime to the currently elapsed time so we can get a wholistic
+      // elapsed time in _onRefreshDriverTick.
+      this._startTime = -this._elapsedTime;
+      this._rafID = this._contentWin.requestAnimationFrame(this._onRefreshDriverTick);
+    }
   }
 });
 
 /**
  * The corresponding Front object for the FramerateActor.
  */
 let FramerateFront = exports.FramerateFront = protocol.FrontClass(FramerateActor, {
   initialize: function(client, { framerateActor }) {
@@ -166,23 +184,8 @@ FramerateFront.plotFPS = function(ticks,
     timeline.push({ delta: currTime, value: framerate });
 
     frameCount = 0;
     prevTime = currTime;
   }
 
   return timeline;
 };
-
-/**
- * Gets the top level browser window from a content window.
- *
- * @param nsIDOMWindow innerWin
- *        The content window to query.
- * @return nsIDOMWindow
- *         The top level browser window.
- */
-function getChromeWin(innerWin) {
-  return innerWin
-    .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
-    .QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem
-    .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
-}