diff options
Diffstat (limited to 'devtools/server/performance/framerate.js')
-rw-r--r-- | devtools/server/performance/framerate.js | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/devtools/server/performance/framerate.js b/devtools/server/performance/framerate.js new file mode 100644 index 000000000..24f8a7a6b --- /dev/null +++ b/devtools/server/performance/framerate.js @@ -0,0 +1,99 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const { on, once, off, emit } = require("sdk/event/core"); +const { Class } = require("sdk/core/heritage"); + +/** + * A very simple utility for monitoring framerate. Takes a `tabActor` + * and monitors framerate over time. The actor wrapper around this + * can be found at devtools/server/actors/framerate.js + */ +var Framerate = exports.Framerate = Class({ + initialize: function (tabActor) { + this.tabActor = tabActor; + 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); + this.stopRecording(); + }, + + /** + * Starts monitoring framerate, storing the frames per second. + */ + startRecording: function () { + if (this._recording) { + return; + } + this._recording = true; + this._ticks = []; + this._startTime = this.tabActor.docShell.now(); + this._rafID = this._contentWin.requestAnimationFrame(this._onRefreshDriverTick); + }, + + /** + * Stops monitoring framerate, returning the recorded values. + */ + stopRecording: function (beginAt = 0, endAt = Number.MAX_SAFE_INTEGER) { + if (!this._recording) { + return []; + } + let ticks = this.getPendingTicks(beginAt, endAt); + this.cancelRecording(); + return ticks; + }, + + /** + * Stops monitoring framerate, without returning the recorded values. + */ + cancelRecording: function () { + this._contentWin.cancelAnimationFrame(this._rafID); + this._recording = false; + this._ticks = null; + this._rafID = -1; + }, + + /** + * Returns whether this instance is currently recording. + */ + isRecording: function () { + return !!this._recording; + }, + + /** + * Gets the refresh driver ticks recorded so far. + */ + getPendingTicks: function (beginAt = 0, endAt = Number.MAX_SAFE_INTEGER) { + if (!this._ticks) { + return []; + } + return this._ticks.filter(e => e >= beginAt && e <= endAt); + }, + + /** + * Function invoked along with the refresh driver. + */ + _onRefreshDriverTick: function () { + if (!this._recording) { + return; + } + this._rafID = this._contentWin.requestAnimationFrame(this._onRefreshDriverTick); + this._ticks.push(this.tabActor.docShell.now() - this._startTime); + }, + + /** + * When the content window for the tab actor is created. + */ + _onGlobalCreated: function (win) { + if (this._recording) { + this._contentWin.cancelAnimationFrame(this._rafID); + this._rafID = this._contentWin.requestAnimationFrame(this._onRefreshDriverTick); + } + } +}); |