summaryrefslogtreecommitdiffstats
path: root/devtools/server/performance/framerate.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /devtools/server/performance/framerate.js
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/server/performance/framerate.js')
-rw-r--r--devtools/server/performance/framerate.js105
1 files changed, 105 insertions, 0 deletions
diff --git a/devtools/server/performance/framerate.js b/devtools/server/performance/framerate.js
new file mode 100644
index 0000000000..330c270c58
--- /dev/null
+++ b/devtools/server/performance/framerate.js
@@ -0,0 +1,105 @@
+/* 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";
+
+/**
+ * A very simple utility for monitoring framerate. Takes a `targetActor`
+ * and monitors framerate over time. The actor wrapper around this
+ * can be found at devtools/server/actors/framerate.js
+ */
+class Framerate {
+ constructor(targetActor) {
+ this.targetActor = targetActor;
+ this._contentWin = targetActor.window;
+ this._onRefreshDriverTick = this._onRefreshDriverTick.bind(this);
+ this._onGlobalCreated = this._onGlobalCreated.bind(this);
+ this.targetActor.on("window-ready", this._onGlobalCreated);
+ }
+
+ destroy(conn) {
+ this.targetActor.off("window-ready", this._onGlobalCreated);
+ this.stopRecording();
+ }
+
+ /**
+ * Starts monitoring framerate, storing the frames per second.
+ */
+ startRecording() {
+ if (this._recording) {
+ return;
+ }
+ this._recording = true;
+ this._ticks = [];
+ this._startTime = this.targetActor.docShell.now();
+ this._rafID = this._contentWin.requestAnimationFrame(
+ this._onRefreshDriverTick
+ );
+ }
+
+ /**
+ * Stops monitoring framerate, returning the recorded values.
+ */
+ stopRecording(beginAt = 0, endAt = Number.MAX_SAFE_INTEGER) {
+ if (!this._recording) {
+ return [];
+ }
+ const ticks = this.getPendingTicks(beginAt, endAt);
+ this.cancelRecording();
+ return ticks;
+ }
+
+ /**
+ * Stops monitoring framerate, without returning the recorded values.
+ */
+ cancelRecording() {
+ this._contentWin.cancelAnimationFrame(this._rafID);
+ this._recording = false;
+ this._ticks = null;
+ this._rafID = -1;
+ }
+
+ /**
+ * Returns whether this instance is currently recording.
+ */
+ isRecording() {
+ return !!this._recording;
+ }
+
+ /**
+ * Gets the refresh driver ticks recorded so far.
+ */
+ getPendingTicks(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() {
+ if (!this._recording) {
+ return;
+ }
+ this._rafID = this._contentWin.requestAnimationFrame(
+ this._onRefreshDriverTick
+ );
+ this._ticks.push(this.targetActor.docShell.now() - this._startTime);
+ }
+
+ /**
+ * When the content window for the target actor is created.
+ */
+ _onGlobalCreated(win) {
+ if (this._recording) {
+ this._contentWin.cancelAnimationFrame(this._rafID);
+ this._rafID = this._contentWin.requestAnimationFrame(
+ this._onRefreshDriverTick
+ );
+ }
+ }
+}
+
+exports.Framerate = Framerate;