summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/widgets/GraphsWorker.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/widgets/GraphsWorker.js')
-rw-r--r--devtools/client/shared/widgets/GraphsWorker.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/devtools/client/shared/widgets/GraphsWorker.js b/devtools/client/shared/widgets/GraphsWorker.js
new file mode 100644
index 000000000..1e12f1d11
--- /dev/null
+++ b/devtools/client/shared/widgets/GraphsWorker.js
@@ -0,0 +1,103 @@
+/* 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";
+
+/* eslint-env worker */
+
+/**
+ * Import `createTask` to communicate with `devtools/shared/worker`.
+ */
+importScripts("resource://gre/modules/workers/require.js");
+const { createTask } = require("resource://devtools/shared/worker/helper.js");
+
+/**
+ * @see LineGraphWidget.prototype.setDataFromTimestamps in Graphs.js
+ * @param number id
+ * @param array timestamps
+ * @param number interval
+ * @param number duration
+ */
+createTask(self, "plotTimestampsGraph", function ({ timestamps,
+ interval, duration }) {
+ let plottedData = plotTimestamps(timestamps, interval);
+ let plottedMinMaxSum = getMinMaxAvg(plottedData, timestamps, duration);
+
+ return { plottedData, plottedMinMaxSum };
+});
+
+/**
+ * Gets the min, max and average of the values in an array.
+ * @param array source
+ * @param array timestamps
+ * @param number duration
+ * @return object
+ */
+function getMinMaxAvg(source, timestamps, duration) {
+ let totalFrames = timestamps.length;
+ let maxValue = Number.MIN_SAFE_INTEGER;
+ let minValue = Number.MAX_SAFE_INTEGER;
+ // Calculate the average by counting how many frames occurred
+ // in the duration of the recording, rather than average the frame points
+ // we have, as that weights higher FPS, as there'll be more timestamps for
+ // those values
+ let avgValue = totalFrames / (duration / 1000);
+
+ for (let { value } of source) {
+ maxValue = Math.max(value, maxValue);
+ minValue = Math.min(value, minValue);
+ }
+
+ return { minValue, maxValue, avgValue };
+}
+
+/**
+ * Takes a list of numbers and plots them on a line graph representing
+ * the rate of occurences in a specified interval.
+ *
+ * @param array timestamps
+ * A list of numbers representing time, ordered ascending. For example,
+ * this can be the raw data received from the framerate actor, which
+ * represents the elapsed time on each refresh driver tick.
+ * @param number interval
+ * The maximum amount of time to wait between calculations.
+ * @param number clamp
+ * The maximum allowed value.
+ * @return array
+ * A collection of { delta, value } objects representing the
+ * plotted value at every delta time.
+ */
+function plotTimestamps(timestamps, interval = 100, clamp = 60) {
+ let timeline = [];
+ let totalTicks = timestamps.length;
+
+ // If the refresh driver didn't get a chance to tick before the
+ // recording was stopped, assume rate was 0.
+ if (totalTicks == 0) {
+ timeline.push({ delta: 0, value: 0 });
+ timeline.push({ delta: interval, value: 0 });
+ return timeline;
+ }
+
+ let frameCount = 0;
+ let prevTime = +timestamps[0];
+
+ for (let i = 1; i < totalTicks; i++) {
+ let currTime = +timestamps[i];
+ frameCount++;
+
+ let elapsedTime = currTime - prevTime;
+ if (elapsedTime < interval) {
+ continue;
+ }
+
+ let rate = Math.min(1000 / (elapsedTime / frameCount), clamp);
+ timeline.push({ delta: prevTime, value: rate });
+ timeline.push({ delta: currTime, value: rate });
+
+ frameCount = 0;
+ prevTime = currTime;
+ }
+
+ return timeline;
+}