GraphsWorker.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. /* eslint-env worker */
  6. /**
  7. * Import `createTask` to communicate with `devtools/shared/worker`.
  8. */
  9. importScripts("resource://gre/modules/workers/require.js");
  10. const { createTask } = require("resource://devtools/shared/worker/helper.js");
  11. /**
  12. * @see LineGraphWidget.prototype.setDataFromTimestamps in Graphs.js
  13. * @param number id
  14. * @param array timestamps
  15. * @param number interval
  16. * @param number duration
  17. */
  18. createTask(self, "plotTimestampsGraph", function ({ timestamps,
  19. interval, duration }) {
  20. let plottedData = plotTimestamps(timestamps, interval);
  21. let plottedMinMaxSum = getMinMaxAvg(plottedData, timestamps, duration);
  22. return { plottedData, plottedMinMaxSum };
  23. });
  24. /**
  25. * Gets the min, max and average of the values in an array.
  26. * @param array source
  27. * @param array timestamps
  28. * @param number duration
  29. * @return object
  30. */
  31. function getMinMaxAvg(source, timestamps, duration) {
  32. let totalFrames = timestamps.length;
  33. let maxValue = Number.MIN_SAFE_INTEGER;
  34. let minValue = Number.MAX_SAFE_INTEGER;
  35. // Calculate the average by counting how many frames occurred
  36. // in the duration of the recording, rather than average the frame points
  37. // we have, as that weights higher FPS, as there'll be more timestamps for
  38. // those values
  39. let avgValue = totalFrames / (duration / 1000);
  40. for (let { value } of source) {
  41. maxValue = Math.max(value, maxValue);
  42. minValue = Math.min(value, minValue);
  43. }
  44. return { minValue, maxValue, avgValue };
  45. }
  46. /**
  47. * Takes a list of numbers and plots them on a line graph representing
  48. * the rate of occurences in a specified interval.
  49. *
  50. * @param array timestamps
  51. * A list of numbers representing time, ordered ascending. For example,
  52. * this can be the raw data received from the framerate actor, which
  53. * represents the elapsed time on each refresh driver tick.
  54. * @param number interval
  55. * The maximum amount of time to wait between calculations.
  56. * @param number clamp
  57. * The maximum allowed value.
  58. * @return array
  59. * A collection of { delta, value } objects representing the
  60. * plotted value at every delta time.
  61. */
  62. function plotTimestamps(timestamps, interval = 100, clamp = 60) {
  63. let timeline = [];
  64. let totalTicks = timestamps.length;
  65. // If the refresh driver didn't get a chance to tick before the
  66. // recording was stopped, assume rate was 0.
  67. if (totalTicks == 0) {
  68. timeline.push({ delta: 0, value: 0 });
  69. timeline.push({ delta: interval, value: 0 });
  70. return timeline;
  71. }
  72. let frameCount = 0;
  73. let prevTime = +timestamps[0];
  74. for (let i = 1; i < totalTicks; i++) {
  75. let currTime = +timestamps[i];
  76. frameCount++;
  77. let elapsedTime = currTime - prevTime;
  78. if (elapsedTime < interval) {
  79. continue;
  80. }
  81. let rate = Math.min(1000 / (elapsedTime / frameCount), clamp);
  82. timeline.push({ delta: prevTime, value: rate });
  83. timeline.push({ delta: currTime, value: rate });
  84. frameCount = 0;
  85. prevTime = currTime;
  86. }
  87. return timeline;
  88. }