import { defined } from "../../../Source/Cesium.js"; import { getTimestamp } from "../../../Source/Cesium.js"; import { FrameRateMonitor } from "../../../Source/Cesium.js"; import createScene from "../../createScene.js"; import { PerformanceWatchdogViewModel } from "../../../Source/Cesium.js"; describe( "Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel", function () { var scene; beforeAll(function () { scene = createScene(); }); afterAll(function () { scene.destroyForSpecs(); }); var viewModel; afterEach(function () { if (defined(viewModel)) { viewModel.destroy(); viewModel = undefined; } FrameRateMonitor.fromScene(scene).destroy(); }); function spinWait(milliseconds) { /*eslint-disable no-empty*/ var endTime = getTimestamp() + milliseconds; while (getTimestamp() < endTime) {} /*eslint-enable no-empty*/ } it("throws when constructed without a scene", function () { expect(function () { viewModel = new PerformanceWatchdogViewModel(); }).toThrowDeveloperError(); expect(function () { viewModel = new PerformanceWatchdogViewModel({}); }).toThrowDeveloperError(); }); it("can be constructed with just a scene", function () { viewModel = new PerformanceWatchdogViewModel({ scene: scene, }); expect(viewModel.lowFrameRateMessage).toBeDefined(); expect(viewModel.lowFrameRateMessageDismissed).toBe(false); expect(viewModel.showingLowFrameRateMessage).toBe(false); expect(viewModel.scene).toBe(scene); }); it("honors parameters to the constructor", function () { var options = { scene: scene, lowFrameRateMessage: "why so slow?", }; viewModel = new PerformanceWatchdogViewModel(options); expect(viewModel.lowFrameRateMessage).toBe("why so slow?"); expect(viewModel.scene).toBe(scene); }); it("shows a message on low frame rate", function () { var monitor = FrameRateMonitor.fromScene(scene); monitor.quietPeriod = 0.001; monitor.warmupPeriod = 0.001; monitor.samplingWindow = 0.001; monitor.minimumFrameRateDuringWarmup = 1000; monitor.minimumFrameRateAfterWarmup = 1000; viewModel = new PerformanceWatchdogViewModel({ scene: scene, }); expect(viewModel.showingLowFrameRateMessage).toBe(false); // Rendering once starts the quiet period scene.render(); // Wait until we're well past the end of the quiet period. spinWait(2); // Rendering again records our first sample. scene.render(); // Wait well over a millisecond, which is the maximum frame time allowed by this instance. spinWait(2); // Record our second sample. The watchdog should notice that our frame rate is too low. scene.render(); expect(viewModel.showingLowFrameRateMessage).toBe(true); }); it("does not report a low frame rate during the queit period", function () { var monitor = FrameRateMonitor.fromScene(scene); monitor.quietPeriod = 1.0; monitor.warmupPeriod = 0.001; monitor.samplingWindow = 0.001; monitor.minimumFrameRateDuringWarmup = 1000; monitor.minimumFrameRateAfterWarmup = 1000; viewModel = new PerformanceWatchdogViewModel({ scene: scene, }); // Rendering once starts the quiet period scene.render(); // Wait well over a millisecond, which is the maximum frame time allowed by this instance. spinWait(2); // Render again. Even though our frame rate is too low, the watchdog shouldn't bark because we're in the quiet period. scene.render(); expect(viewModel.showingLowFrameRateMessage).toBe(false); }); it("the low frame rate message goes away after the warmup period if the frame rate returns to nominal", function () { var monitor = FrameRateMonitor.fromScene(scene); monitor.quietPeriod = 0.001; monitor.warmupPeriod = 0.001; monitor.samplingWindow = 0.001; monitor.minimumFrameRateDuringWarmup = 10; monitor.minimumFrameRateAfterWarmup = 10; viewModel = new PerformanceWatchdogViewModel({ scene: scene, }); expect(viewModel.showingLowFrameRateMessage).toBe(false); // Rendering once starts the quiet period scene.render(); // Wait until we're well past the end of the quiet period. spinWait(2); // Rendering again records our first sample. scene.render(); // Wait 120 millseconds, which is over the maximum frame time allowed by this instance. spinWait(120); // Record our second sample. The watchdog should notice that our frame rate is too low. scene.render(); expect(viewModel.showingLowFrameRateMessage).toBe(true); // Render as fast as possible for a samplingWindow, quietPeriod, and warmupPeriod. var endTime = getTimestamp() + 50; while (getTimestamp() < endTime) { scene.render(); } // The low frame rate message should have gone away. expect(viewModel.showingLowFrameRateMessage).toBe(false); }); it("does not show the low frame rate message again once it is dismissed", function () { var monitor = FrameRateMonitor.fromScene(scene); monitor.quietPeriod = 0.001; monitor.warmupPeriod = 0.001; monitor.samplingWindow = 0.001; monitor.minimumFrameRateDuringWarmup = 1000; monitor.minimumFrameRateAfterWarmup = 1000; viewModel = new PerformanceWatchdogViewModel({ scene: scene, }); expect(viewModel.showingLowFrameRateMessage).toBe(false); // Rendering once starts the quiet period scene.render(); // Wait until we're well past the end of the quiet period. spinWait(2); // Rendering again records our first sample. scene.render(); // Wait well over a millisecond, which is the maximum frame time allowed by this instance. spinWait(2); // Record our second sample. The watchdog should notice that our frame rate is too low. scene.render(); expect(viewModel.showingLowFrameRateMessage).toBe(true); viewModel.dismissMessage(); // Render several slow frames. The message should not re-appear. scene.render(); spinWait(2); scene.render(); expect(viewModel.showingLowFrameRateMessage).toBe(false); }); }, "WebGL" );