browser_partial_prerender_animation_in_popup.js (3460B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /* import-globals-from ../../../dom/animation/test/testcommon.js */ 7 Services.scriptloader.loadSubScript( 8 "chrome://mochitests/content/tests/dom/animation/test/testcommon.js", 9 this 10 ); 11 12 add_task(async () => { 13 await SpecialPowers.pushPrefEnv({ 14 set: [ 15 ["apz.popups.enabled", false], // bug 1934722 16 ["layout.animation.prerender.partial", true], 17 ["layout.animation.prerender.viewport-ratio-limit", 1.125], 18 ], 19 }); 20 21 let navBar = document.getElementById("nav-bar"); 22 23 const anchor = document.createXULElement("toolbarbutton"); 24 anchor.classList.add("toolbarbutton-1", "chromeclass-toolbar-additional"); 25 navBar.appendChild(anchor); 26 27 // Prepare a popup panel. 28 const panel = document.createXULElement("panel"); 29 panel.setAttribute("noautohide", true); 30 navBar.appendChild(panel); 31 32 // Add a overflow:scroll container to avoid expanding the popup window size. 33 const container = document.createElement("div"); 34 container.style = "width: 100px; height: 100px; overflow: scroll;"; 35 36 // Looks like in popup window wider elements in the overflow:scroll container 37 // are still affecting the viewport size of the popup content, for example, 38 // if we specify "witdh: 800px" here, this element is not going to be partial- 39 // prerendered, it will be fully prerendered, so we use vertically overflowed 40 // element here. 41 const target = document.createElement("div"); 42 target.style = "width: 100px; height: 800px;"; 43 44 container.appendChild(target); 45 panel.appendChild(container); 46 47 registerCleanupFunction(() => { 48 panel.remove(); 49 anchor.remove(); 50 }); 51 52 panel.openPopup(anchor); 53 54 // Start a transform transition with a 1s delay step-start function so that 55 // we can ensure that 56 // 1) when the target element is initially composited on the compositor the 57 // transition hasn't yet started, thus no jank happens 58 // 2) when the transition starts on the compositor thread, it causes a jank 59 // so that it will report back to the main-thread 60 target.style.transition = "transform 100s step-start 1s"; 61 getComputedStyle(target); 62 const startTransition = new Promise(resolve => { 63 target.addEventListener("transitionstart", resolve); 64 }); 65 target.style.transform = "translateY(-130px)"; 66 const transition = target.getAnimations()[0]; 67 68 // Wait for the transition start. 69 await startTransition; 70 71 // Make sure it's running on the compositor. 72 Assert.ok( 73 transition.isRunningOnCompositor, 74 "The transition should be running on the compositor thread" 75 ); 76 77 // Collect restyling markers in 5 frames. 78 const restyleCount = await observeStylingInTargetWindow(panel.ownerGlobal, 5); 79 80 // On non WebRender we observe two restyling markers because we get the second 81 // jank report from the compositor thread before a new pre-rendered result, 82 // which was triggered by the first jank report, reached to the compositor 83 // thread. So we allow one or two makers here. 84 // NOTE: Since we wrap the target element in overflow:scroll container, we 85 // might see an additional restyling marker triggered by 86 // KeyframeEffect::OverflowRegionRefreshInterval (200ms) on very slow 87 // platforms (e.g. TSAN builds), if it happens we should allow the additional 88 // restyling here. 89 Assert.greaterOrEqual(restyleCount, 1); 90 Assert.lessOrEqual(restyleCount, 2); 91 });