diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/test/test_video_low_power_telemetry.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/test/test_video_low_power_telemetry.html')
-rw-r--r-- | dom/media/test/test_video_low_power_telemetry.html | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/dom/media/test/test_video_low_power_telemetry.html b/dom/media/test/test_video_low_power_telemetry.html new file mode 100644 index 0000000000..be609f7ceb --- /dev/null +++ b/dom/media/test/test_video_low_power_telemetry.html @@ -0,0 +1,205 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1737682 + +This is a test of the macOS video low power telemetry, defined as GFX_MACOS_VIDEO_LOW_POWER +enums in Histograms.json. The test will load some video media files, play them for some +number of frames, then check that appropriate telemetry has been recorded. Since the +telemetry fires based on the number of frames painted, the test is structured around +the `media.video_stats.enabled` pref, which allows us to monitor the number of frames +that have been shown. The telemetry fires every 600 frames. To make sure we have enough +painted frames to trigger telemetry, we run the media for many frames and then check +that the expected telemetry value has been recorded at least once. + +The tests are run via the MediaTestManager, which loads and plays the video sequentially. +Since we want to test different telemetry outcomes, we have some special setup and teardown +steps we run before each video. We keep track of which test we are running with a simple +1-based index, `testIndex`. So our test structure is: + +1) Set some initial preferences that need to be set for the whole test series. +2) Start MediaTestManager with a set of media to play. +3) When a video arrives, increment testIndex and call preTest. +4) Run the video for PAINTED_FRAMES frames, then call postTest, which checks telemetry + and cleans up. +5) Tell the MediaTestManager we've finished with that video, which triggers the next. +--> + +<head> + <title>Test of macOS video low power telemetry</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1737682">Mozilla Bug 1737682</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + // Parallel test must be disabled for media.video_stats.enabled is a global setting + // to prevent the setting from changing unexpectedly in the middle of the test. + PARALLEL_TESTS = 1; + SimpleTest.waitForExplicitFinish(); + + // How many frames do we run? Must be more than the value set by the + // gfx.core-animation.low-power-telemetry-frames pref, because that's how + // many frames must be shown before telemetry is emitted. We present for + // longer than that to ensure that the telemetry is emitted at least once. + // This also has to be enough frames to overcome the animated "<video> is + // now fullscreen." popup that appears over the video. While that modal + // is visible and animating away, it will register as an overlay and + // prevent low power mode. As an estimate, we need at least 200 frames to + // ensure that animation has finished and there has been time to fire the + // telemetry at least once after it has finished. + const TELEMETRY_FRAMES = SpecialPowers.getIntPref("gfx.core-animation.low-power-telemetry-frames"); + const PAINTED_FRAMES = Math.max(Math.floor(TELEMETRY_FRAMES * 1.1), 200 + TELEMETRY_FRAMES); + info(`Running each video for ${PAINTED_FRAMES} frames.`); + + // Taken from TelemetryHistogramEnums.h + const GFX_MACOS_VIDEO_LOW_POWER_LowPower = 1; + const GFX_MACOS_VIDEO_LOW_POWER_FailWindowed = 3; + + var manager = new MediaTestManager; + + // Define some state variables that we'll use to manage multiple setup, + // check, and teardown steps using the same preTest and postTest functions. + var testIndex = 0; + var testsComplete = false; + + async function retrieveSnapshotAndClearTelemetry() { + return SpecialPowers.spawnChrome([], () => { + let hist = Services.telemetry.getHistogramById("GFX_MACOS_VIDEO_LOW_POWER"); + let snap = hist.snapshot(); + hist.clear(); + return snap; + }); + } + + function checkSnapshot(snap, category) { + if (!snap) { + return; + } + + // For debugging purposes, build a string of the snapshot values hashmap. + let valuesString = ''; + let keys = Object.keys(snap.values); + keys.forEach(k => { + valuesString += `[${k}] = ${snap.values[k]}, `; + }); + info(`Test ${testIndex} telemetry values are ${valuesString}`); + + // Since we've run the media for more frames than the telemetry needs to + // fire, we should have at least 1 of the expected value. + let val = snap.values[category]; + if (!val) { + val = 0; + } + ok(val > 0, `Test ${testIndex} enum ${category} should have at least 1 occurrence; found ${val}.`); + } + + async function doPreTest(v) { + if (testsComplete) { + manager.finished(v.token); + return; + } + + switch (testIndex) { + case 1: { + // Test 1 (FailWindowed): No special setup. + break; + } + + case 2: { + // Test 2 (LowPower): Enter fullscreen. + + // Wait one frame to ensure the old video is no longer in the layer tree, which + // causes problems with the telemetry. + await new Promise(resolve => requestAnimationFrame(resolve)); + + info("Attempting to enter fullscreen."); + ok(document.fullscreenEnabled, "Document should permit fullscreen-ing of elements."); + await SpecialPowers.wrap(v).requestFullscreen(); + ok(document.fullscreenElement, "Document should have one element in fullscreen."); + break; + } + } + } + + async function doPostTest(v) { + info(`Test ${testIndex} attempting to retrieve telemetry.`); + let snap = await retrieveSnapshotAndClearTelemetry(); + ok(snap, `Test ${testIndex} should have telemetry.`); + + switch (testIndex) { + case 1: { + // Test 1 (FailWindowed): Just check. + checkSnapshot(snap, GFX_MACOS_VIDEO_LOW_POWER_FailWindowed); + break; + } + + case 2: { + // Test 2 (LowPower): Check, then exit fullscreen. + checkSnapshot(snap, GFX_MACOS_VIDEO_LOW_POWER_LowPower); + + info("Attempting to exit fullscreen."); + await SpecialPowers.wrap(document).exitFullscreen(); + ok(!document.fullscreenElement, "Document should be out of fullscreen."); + + // This is the last test. + testsComplete = true; + break; + } + } + } + + function ontimeupdate(event) { + let v = event.target; + // Count painted frames to see when we should hit some telemetry threshholds. + if (v.mozPaintedFrames >= PAINTED_FRAMES) { + v.pause(); + v.removeEventListener("timeupdate", ontimeupdate); + + doPostTest(v).then(() => { + let token = v.token; + removeNodeAndSource(v); + manager.finished(token); + }); + } + } + + function startTest(test, token) { + manager.started(token); + + testIndex++; + info(`Starting test ${testIndex} video ${test.name}.`); + + let v = document.createElement('video'); + v.addEventListener("timeupdate", ontimeupdate); + v.token = token; + v.src = test.name; + v.loop = true; + document.body.appendChild(v); + + doPreTest(v).then(() => { + info(`Playing test ${testIndex}.`); + v.play(); + }); + } + + SpecialPowers.pushPrefEnv({"set": [ + ["media.video_stats.enabled", true], + ["gfx.core-animation.specialize-video", true], + ]}, + async function() { + // Clear out existing telemetry in case previous tests were displaying + // video. + info("Clearing initial telemetry."); + await retrieveSnapshotAndClearTelemetry(); + + ok(gVideoLowPowerTests.length >= 2, "Should have enough videos to test."); + manager.runTests(gVideoLowPowerTests, startTest); + }); + +</script> +</pre> +</body> +</html> |