helper_displayport_estimation.html (4261B)
1 <!DOCTYPE html> 2 <html id="html"> 3 <title>Test for making sure that an instant scroll update on the main-thread is reflected to displayport</title> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 6 <script src="apz_test_utils.js"></script> 7 <script src="apz_test_native_event_utils.js"></script> 8 <script src="/tests/SimpleTest/EventUtils.js"></script> 9 <script src="/tests/SimpleTest/paint_listener.js"></script> 10 <style> 11 html { 12 overflow: scroll; 13 scrollbar-width: none; 14 } 15 </style> 16 <body> 17 <div style="height: 50000px"></div> 18 </body> 19 <script> 20 // Displayport alignment multiplier calculation; see AsyncPanZoomController::GetDisplayportAlignmentMultiplier 21 function GetDisplayportAlignmentMultiplier(aBaseHeight) { 22 return Math.min(aBaseHeight / 250, 8.0); 23 } 24 25 async function test() { 26 const resolution = await getResolution(); 27 const deviceScale = window.devicePixelRatio; 28 29 // Invoke scrollToVisual to diverge the visual scroll offset from the 30 // layout scroll offset. 31 const utils = SpecialPowers.getDOMWindowUtils(window); 32 utils.scrollToVisual(0, 1000, 33 utils.UPDATE_TYPE_MAIN_THREAD, 34 utils.SCROLL_MODE_INSTANT); 35 await promiseApzFlushedRepaints(); 36 37 const initialVisualOffset = visualViewport.offsetTop; 38 info(`The visualViewport.offsetTop is now ${visualViewport.offsetTop}`); 39 ok(visualViewport.offsetTop > 0, `The visual viewport has scrolled`); 40 info(`The visualViewport.pageTop is now ${visualViewport.pageTop}`); 41 const initialScrollY = window.scrollY; 42 info(`The window.scrollY is now ${window.scrollY}`); 43 ok(window.scrollY > 0, `The layout viewport has scrolled`); 44 is(initialScrollY + initialVisualOffset, 1000, 45 "The visual scroll offset + the layout scroll offset should equal to 1000"); 46 47 // Start in a requestAnimationFrame callback so that awaiting an additional 48 // requestAnimationFrame callback should result a paint. 49 await promiseFrame(); 50 const currentTime = document.timeline.currentTime; 51 52 // Do an instant relative scroll operation on the main-thread. 53 // NOTE: Until the next paint this scroll position update will not be sent 54 // to APZ. 55 window.scrollBy(0, 1000); 56 57 // Wait a frame so that a paint should have happened. 58 await promiseFrame(); 59 60 // Make sure now that refresh driver's time has advanced. 61 ok(document.timeline.currentTime > currentTime, 62 `${document.timeline.currentTime} > ${currentTime}`); 63 64 // Displayport margins calculation; see DisplayPortMargins::GetRelativeToLayoutViewport 65 // https://searchfox.org/mozilla-central/rev/380b8fd795e7d96d8a5a3e6ec2b50a9f2b65854a/layout/base/DisplayPortUtils.cpp#85-92 66 const margin = initialVisualOffset * resolution * deviceScale; 67 68 const clientHeightInScreen = document.documentElement.clientHeight * deviceScale; 69 const multiplier = GetDisplayportAlignmentMultiplier(clientHeightInScreen); 70 71 // These calculations need to be same as the ones in GetDisplayPortFromMarginsData(). 72 // https://searchfox.org/mozilla-central/rev/380b8fd795e7d96d8a5a3e6ec2b50a9f2b65854a/layout/base/DisplayPortUtils.cpp#169 73 const currentScrollPosition = initialScrollY + 1000; 74 const currentScrollPositionInScreen = currentScrollPosition * resolution * deviceScale; 75 const notAlignedDisplayportPosition = currentScrollPositionInScreen + margin; 76 const displayportAlignment = 128 * multiplier; 77 const alignedDisplayportPosition = 78 displayportAlignment * Math.floor(notAlignedDisplayportPosition / displayportAlignment); 79 80 let displayport = getLastContentDisplayportFor(document.documentElement.id); 81 isfuzzy(displayport.y, 82 (alignedDisplayportPosition - currentScrollPositionInScreen) / (resolution * deviceScale), 83 1.0 * deviceScale, // `getLastContentDisplayportFor` returns rounded interger values. 84 // `document.documentElement.clientHeight` also returns rounded values. 85 "The displayport y should be reflecting the instant scroll distance"); 86 } 87 88 // Scale 2.0x to diverge the visual scroll offset from the layout scroll 89 // offset by calling nsIDOMWindowUtils.scrollToVisual. 90 SpecialPowers.DOMWindowUtils.setResolutionAndScaleTo(2.0); 91 waitUntilApzStable() 92 .then(test) 93 .then(subtestDone, subtestFailed); 94 </script> 95 </html>