Changeset 261113 in webkit
- Timestamp:
- May 4, 2020 2:24:49 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 45 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r261106 r261113 1 2020-05-04 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 Throttling requestAnimationFrame should be controlled by RenderingUpdateScheduler 4 https://bugs.webkit.org/show_bug.cgi?id=204713 5 6 Reviewed by Simon Fraser. 7 8 * fast/animation/request-animation-frame-throttle-inside-overflow-scroll-expected.txt: 9 * fast/animation/request-animation-frame-throttle-inside-overflow-scroll.html: 10 * fast/animation/request-animation-frame-throttle-subframe-display-none-expected.txt: 11 * fast/animation/request-animation-frame-throttle-subframe-display-none.html: 12 * fast/animation/request-animation-frame-throttle-subframe-expected.txt: 13 * fast/animation/request-animation-frame-throttle-subframe-zero-size-expected.txt: 14 * fast/animation/request-animation-frame-throttle-subframe-zero-size.html: 15 * fast/animation/request-animation-frame-throttle-subframe.html: 16 * fast/animation/request-animation-frame-throttling-detached-iframe-expected.txt: 17 * fast/animation/request-animation-frame-throttling-detached-iframe.html: 18 Replace the call isRequestAnimationFrameThrottled() by requestAnimationFrameThrottlingReasons(). 19 20 * fast/animation/request-animation-frame-throttling-lowPowerMode-expected.txt: 21 * fast/animation/request-animation-frame-throttling-lowPowerMode.html: 22 Ensure the actual rAF interval is > 30ms for lowPowerMode. 23 24 * http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe-expected.txt: 25 * http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html: 26 * http/tests/frame-throttling/resources/requestAnimationFrame-frame.html: 27 Replace the call isRequestAnimationFrameThrottled() by requestAnimationFrameThrottlingReasons(). 28 1 29 2020-05-04 Eric Carlson <eric.carlson@apple.com> 2 30 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-inside-overflow-scroll-expected.txt
r225554 r261113 5 5 6 6 Frame is initially inside the viewport so requestAnimationFrame should not be throttled 7 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is false7 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 8 8 Scrolling overflow. 9 9 requestAnimationFrame should still not be throttled 10 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is false10 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 11 11 PASS successfullyParsed is true 12 12 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-inside-overflow-scroll.html
r225554 r261113 15 15 16 16 debug("requestAnimationFrame should still not be throttled"); 17 shouldBe False("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");17 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 18 18 19 19 finishJSTest(); … … 24 24 testFrame = document.getElementById("testFrame"); 25 25 debug("Frame is initially inside the viewport so requestAnimationFrame should not be throttled"); 26 shouldBe False("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");26 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 27 27 scrollOverflow(); 28 28 } -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-subframe-display-none-expected.txt
r186195 r261113 4 4 5 5 6 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is false6 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 7 7 PASS successfullyParsed is true 8 8 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-subframe-display-none.html
r186195 r261113 14 14 document.body.offsetTop; 15 15 16 shouldBe False("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");16 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 17 17 finishJSTest(); 18 18 } -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-subframe-expected.txt
r183998 r261113 5 5 6 6 Frame is initially outside the viewport so requestAnimationFrame should be throttled 7 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() became true8 PASS internals. isRequestAnimationFrameThrottled() is false9 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is true10 PASS grandChildFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is true7 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() became "OutsideViewport" 8 PASS internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 9 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "OutsideViewport" 10 PASS grandChildFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "OutsideViewport" 11 11 Scrolling frame into view. 12 12 RequestAnimationFrame should no longer be throttled 13 PASS internals. isRequestAnimationFrameThrottled() is false14 PASS grandChildFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is false15 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is false13 PASS internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 14 PASS grandChildFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 15 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 16 16 Scrolling frame out of view again. 17 PASS internals. isRequestAnimationFrameThrottled() is false18 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() became true19 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is true20 PASS grandChildFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is true17 PASS internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 18 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() became "OutsideViewport" 19 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "OutsideViewport" 20 PASS grandChildFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "OutsideViewport" 21 21 PASS successfullyParsed is true 22 22 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-subframe-zero-size-expected.txt
r186195 r261113 4 4 5 5 6 PASS testFrame.contentWindow.internals. isRequestAnimationFrameThrottled() is false6 PASS testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 7 7 PASS successfullyParsed is true 8 8 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-subframe-zero-size.html
r186195 r261113 14 14 document.body.offsetTop; 15 15 16 shouldBe False("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");16 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 17 17 finishJSTest(); 18 18 } -
trunk/LayoutTests/fast/animation/request-animation-frame-throttle-subframe.html
r256512 r261113 9 9 function checkSubframesThrottled() 10 10 { 11 shouldBe True("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");12 shouldBe True("grandChildFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");11 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "OutsideViewport"); 12 shouldBeEqualToString("grandChildFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "OutsideViewport"); 13 13 14 14 finishJSTest(); … … 20 20 window.scroll(0, 0); 21 21 22 shouldBe False("internals.isRequestAnimationFrameThrottled()");23 shouldBecomeEqual ("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()", "true", checkSubframesThrottled);22 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 23 shouldBecomeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "OutsideViewport", checkSubframesThrottled); 24 24 } 25 25 26 26 function scrollFrameIntoView() 27 27 { 28 shouldBe False("internals.isRequestAnimationFrameThrottled()");29 shouldBe True("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");30 shouldBe True("grandChildFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");28 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 29 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "OutsideViewport"); 30 shouldBeEqualToString("grandChildFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "OutsideViewport"); 31 31 32 32 debug("Scrolling frame into view."); … … 34 34 35 35 debug("RequestAnimationFrame should no longer be throttled"); 36 shouldBe False("internals.isRequestAnimationFrameThrottled()");37 shouldBe False("grandChildFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");38 shouldBe False("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()");36 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 37 shouldBeEqualToString("grandChildFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 38 shouldBeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 39 39 40 40 scrollFrameOutOfView(); … … 46 46 grandChildFrame = testFrame.contentDocument.getElementById("grandChildFrame"); 47 47 debug("Frame is initially outside the viewport so requestAnimationFrame should be throttled"); 48 shouldBecomeEqual ("testFrame.contentWindow.internals.isRequestAnimationFrameThrottled()", "true", scrollFrameIntoView);48 shouldBecomeEqualToString("testFrame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "OutsideViewport", scrollFrameIntoView); 49 49 } 50 50 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttling-detached-iframe-expected.txt
r213169 r261113 4 4 5 5 6 PASS internals. isRequestAnimationFrameThrottled() is false6 PASS internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 7 7 PASS internals.requestAnimationFrameInterval is 0.015 8 PASS frame.contentWindow.internals. isRequestAnimationFrameThrottled() is false8 PASS frame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 9 9 PASS frame.contentWindow.internals.requestAnimationFrameInterval is 0.015 10 10 internals.setLowPowerModeEnabled(true); 11 PASS internals. isRequestAnimationFrameThrottled() is true11 PASS internals.requestAnimationFrameThrottlingReasons() is "LowPowerMode" 12 12 PASS internals.requestAnimationFrameInterval is 0.030 13 PASS frame.contentWindow.internals. isRequestAnimationFrameThrottled() is true13 PASS frame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "LowPowerMode" 14 14 PASS frame.contentWindow.internals.requestAnimationFrameInterval is 0.030 15 15 frame.remove() 16 16 document.body.appendChild(frame) 17 PASS internals. isRequestAnimationFrameThrottled() is true17 PASS internals.requestAnimationFrameThrottlingReasons() is "LowPowerMode" 18 18 PASS internals.requestAnimationFrameInterval is 0.030 19 PASS frame.contentWindow.internals. isRequestAnimationFrameThrottled() is true19 PASS frame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "LowPowerMode" 20 20 PASS frame.contentWindow.internals.requestAnimationFrameInterval is 0.030 21 21 frame.remove() 22 22 internals.setLowPowerModeEnabled(false); 23 PASS internals. isRequestAnimationFrameThrottled() is false23 PASS internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 24 24 PASS internals.requestAnimationFrameInterval is 0.015 25 25 document.body.appendChild(frame) 26 PASS frame.contentWindow.internals. isRequestAnimationFrameThrottled() is false26 PASS frame.contentWindow.internals.requestAnimationFrameThrottlingReasons() is "[Unthrottled]" 27 27 PASS frame.contentWindow.internals.requestAnimationFrameInterval is 0.015 28 28 PASS successfullyParsed is true -
trunk/LayoutTests/fast/animation/request-animation-frame-throttling-detached-iframe.html
r256512 r261113 19 19 frame.src = "resources/frame-with-animation.html"; 20 20 frame.onload = function() { 21 shouldBe False("internals.isRequestAnimationFrameThrottled()");21 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 22 22 shouldBe("internals.requestAnimationFrameInterval", "0.015"); 23 shouldBe False("frame.contentWindow.internals.isRequestAnimationFrameThrottled()");23 shouldBeEqualToString("frame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 24 24 shouldBe("frame.contentWindow.internals.requestAnimationFrameInterval", "0.015"); 25 25 26 26 evalAndLog("internals.setLowPowerModeEnabled(true);"); 27 shouldBe True("internals.isRequestAnimationFrameThrottled()");27 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "LowPowerMode"); 28 28 shouldBe("internals.requestAnimationFrameInterval", "0.030"); 29 shouldBe True("frame.contentWindow.internals.isRequestAnimationFrameThrottled()");29 shouldBeEqualToString("frame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "LowPowerMode"); 30 30 shouldBe("frame.contentWindow.internals.requestAnimationFrameInterval", "0.030"); 31 31 evalAndLog("frame.remove()"); … … 33 33 evalAndLog("document.body.appendChild(frame)"); 34 34 frame.onload = function() { 35 shouldBe True("internals.isRequestAnimationFrameThrottled()");35 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "LowPowerMode"); 36 36 shouldBe("internals.requestAnimationFrameInterval", "0.030"); 37 shouldBe True("frame.contentWindow.internals.isRequestAnimationFrameThrottled()");37 shouldBeEqualToString("frame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "LowPowerMode"); 38 38 shouldBe("frame.contentWindow.internals.requestAnimationFrameInterval", "0.030"); 39 39 40 40 evalAndLog("frame.remove()"); 41 41 evalAndLog("internals.setLowPowerModeEnabled(false);"); 42 shouldBe False("internals.isRequestAnimationFrameThrottled()");42 shouldBeEqualToString("internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 43 43 shouldBe("internals.requestAnimationFrameInterval", "0.015"); 44 44 45 45 evalAndLog("document.body.appendChild(frame)"); 46 46 frame.onload = function() { 47 shouldBe False("frame.contentWindow.internals.isRequestAnimationFrameThrottled()");47 shouldBeEqualToString("frame.contentWindow.internals.requestAnimationFrameThrottlingReasons()", "[Unthrottled]"); 48 48 shouldBe("frame.contentWindow.internals.requestAnimationFrameInterval", "0.015"); 49 49 finishJSTest(); -
trunk/LayoutTests/fast/animation/request-animation-frame-throttling-lowPowerMode-expected.txt
r256512 r261113 4 4 5 5 6 PASS internals.isRequestAnimationFrameThrottled() is false 7 PASS internals.requestAnimationFrameInterval is Infinity 8 rAFHandle = requestAnimationFrame(doWork); 9 PASS internals.isRequestAnimationFrameThrottled() is false 10 PASS internals.requestAnimationFrameInterval is 0.015 11 internals.setLowPowerModeEnabled(true); 12 PASS internals.isRequestAnimationFrameThrottled() is true 13 PASS internals.requestAnimationFrameInterval is 0.030 14 cancelAnimationFrame(rAFHandle); 15 PASS internals.isRequestAnimationFrameThrottled() is true 16 PASS internals.requestAnimationFrameInterval is 0.030 17 rAFHandle = requestAnimationFrame(doWork); 18 PASS internals.isRequestAnimationFrameThrottled() is true 19 PASS internals.requestAnimationFrameInterval is 0.030 20 internals.setLowPowerModeEnabled(false); 21 PASS internals.isRequestAnimationFrameThrottled() is false 22 PASS internals.requestAnimationFrameInterval is 0.015 6 PASS farmesPerSecond < 35 is true 23 7 PASS successfullyParsed is true 24 8 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttling-lowPowerMode.html
r256512 r261113 2 2 <html> 3 3 <body> 4 <script src="../../resources/js-test-pre.js"></script> 5 <script> 6 description("Test that requestAnimationFrame gets throttled in low power mode."); 4 <script src="../../resources/js-test-pre.js"></script> 5 <script> 6 description("Test that requestAnimationFrame gets throttled in low power mode."); 7 window.jsTestIsAsync = true; 7 8 8 let rAFHandle; 9 let i = 0; 10 function doWork() 11 { 12 i++; 13 rAFHandle = requestAnimationFrame(doWork); 14 } 9 if (window.internals) 10 internals.setLowPowerModeEnabled(true); 15 11 16 shouldBeFalse("internals.isRequestAnimationFrameThrottled()"); 17 shouldBe("internals.requestAnimationFrameInterval", "Infinity"); 18 evalAndLog("rAFHandle = requestAnimationFrame(doWork);"); 19 shouldBeFalse("internals.isRequestAnimationFrameThrottled()"); 20 shouldBe("internals.requestAnimationFrameInterval", "0.015"); 21 evalAndLog("internals.setLowPowerModeEnabled(true);"); 22 shouldBeTrue("internals.isRequestAnimationFrameThrottled()"); 23 shouldBe("internals.requestAnimationFrameInterval", "0.030"); 24 evalAndLog("cancelAnimationFrame(rAFHandle);"); 25 shouldBeTrue("internals.isRequestAnimationFrameThrottled()"); 26 shouldBe("internals.requestAnimationFrameInterval", "0.030"); 27 evalAndLog("rAFHandle = requestAnimationFrame(doWork);"); 28 shouldBeTrue("internals.isRequestAnimationFrameThrottled()"); 29 shouldBe("internals.requestAnimationFrameInterval", "0.030"); 30 evalAndLog("internals.setLowPowerModeEnabled(false);"); 31 shouldBeFalse("internals.isRequestAnimationFrameThrottled()"); 32 shouldBe("internals.requestAnimationFrameInterval", "0.015"); 33 </script> 34 <script src="../../resources/js-test-post.js"></script> 12 var start = null; 13 var farmesPerSecond = 0; 14 function doWork(timestamp) { 15 if (!start) 16 start = timestamp; 17 if (timestamp - start < 1000) { 18 ++farmesPerSecond; 19 window.requestAnimationFrame(doWork); 20 } 21 else { 22 // The LowPowerMode throttling interval = 30_ms. The frame rate ~= 33.3 fps. 23 shouldBeTrue("farmesPerSecond < 35"); 24 finishJSTest(); 25 } 26 } 27 window.requestAnimationFrame(doWork); 28 </script> 29 <script src="../../resources/js-test-post.js"></script> 35 30 </body> 36 31 </html> -
trunk/LayoutTests/http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe-expected.txt
r215070 r261113 7 7 Received message: frameload 8 8 Checking that requestAnimationFrame is throttled in cross origin frame 9 Received message: throttled[cross]: true10 Received message: throttled[same]: false11 PASS throttledState['cross'] is " true"12 PASS throttledState['same'] is " false"9 Received message: throttled[cross]: NonInteractiveCrossOriginFrame 10 Received message: throttled[same]: [Unthrottled] 11 PASS throttledState['cross'] is "NonInteractiveCrossOriginFrame" 12 PASS throttledState['same'] is "[Unthrottled]" 13 13 Interacted with cross-origin frame 14 14 Interacted with same-origin frame 15 Received message: throttled[cross]: false16 Received message: throttled[same]: false17 PASS throttledState['cross'] is " false"18 PASS throttledState['same'] is " false"15 Received message: throttled[cross]: [Unthrottled] 16 Received message: throttled[same]: [Unthrottled] 17 PASS throttledState['cross'] is "[Unthrottled]" 18 PASS throttledState['same'] is "[Unthrottled]" 19 19 PASS successfullyParsed is true 20 20 -
trunk/LayoutTests/http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html
r256512 r261113 55 55 function checkInitiallyThrottled() 56 56 { 57 shouldBeEqualToString("throttledState['cross']", " true");58 shouldBeEqualToString("throttledState['same']", " false");57 shouldBeEqualToString("throttledState['cross']", "NonInteractiveCrossOriginFrame"); 58 shouldBeEqualToString("throttledState['same']", "[Unthrottled]"); 59 59 interactWithSubframes(); 60 60 } … … 62 62 function checkUnthrottledAfterInteraction() 63 63 { 64 shouldBeEqualToString("throttledState['cross']", " false");65 shouldBeEqualToString("throttledState['same']", " false");64 shouldBeEqualToString("throttledState['cross']", "[Unthrottled]"); 65 shouldBeEqualToString("throttledState['same']", "[Unthrottled]"); 66 66 finishJSTest(); 67 67 } … … 76 76 } 77 77 78 var re = /throttled\[(\w+)\]: ( true|false)/;78 var re = /throttled\[(\w+)\]: ((\w+)(\|\w+)*|\[Unthrottled\])/; 79 79 var match = re.exec(message.data); 80 80 if (match) { -
trunk/LayoutTests/http/tests/frame-throttling/resources/requestAnimationFrame-frame.html
r215820 r261113 19 19 var frameId = match[1]; 20 20 if (window.internals) 21 parent.window.postMessage("throttled[" + frameId + "]: " + internals. isRequestAnimationFrameThrottled(), "*");21 parent.window.postMessage("throttled[" + frameId + "]: " + internals.requestAnimationFrameThrottlingReasons(), "*"); 22 22 } 23 23 } -
trunk/Source/WebCore/ChangeLog
r261110 r261113 1 2020-05-04 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 Throttling requestAnimationFrame should be controlled by RenderingUpdateScheduler 4 https://bugs.webkit.org/show_bug.cgi?id=204713 5 6 Reviewed by Simon Fraser. 7 8 rAF and Page rendering were managed by two different timers. Throttling 9 rAF was implemented by changing its timer. After r242624, RenderingUpdate 10 steps have been managed by RenderingUpdateScheduler. This means rAF is 11 now serviced by the preferredFramesPerSecond which is 60 fps regardless 12 it's throttled or not. Moreover the rAF throttling timer was mistakenly 13 kept and it has been running under the old assumption which is: rAF is 14 serviced by a timer only. This means rAF will be serviced by its timer 15 and by the RenderingUpdate steps at the same time when it is supposed to 16 throttle. This will make it fire more than 60 fps in cases which it is 17 supposed to run less than 60 fps. 18 19 The solution is to have two throttling types: 20 21 1) Page throttling (or full throttling): This slows down all the steps 22 of RenderingUpdate for the main document and all the sub-documents. 23 Page throttling reasons are: 24 -- VisuallyIdle: Aggressive throttling. 25 -- LowPowerMode: Half speed throttling. 26 2) Document throttling (or partial throttling): This only slows down the 27 rAF of a certain document. Document throttling reasons are: 28 -- OutsideViewport: Aggressive throttling. 29 -- NonInteractedCrossOriginFrame: Half speed throttling. 30 31 RenderingUpdate steps will still be managed by RenderingUpdateScheduler 32 which can be throttled. The assumption is none of these steps will need 33 to run faster than the Page preferredFramesPerSecond. If rAF wants to 34 run slower than the Page because of a Document throttling reason, no rAF 35 callbacks will be serviced before its preferredFrameInterval has elapsed. 36 37 In this patch, "Half speed throttling" is only implemented for the Page 38 and the Document throttling. The "Aggressive throttling" will be done in 39 following patches. Page rendering was never throttled before. We need to 40 make sure this is not going to affect PLT. Some tests need to be changed 41 and new tests need to be written. All of the throttling tests checks the 42 state of the code but none of them checks the real user's experience. 43 44 * Headers.cmake: 45 * WebCore.xcodeproj/project.pbxproj: 46 47 * animation/DocumentTimeline.cpp: 48 (WebCore::DocumentTimeline::animationInterval const): 49 (WebCore::DocumentTimeline::updateThrottlingState): Deleted. 50 * animation/DocumentTimeline.h: 51 There is no need to have DocumentTimeline throttling. It is already 52 throttled when the page RenderingUpdate is throttled. 53 54 * dom/Document.cpp: 55 (WebCore::Document::requestAnimationFrame): 56 (WebCore::Document::updateLastHandledUserGestureTimestamp): 57 LowPowerMode throttling is now handled by the Page. So remove its handling 58 from the Document. 59 60 * dom/ScriptedAnimationController.cpp: 61 (WebCore::ScriptedAnimationController::ScriptedAnimationController): 62 (WebCore::ScriptedAnimationController::page const): 63 (WebCore::ScriptedAnimationController::interval const): 64 (WebCore::ScriptedAnimationController::preferredScriptedAnimationInterval const): 65 (WebCore::ScriptedAnimationController::throttlingReasons const): 66 (WebCore::ScriptedAnimationController::isThrottledRelativeToPage const): 67 (WebCore::ScriptedAnimationController::shouldRescheduleRequestAnimationFrame const): 68 (WebCore::ScriptedAnimationController::registerCallback): 69 (WebCore::ScriptedAnimationController::cancelCallback): 70 (WebCore::ScriptedAnimationController::serviceRequestAnimationFrameCallbacks): 71 (WebCore::ScriptedAnimationController::scheduleAnimation): 72 (WebCore::throttlingReasonToString): Deleted. 73 (WebCore::throttlingReasonsToString): Deleted. 74 (WebCore::ScriptedAnimationController::addThrottlingReason): Deleted. 75 (WebCore::ScriptedAnimationController::removeThrottlingReason): Deleted. 76 (WebCore::ScriptedAnimationController::isThrottled const): Deleted. 77 (WebCore::ScriptedAnimationController::animationTimerFired): Deleted. 78 * dom/ScriptedAnimationController.h: 79 (WebCore::ScriptedAnimationController::addThrottlingReason): 80 (WebCore::ScriptedAnimationController::removeThrottlingReason): 81 Get rid of the rAF throttling timer. Service the rAF callback only when 82 the period from the current time stamp till the last service time stamp 83 is greater than the preferred rAF interval. 84 85 * page/FrameView.cpp: 86 (WebCore::FrameView::updateScriptedAnimationsAndTimersThrottlingState): 87 ThrottlingReason is now defined outside ScriptedAnimationController. 88 89 * page/Page.cpp: 90 (WebCore::m_loadsFromNetwork): 91 (WebCore::Page::setLowPowerModeEnabledOverrideForTesting): 92 93 (WebCore::Page::preferredRenderingUpdateInterval const): 94 Calculate the preferred RenderingUpdate interval from the throttling 95 reasons. 96 97 (WebCore::Page::setIsVisuallyIdleInternal): 98 (WebCore::Page::handleLowModePowerChange): 99 Call adjustRenderingUpdateFrequency() when isLowPowerModeEnabled or 100 IsVisuallyIdle is toggled. 101 102 (WebCore::Page::isLowPowerModeEnabled const): Deleted. 103 (WebCore::updateScriptedAnimationsThrottlingReason): Deleted. 104 * page/Page.h: 105 (WebCore::Page::isLowPowerModeEnabled const): 106 (WebCore::Page::throttlingReasons const): 107 (WebCore::Page::canUpdateThrottlingReason const): 108 109 * page/RenderingUpdateScheduler.cpp: 110 (WebCore::RenderingUpdateScheduler::setPreferredFramesPerSecond): 111 (WebCore::RenderingUpdateScheduler::scheduleAnimation): 112 (WebCore::RenderingUpdateScheduler::adjustRenderingUpdateFrequency): 113 Change the preferredFramesPerSecond of the DisplayRefreshMonitor if the 114 throttling is not aggressive e.g. 10_s. Otherwise use the timer. 115 116 (WebCore::RenderingUpdateScheduler::scheduleTimedRenderingUpdate): 117 Call adjustFramesPerSecond() when DisplayRefreshMonitor is created. 118 119 (WebCore::RenderingUpdateScheduler::startTimer): 120 * page/RenderingUpdateScheduler.h: 121 * platform/graphics/AnimationFrameRate.h: Added. 122 (WebCore::preferredFrameInterval): 123 (WebCore::preferredFramesPerSecond): 124 (WebCore::operator<<): 125 Push names of ThrottlingReasons to a TextStream. 126 127 * platform/graphics/DisplayRefreshMonitor.h: 128 (WebCore::DisplayRefreshMonitor::setPreferredFramesPerSecond): 129 * platform/graphics/DisplayRefreshMonitorManager.cpp: 130 (WebCore::DisplayRefreshMonitorManager::monitorForClient): 131 Rename createMonitorForClient() to monitorForClient() since it may return 132 a cached DisplayRefreshMonitor. 133 134 (WebCore::DisplayRefreshMonitorManager::setPreferredFramesPerSecond): 135 (WebCore::DisplayRefreshMonitorManager::scheduleAnimation): 136 (WebCore::DisplayRefreshMonitorManager::windowScreenDidChange): 137 No need to call registerClient(). This function was just ensuring the 138 DisplayRefreshMonitor is created. scheduleAnimation() does the same thing. 139 140 (WebCore::DisplayRefreshMonitorManager::createMonitorForClient): Deleted. 141 (WebCore::DisplayRefreshMonitorManager::registerClient): Deleted. 142 * platform/graphics/DisplayRefreshMonitorManager.h: 143 (WebCore::DisplayRefreshMonitorManager::DisplayRefreshMonitorManager): Deleted. 144 145 * platform/graphics/GraphicsLayerUpdater.cpp: 146 (WebCore::GraphicsLayerUpdater::GraphicsLayerUpdater): 147 * platform/graphics/ios/DisplayRefreshMonitorIOS.mm: 148 (-[WebDisplayLinkHandler setPreferredFramesPerSecond:]): 149 Set the preferredFramesPerSecond of the CADisplayLink. 150 151 * testing/Internals.cpp: 152 (WebCore::Internals::requestAnimationFrameThrottlingReasons const): 153 (WebCore::Internals::isRequestAnimationFrameThrottled const): Deleted. 154 * testing/Internals.h: 155 * testing/Internals.idl: 156 Replace isRequestAnimationFrameThrottled() which returns a boolean by 157 requestAnimationFrameThrottlingReasons() which returns a string. The 158 string represents the throttling reasons. 159 1 160 2020-05-04 Darin Adler <darin@apple.com> 2 161 -
trunk/Source/WebCore/Headers.cmake
r260736 r261113 1073 1073 platform/graphics/AlphaPremultiplication.h 1074 1074 platform/graphics/ANGLEWebKitBridge.h 1075 platform/graphics/AnimationFrameRate.h 1075 1076 platform/graphics/AudioTrackPrivate.h 1076 1077 platform/graphics/BitmapImage.h -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r261077 r261113 2156 2156 7299BC6723D6A53200CC6883 /* AlphaPremultiplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6423D686A600CC6883 /* AlphaPremultiplication.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2157 2157 7299BC6823D6A53E00CC6883 /* RenderingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6623D686C600CC6883 /* RenderingMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2158 72A73BEF245A3F90001C9D03 /* AnimationFrameRate.h in Headers */ = {isa = PBXBuildFile; fileRef = 722A815C238FD50500C00583 /* AnimationFrameRate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2158 2159 72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BAC3A523E17328008D741C /* ImageBufferBackend.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2159 2160 7553CFE8108F473F00EA281E /* TimelineRecordFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7553CFE6108F473F00EA281E /* TimelineRecordFactory.h */; }; … … 9714 9715 721443452240C8BA00F12FF7 /* SVGAnimatedValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedValueProperty.h; sourceTree = "<group>"; }; 9715 9716 721443462240CAD200F12FF7 /* SVGValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGValueProperty.h; sourceTree = "<group>"; }; 9717 722A815C238FD50500C00583 /* AnimationFrameRate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimationFrameRate.h; sourceTree = "<group>"; }; 9716 9718 724ED3291A3A7E5400F5F13C /* EXTBlendMinMax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXTBlendMinMax.cpp; sourceTree = "<group>"; }; 9717 9719 724ED32A1A3A7E5400F5F13C /* EXTBlendMinMax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTBlendMinMax.h; sourceTree = "<group>"; }; … … 25325 25327 490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */, 25326 25328 490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */, 25329 722A815C238FD50500C00583 /* AnimationFrameRate.h */, 25327 25330 BEF29EE91715DD0900C4B4C9 /* AudioTrackPrivate.h */, 25328 25331 A89943270B42338700D7C802 /* BitmapImage.cpp */, … … 29515 29518 319848011A1D817B00A13318 /* AnimationEvent.h in Headers */, 29516 29519 711AD126236D86E5006FF37C /* AnimationEventBase.h in Headers */, 29520 72A73BEF245A3F90001C9D03 /* AnimationFrameRate.h in Headers */, 29517 29521 49E912AD0EFAC906009D0CAF /* AnimationList.h in Headers */, 29518 29522 714C7C661FDAD2A100F2BEE1 /* AnimationPlaybackEvent.h in Headers */, -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r260736 r261113 47 47 #include <JavaScriptCore/VM.h> 48 48 49 static const Seconds defaultAnimationInterval { 15_ms };50 static const Seconds throttledAnimationInterval { 30_ms };51 52 49 namespace WebCore { 53 50 … … 215 212 } 216 213 217 void DocumentTimeline::updateThrottlingState()218 {219 scheduleAnimationResolution();220 }221 222 214 Seconds DocumentTimeline::animationInterval() const 223 215 { 224 216 if (!m_document || !m_document->page()) 225 217 return Seconds::infinity(); 226 return m_document->page()-> isLowPowerModeEnabled() ? throttledAnimationInterval : defaultAnimationInterval;218 return m_document->page()->preferredRenderingUpdateInterval(); 227 219 } 228 220 -
trunk/Source/WebCore/animation/DocumentTimeline.h
r260736 r261113 81 81 void documentDidUpdateAnimationsAndSendEvents(); 82 82 83 void updateThrottlingState();84 83 WEBCORE_EXPORT Seconds animationInterval() const; 85 84 WEBCORE_EXPORT void suspendAnimations(); -
trunk/Source/WebCore/dom/Document.cpp
r261028 r261113 6554 6554 m_scriptedAnimationController->suspend(); 6555 6555 6556 if (page() && page()->isLowPowerModeEnabled())6557 m_scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::LowPowerMode);6558 6559 6556 if (!topOrigin().canAccess(securityOrigin()) && !hasHadUserInteraction()) 6560 m_scriptedAnimationController->addThrottlingReason( ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame);6557 m_scriptedAnimationController->addThrottlingReason(ThrottlingReason::NonInteractedCrossOriginFrame); 6561 6558 } 6562 6559 … … 6797 6794 if (static_cast<bool>(time) && m_scriptedAnimationController) { 6798 6795 // It's OK to always remove NonInteractedCrossOriginFrame even if this frame isn't cross-origin. 6799 m_scriptedAnimationController->removeThrottlingReason( ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame);6796 m_scriptedAnimationController->removeThrottlingReason(ThrottlingReason::NonInteractedCrossOriginFrame); 6800 6797 } 6801 6798 -
trunk/Source/WebCore/dom/ScriptedAnimationController.cpp
r260870 r261113 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All Rights Reserved. 3 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 27 28 #include "ScriptedAnimationController.h" 28 29 29 #include "Chrome.h"30 #include "ChromeClient.h"31 #include "CustomHeaderFields.h"32 #include "DOMWindow.h"33 #include "Document.h"34 #include "DocumentLoader.h"35 #include "Frame.h"36 #include "FrameView.h"37 30 #include "InspectorInstrumentation.h" 38 #include "Logging.h"39 31 #include "Page.h" 40 #include "Performance.h"41 32 #include "Quirks.h" 42 33 #include "RequestAnimationFrameCallback.h" 43 34 #include "Settings.h" 44 #include <algorithm>45 35 #include <wtf/Ref.h> 46 36 #include <wtf/SystemTracing.h> 47 #include <wtf/text/StringBuilder.h>48 49 // Allow a little more than 60fps to make sure we can at least hit that frame rate.50 static const Seconds fullSpeedAnimationInterval { 15_ms };51 // Allow a little more than 30fps to make sure we can at least hit that frame rate.52 static const Seconds halfSpeedThrottlingAnimationInterval { 30_ms };53 static const Seconds aggressiveThrottlingAnimationInterval { 10_s };54 55 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(page() && page()->isAlwaysOnLoggingAllowed(), PerformanceLogging, "%p - ScriptedAnimationController::" fmt, this, ##__VA_ARGS__)56 37 57 38 namespace WebCore { … … 59 40 ScriptedAnimationController::ScriptedAnimationController(Document& document) 60 41 : m_document(makeWeakPtr(document)) 61 , m_animationTimer(*this, &ScriptedAnimationController::animationTimerFired)62 42 { 63 43 } … … 86 66 } 87 67 88 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && !RELEASE_LOG_DISABLED 89 90 static const char* throttlingReasonToString(ScriptedAnimationController::ThrottlingReason reason) 68 Page* ScriptedAnimationController::page() const 91 69 { 92 switch (reason) { 93 case ScriptedAnimationController::ThrottlingReason::VisuallyIdle: 94 return "VisuallyIdle"; 95 case ScriptedAnimationController::ThrottlingReason::OutsideViewport: 96 return "OutsideViewport"; 97 case ScriptedAnimationController::ThrottlingReason::LowPowerMode: 98 return "LowPowerMode"; 99 case ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame: 100 return "NonInteractiveCrossOriginFrame"; 101 } 102 RELEASE_ASSERT_NOT_REACHED(); 103 return ""; 70 return m_document ? m_document->page() : nullptr; 104 71 } 105 72 106 static String throttlingReasonsToString(OptionSet<ScriptedAnimationController::ThrottlingReason> reasons) 73 Seconds ScriptedAnimationController::interval() const 107 74 { 108 if (reasons.isEmpty()) 109 return "[Unthrottled]"_s; 110 111 StringBuilder builder; 112 for (auto reason : reasons) { 113 if (!builder.isEmpty()) 114 builder.append('|'); 115 builder.append(throttlingReasonToString(reason)); 116 } 117 return builder.toString(); 75 if (auto* page = this->page()) 76 return std::max(preferredScriptedAnimationInterval(), page->preferredRenderingUpdateInterval()); 77 return FullSpeedAnimationInterval; 118 78 } 119 79 120 #endif 121 122 void ScriptedAnimationController::addThrottlingReason(ThrottlingReason reason) 80 Seconds ScriptedAnimationController::preferredScriptedAnimationInterval() const 123 81 { 124 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 125 if (m_throttlingReasons.contains(reason)) 126 return; 127 128 m_throttlingReasons.add(reason); 129 130 RELEASE_LOG_IF_ALLOWED("addThrottlingReason(%s) -> %s", throttlingReasonToString(reason), throttlingReasonsToString(m_throttlingReasons).utf8().data()); 131 132 if (m_animationTimer.isActive()) { 133 m_animationTimer.stop(); 134 scheduleAnimation(); 135 } 136 #else 137 UNUSED_PARAM(reason); 138 #endif 82 if (auto* page = this->page()) 83 return preferredFrameInterval(m_throttlingReasons); 84 return FullSpeedAnimationInterval; 139 85 } 140 86 141 void ScriptedAnimationController::removeThrottlingReason(ThrottlingReason reason) 87 OptionSet<ThrottlingReason> ScriptedAnimationController::throttlingReasons() const 142 88 { 143 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 144 if (!m_throttlingReasons.contains(reason)) 145 return; 146 147 m_throttlingReasons.remove(reason); 148 149 RELEASE_LOG_IF_ALLOWED("removeThrottlingReason(%s) -> %s", throttlingReasonToString(reason), throttlingReasonsToString(m_throttlingReasons).utf8().data()); 150 151 if (m_animationTimer.isActive()) { 152 m_animationTimer.stop(); 153 scheduleAnimation(); 154 } 155 #else 156 UNUSED_PARAM(reason); 157 #endif 89 if (auto* page = this->page()) 90 return page->throttlingReasons() | m_throttlingReasons; 91 return { }; 158 92 } 159 93 160 bool ScriptedAnimationController::isThrottled () const94 bool ScriptedAnimationController::isThrottledRelativeToPage() const 161 95 { 162 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 163 return !m_throttlingReasons.isEmpty(); 164 #else 96 if (auto* page = this->page()) 97 return preferredScriptedAnimationInterval() > page->preferredRenderingUpdateInterval(); 165 98 return false; 166 #endif 99 } 100 101 bool ScriptedAnimationController::shouldRescheduleRequestAnimationFrame(ReducedResolutionSeconds timestamp) const 102 { 103 return isThrottledRelativeToPage() && (timestamp - m_lastAnimationFrameTimestamp < preferredScriptedAnimationInterval()); 167 104 } 168 105 169 106 ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(Ref<RequestAnimationFrameCallback>&& callback) 170 107 { 171 ScriptedAnimationController::CallbackId id = ++m_nextCallbackId;108 CallbackId callbackId = ++m_nextCallbackId; 172 109 callback->m_firedOrCancelled = false; 173 callback->m_id = id;110 callback->m_id = callbackId; 174 111 m_callbacks.append(WTFMove(callback)); 175 112 176 113 if (m_document) 177 InspectorInstrumentation::didRequestAnimationFrame(*m_document, id);114 InspectorInstrumentation::didRequestAnimationFrame(*m_document, callbackId); 178 115 179 116 if (!m_suspendCount) 180 117 scheduleAnimation(); 181 return id;118 return callbackId; 182 119 } 183 120 184 void ScriptedAnimationController::cancelCallback(CallbackId id)121 void ScriptedAnimationController::cancelCallback(CallbackId callbackId) 185 122 { 186 for (size_t i = 0; i < m_callbacks.size(); ++i) { 187 if (m_callbacks[i]->m_id == id) { 188 m_callbacks[i]->m_firedOrCancelled = true; 189 InspectorInstrumentation::didCancelAnimationFrame(*m_document, id); 190 m_callbacks.remove(i); 191 return; 192 } 193 } 123 bool cancelled = m_callbacks.removeFirstMatching([callbackId](auto& callback) { 124 if (callback->m_id != callbackId) 125 return false; 126 callback->m_firedOrCancelled = true; 127 return true; 128 }); 129 130 if (cancelled && m_document) 131 InspectorInstrumentation::didCancelAnimationFrame(*m_document, callbackId); 194 132 } 195 133 … … 199 137 return; 200 138 139 if (shouldRescheduleRequestAnimationFrame(timestamp)) { 140 scheduleAnimation(); 141 return; 142 } 143 201 144 TraceScope tracingScope(RAFCallbackStart, RAFCallbackEnd); 202 145 … … 229 172 }); 230 173 174 m_lastAnimationFrameTimestamp = timestamp; 175 231 176 if (m_callbacks.size()) 232 177 scheduleAnimation(); 233 }234 235 Seconds ScriptedAnimationController::interval() const236 {237 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)238 if (m_throttlingReasons.contains(ThrottlingReason::VisuallyIdle) || m_throttlingReasons.contains(ThrottlingReason::OutsideViewport))239 return aggressiveThrottlingAnimationInterval;240 241 if (m_throttlingReasons.contains(ThrottlingReason::LowPowerMode))242 return halfSpeedThrottlingAnimationInterval;243 244 if (m_throttlingReasons.contains(ThrottlingReason::NonInteractedCrossOriginFrame))245 return halfSpeedThrottlingAnimationInterval;246 247 ASSERT(m_throttlingReasons.isEmpty());248 #endif249 return fullSpeedAnimationInterval;250 }251 252 Page* ScriptedAnimationController::page() const253 {254 return m_document ? m_document->page() : nullptr;255 178 } 256 179 … … 260 183 return; 261 184 262 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 263 if (!m_isUsingTimer && !isThrottled()) { 264 if (auto* page = this->page()) { 265 page->renderingUpdateScheduler().scheduleTimedRenderingUpdate(); 266 return; 267 } 268 269 m_isUsingTimer = true; 270 } 271 #endif 272 if (m_animationTimer.isActive()) 273 return; 274 275 Seconds animationInterval = interval(); 276 Seconds scheduleDelay = std::max(animationInterval - (m_document->domWindow()->nowTimestamp() - m_lastAnimationFrameTimestamp), 0_s); 277 278 if (isThrottled()) { 279 // FIXME: not ideal to snapshot time both in now() and nowTimestamp(), the latter of which also has reduced resolution. 280 MonotonicTime now = MonotonicTime::now(); 281 282 MonotonicTime fireTime = now + scheduleDelay; 283 Seconds alignmentInterval = 10_ms; 284 // Snap to the nearest alignmentInterval. 285 Seconds alignment = (fireTime + alignmentInterval / 2) % alignmentInterval; 286 MonotonicTime alignedFireTime = fireTime - alignment; 287 scheduleDelay = alignedFireTime - now; 288 } 289 290 m_animationTimer.startOneShot(scheduleDelay); 291 } 292 293 void ScriptedAnimationController::animationTimerFired() 294 { 295 m_lastAnimationFrameTimestamp = m_document->domWindow()->nowTimestamp(); 296 serviceRequestAnimationFrameCallbacks(m_lastAnimationFrameTimestamp); 185 if (auto* page = this->page()) 186 page->renderingUpdateScheduler().scheduleTimedRenderingUpdate(); 297 187 } 298 188 -
trunk/Source/WebCore/dom/ScriptedAnimationController.h
r260818 r261113 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All Rights Reserved. 3 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 26 27 #pragma once 27 28 28 #include " DOMHighResTimeStamp.h"29 #include "AnimationFrameRate.h" 29 30 #include "ReducedResolutionSeconds.h" 30 31 #include "Timer.h" … … 51 52 bool requestAnimationFrameEnabled() const; 52 53 53 typedef int CallbackId; 54 WEBCORE_EXPORT Seconds interval() const; 55 WEBCORE_EXPORT OptionSet<ThrottlingReason> throttlingReasons() const; 54 56 57 void suspend(); 58 void resume(); 59 60 void addThrottlingReason(ThrottlingReason reason) { m_throttlingReasons.add(reason); } 61 void removeThrottlingReason(ThrottlingReason reason) { m_throttlingReasons.remove(reason); } 62 63 using CallbackId = int; 55 64 CallbackId registerCallback(Ref<RequestAnimationFrameCallback>&&); 56 65 void cancelCallback(CallbackId); 57 66 void serviceRequestAnimationFrameCallbacks(ReducedResolutionSeconds); 58 67 59 void suspend();60 void resume();61 62 enum class ThrottlingReason {63 VisuallyIdle = 1 << 0,64 OutsideViewport = 1 << 1,65 LowPowerMode = 1 << 2,66 NonInteractedCrossOriginFrame = 1 << 3,67 };68 void addThrottlingReason(ThrottlingReason);69 void removeThrottlingReason(ThrottlingReason);70 71 WEBCORE_EXPORT bool isThrottled() const;72 WEBCORE_EXPORT Seconds interval() const;73 74 68 private: 75 69 ScriptedAnimationController(Document&); 76 70 71 Page* page() const; 72 Seconds preferredScriptedAnimationInterval() const; 73 bool isThrottledRelativeToPage() const; 74 bool shouldRescheduleRequestAnimationFrame(ReducedResolutionSeconds) const; 77 75 void scheduleAnimation(); 78 void animationTimerFired();79 76 80 Page* page() const; 81 82 typedef Vector<RefPtr<RequestAnimationFrameCallback>> CallbackList; 77 using CallbackList = Vector<RefPtr<RequestAnimationFrameCallback>>; 83 78 CallbackList m_callbacks; 84 79 … … 87 82 int m_suspendCount { 0 }; 88 83 89 Timer m_animationTimer; 90 ReducedResolutionSeconds m_lastAnimationFrameTimestamp { 0 }; 91 92 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 84 ReducedResolutionSeconds m_lastAnimationFrameTimestamp; 93 85 OptionSet<ThrottlingReason> m_throttlingReasons; 94 bool m_isUsingTimer { false };95 #endif96 86 }; 97 87 -
trunk/Source/WebCore/page/FrameView.cpp
r261044 r261113 2531 2531 if (auto* scriptedAnimationController = document->scriptedAnimationController()) { 2532 2532 if (shouldThrottle) 2533 scriptedAnimationController->addThrottlingReason( ScriptedAnimationController::ThrottlingReason::OutsideViewport);2533 scriptedAnimationController->addThrottlingReason(ThrottlingReason::OutsideViewport); 2534 2534 else 2535 scriptedAnimationController->removeThrottlingReason( ScriptedAnimationController::ThrottlingReason::OutsideViewport);2535 scriptedAnimationController->removeThrottlingReason(ThrottlingReason::OutsideViewport); 2536 2536 } 2537 2537 -
trunk/Source/WebCore/page/Page.cpp
r261054 r261113 23 23 #include "ActivityStateChangeObserver.h" 24 24 #include "AlternativeTextClient.h" 25 #include "AnimationFrameRate.h" 25 26 #include "ApplicationCacheStorage.h" 26 27 #include "AuthenticatorCoordinator.h" … … 334 335 m_libWebRTCProvider->supportsH265(RuntimeEnabledFeatures::sharedFeatures().webRTCH265CodecEnabled()); 335 336 #endif 336 337 337 338 if (!pageConfiguration.userScriptsShouldWaitUntilNotification) 338 339 m_hasBeenNotifiedToInjectUserScripts = true; 340 341 if (m_lowPowerModeNotifier->isLowPowerModeEnabled()) 342 m_throttlingReasons.add(ThrottlingReason::LowPowerMode); 339 343 } 340 344 … … 1171 1175 } 1172 1176 1173 bool Page::isLowPowerModeEnabled() const1174 {1175 if (m_lowPowerModeEnabledOverrideForTesting)1176 return m_lowPowerModeEnabledOverrideForTesting.value();1177 1178 return m_lowPowerModeNotifier->isLowPowerModeEnabled();1179 }1180 1181 1177 void Page::setLowPowerModeEnabledOverrideForTesting(Optional<bool> isEnabled) 1182 1178 { 1183 m_lowPowerModeEnabledOverrideForTesting = isEnabled; 1184 handleLowModePowerChange(m_lowPowerModeEnabledOverrideForTesting.valueOr(false)); 1179 // Remove ThrottlingReason::LowPowerMode so handleLowModePowerChange() can do its work. 1180 m_throttlingReasonsOverridenForTesting.remove(ThrottlingReason::LowPowerMode); 1181 1182 // Use the current low power mode value of the device. 1183 if (!isEnabled) { 1184 handleLowModePowerChange(m_lowPowerModeNotifier->isLowPowerModeEnabled()); 1185 return; 1186 } 1187 1188 // Override the value and add ThrottlingReason::LowPowerMode so it override the device state. 1189 handleLowModePowerChange(isEnabled.value()); 1190 m_throttlingReasonsOverridenForTesting.add(ThrottlingReason::LowPowerMode); 1185 1191 } 1186 1192 … … 1475 1481 } 1476 1482 1477 enum class ThrottlingReasonOperation { Add, Remove }; 1478 static void updateScriptedAnimationsThrottlingReason(Page& page, ThrottlingReasonOperation operation, ScriptedAnimationController::ThrottlingReason reason) 1479 { 1480 page.forEachDocument([&] (Document& document) { 1481 if (auto* controller = document.scriptedAnimationController()) { 1482 if (operation == ThrottlingReasonOperation::Add) 1483 controller->addThrottlingReason(reason); 1484 else 1485 controller->removeThrottlingReason(reason); 1486 } 1487 }); 1483 Seconds Page::preferredRenderingUpdateInterval() const 1484 { 1485 return preferredFrameInterval(m_throttlingReasons); 1488 1486 } 1489 1487 1490 1488 void Page::setIsVisuallyIdleInternal(bool isVisuallyIdle) 1491 1489 { 1492 updateScriptedAnimationsThrottlingReason(*this, isVisuallyIdle ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::VisuallyIdle); 1490 if (isVisuallyIdle == m_throttlingReasons.contains(ThrottlingReason::VisuallyIdle)) 1491 return; 1492 1493 m_throttlingReasons = m_throttlingReasons ^ ThrottlingReason::VisuallyIdle; 1494 renderingUpdateScheduler().adjustRenderingUpdateFrequency(); 1493 1495 } 1494 1496 1495 1497 void Page::handleLowModePowerChange(bool isLowPowerModeEnabled) 1496 1498 { 1497 updateScriptedAnimationsThrottlingReason(*this, isLowPowerModeEnabled ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::LowPowerMode); 1498 if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) { 1499 forEachDocument([] (Document& document) { 1500 if (auto timeline = document.existingTimeline()) 1501 timeline->updateThrottlingState(); 1502 }); 1503 } else 1499 if (!canUpdateThrottlingReason(ThrottlingReason::LowPowerMode)) 1500 return; 1501 1502 if (isLowPowerModeEnabled == m_throttlingReasons.contains(ThrottlingReason::LowPowerMode)) 1503 return; 1504 1505 m_throttlingReasons = m_throttlingReasons ^ ThrottlingReason::LowPowerMode; 1506 renderingUpdateScheduler().adjustRenderingUpdateFrequency(); 1507 1508 if (!RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) 1504 1509 mainFrame().legacyAnimation().updateThrottlingState(); 1510 1505 1511 updateDOMTimerAlignmentInterval(); 1506 1512 } -
trunk/Source/WebCore/page/Page.h
r261031 r261113 22 22 23 23 #include "ActivityState.h" 24 #include "AnimationFrameRate.h" 24 25 #include "DisabledAdaptations.h" 25 26 #include "Document.h" … … 721 722 bool loadsFromNetwork() const { return m_loadsFromNetwork; } 722 723 723 bool isLowPowerModeEnabled() const ;724 bool isLowPowerModeEnabled() const { return m_throttlingReasons.contains(ThrottlingReason::LowPowerMode); } 724 725 WEBCORE_EXPORT void setLowPowerModeEnabledOverrideForTesting(Optional<bool>); 726 727 OptionSet<ThrottlingReason> throttlingReasons() const { return m_throttlingReasons; } 728 Seconds preferredRenderingUpdateInterval() const; 725 729 726 730 WEBCORE_EXPORT void applicationWillResignActive(); … … 790 794 void updateDOMTimerAlignmentInterval(); 791 795 void domTimerAlignmentIntervalIncreaseTimerFired(); 796 797 bool canUpdateThrottlingReason(ThrottlingReason reason) const { return !m_throttlingReasonsOverridenForTesting.contains(reason); } 792 798 793 799 void doAfterUpdateRendering(); … … 1001 1007 std::unique_ptr<PerformanceMonitor> m_performanceMonitor; 1002 1008 std::unique_ptr<LowPowerModeNotifier> m_lowPowerModeNotifier; 1003 Optional<bool> m_lowPowerModeEnabledOverrideForTesting; 1009 OptionSet<ThrottlingReason> m_throttlingReasons; 1010 OptionSet<ThrottlingReason> m_throttlingReasonsOverridenForTesting; 1004 1011 1005 1012 Optional<Navigation> m_navigationToLogWhenVisible; -
trunk/Source/WebCore/page/RenderingUpdateScheduler.cpp
r256834 r261113 1 1 /* 2 * Copyright (C) 2019 Apple Inc. All rights reserved.2 * Copyright (C) 2019-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 43 43 } 44 44 45 46 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 47 void RenderingUpdateScheduler::setPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond) 48 { 49 if (m_preferredFramesPerSecond == preferredFramesPerSecond) 50 return; 51 52 m_preferredFramesPerSecond = preferredFramesPerSecond; 53 DisplayRefreshMonitorManager::sharedManager().setPreferredFramesPerSecond(*this, m_preferredFramesPerSecond); 54 } 55 56 bool RenderingUpdateScheduler::scheduleAnimation(FramesPerSecond preferredFramesPerSecond) 57 { 58 #if !PLATFORM(IOS_FAMILY) 59 // PreferredFramesPerSecond can only be changed for iOS DisplayRefreshMonitor. 60 // The caller has to fall back to using the timer. 61 if (preferredFramesPerSecond != FullSpeedFramesPerSecond) 62 return false; 63 #endif 64 setPreferredFramesPerSecond(preferredFramesPerSecond); 65 return DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this); 66 } 67 #endif 68 69 void RenderingUpdateScheduler::adjustRenderingUpdateFrequency() 70 { 71 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 72 Seconds interval = m_page.preferredRenderingUpdateInterval(); 73 74 // PreferredFramesPerSecond is an integer and should be > 0. 75 if (interval <= 1_s) 76 setPreferredFramesPerSecond(preferredFramesPerSecond(interval)); 77 #endif 78 if (isScheduled()) { 79 clearScheduled(); 80 scheduleTimedRenderingUpdate(); 81 } 82 } 83 45 84 void RenderingUpdateScheduler::scheduleTimedRenderingUpdate() 46 85 { … … 56 95 tracePoint(ScheduleRenderingUpdate); 57 96 97 Seconds interval = m_page.preferredRenderingUpdateInterval(); 98 58 99 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 59 if (!DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this)) 100 // PreferredFramesPerSecond is an integer and should be > 0. 101 if (interval <= 1_s) 102 m_scheduled = scheduleAnimation(preferredFramesPerSecond(interval)); 60 103 #endif 61 startTimer(Seconds(1.0 / 60));62 104 63 m_scheduled = true; 105 if (!isScheduled()) 106 startTimer(interval); 64 107 } 65 108 … … 75 118 m_refreshTimer = makeUnique<Timer>(*this, &RenderingUpdateScheduler::displayRefreshFired); 76 119 m_refreshTimer->startOneShot(delay); 120 m_scheduled = true; 77 121 } 78 122 -
trunk/Source/WebCore/page/RenderingUpdateScheduler.h
r256512 r261113 1 1 /* 2 * Copyright (C) 2019 Apple Inc. All rights reserved.2 * Copyright (C) 2019-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #include "AnimationFrameRate.h" 28 29 #include "DisplayRefreshMonitorClient.h" 29 30 #include <wtf/Seconds.h> … … 47 48 48 49 RenderingUpdateScheduler(Page&); 50 51 void adjustRenderingUpdateFrequency(); 49 52 void scheduleTimedRenderingUpdate(); 50 53 void scheduleImmediateRenderingUpdate(); … … 57 60 private: 58 61 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 62 void setPreferredFramesPerSecond(FramesPerSecond); 63 bool scheduleAnimation(FramesPerSecond); 59 64 RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const final; 60 65 void displayRefreshFired() final; … … 70 75 bool m_scheduled { false }; 71 76 std::unique_ptr<Timer> m_refreshTimer; 77 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 78 FramesPerSecond m_preferredFramesPerSecond { FullSpeedFramesPerSecond }; 79 #endif 72 80 }; 73 81 -
trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h
r256512 r261113 28 28 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 29 29 30 #include "AnimationFrameRate.h" 30 31 #include "PlatformScreen.h" 31 32 #include <wtf/HashSet.h> … … 45 46 46 47 virtual void displayLinkFired() { } 48 49 virtual void setPreferredFramesPerSecond(FramesPerSecond) { } 47 50 48 51 // Return true if callback request was scheduled, false if it couldn't be -
trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp
r256512 r261113 43 43 } 44 44 45 DisplayRefreshMonitor* DisplayRefreshMonitorManager:: createMonitorForClient(DisplayRefreshMonitorClient& client)45 DisplayRefreshMonitor* DisplayRefreshMonitorManager::monitorForClient(DisplayRefreshMonitorClient& client) 46 46 { 47 if (!client.hasDisplayID()) 48 return nullptr; 49 47 50 PlatformDisplayID clientDisplayID = client.displayID(); 48 51 if (auto* existingMonitor = monitorForDisplayID(clientDisplayID)) { … … 55 58 return nullptr; 56 59 57 LOG(RequestAnimationFrame, "DisplayRefreshMonitorManager:: createMonitorForClient() - created monitor %p", monitor.get());60 LOG(RequestAnimationFrame, "DisplayRefreshMonitorManager::monitorForClient() - created monitor %p", monitor.get()); 58 61 monitor->addClient(client); 59 62 DisplayRefreshMonitor* result = monitor.get(); 60 63 m_monitors.append({ WTFMove(monitor) }); 61 64 return result; 62 }63 64 void DisplayRefreshMonitorManager::registerClient(DisplayRefreshMonitorClient& client)65 {66 if (!client.hasDisplayID())67 return;68 69 createMonitorForClient(client);70 65 } 71 66 … … 86 81 } 87 82 83 void DisplayRefreshMonitorManager::setPreferredFramesPerSecond(DisplayRefreshMonitorClient& client, FramesPerSecond preferredFramesPerSecond) 84 { 85 if (auto* monitor = monitorForClient(client)) 86 monitor->setPreferredFramesPerSecond(preferredFramesPerSecond); 87 } 88 88 89 bool DisplayRefreshMonitorManager::scheduleAnimation(DisplayRefreshMonitorClient& client) 89 90 { 90 if (!client.hasDisplayID()) 91 return false; 92 93 DisplayRefreshMonitor* monitor = createMonitorForClient(client); 94 if (!monitor) 95 return false; 96 97 client.setIsScheduled(true); 98 return monitor->requestRefreshCallback(); 91 if (auto* monitor = monitorForClient(client)) { 92 client.setIsScheduled(true); 93 return monitor->requestRefreshCallback(); 94 } 95 return false; 99 96 } 100 97 … … 117 114 unregisterClient(client); 118 115 client.setDisplayID(displayID); 119 registerClient(client);120 116 if (client.isScheduled()) 121 117 scheduleAnimation(client); -
trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.h
r256512 r261113 28 28 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 29 29 30 #include "AnimationFrameRate.h" 30 31 #include "DisplayRefreshMonitor.h" 31 32 #include "PlatformScreen.h" … … 38 39 class DisplayRefreshMonitorManager { 39 40 friend class NeverDestroyed<DisplayRefreshMonitorManager>; 41 friend class DisplayRefreshMonitor; 40 42 public: 41 43 WEBCORE_EXPORT static DisplayRefreshMonitorManager& sharedManager(); 42 43 void registerClient(DisplayRefreshMonitorClient&); 44 44 45 void unregisterClient(DisplayRefreshMonitorClient&); 45 46 47 void setPreferredFramesPerSecond(DisplayRefreshMonitorClient&, FramesPerSecond); 46 48 bool scheduleAnimation(DisplayRefreshMonitorClient&); 47 49 void windowScreenDidChange(PlatformDisplayID, DisplayRefreshMonitorClient&); 48 50 49 51 WEBCORE_EXPORT void displayWasUpdated(PlatformDisplayID); 50 52 51 53 private: 52 friend class DisplayRefreshMonitor; 54 DisplayRefreshMonitorManager() = default; 55 virtual ~DisplayRefreshMonitorManager(); 56 53 57 void displayDidRefresh(DisplayRefreshMonitor&); 54 55 DisplayRefreshMonitorManager() { }56 virtual ~DisplayRefreshMonitorManager();57 58 58 59 size_t findMonitorForDisplayID(PlatformDisplayID) const; 59 60 DisplayRefreshMonitor* monitorForDisplayID(PlatformDisplayID) const; 60 61 DisplayRefreshMonitor* createMonitorForClient(DisplayRefreshMonitorClient&); 61 DisplayRefreshMonitor* monitorForClient(DisplayRefreshMonitorClient&); 62 62 63 63 struct DisplayRefreshMonitorWrapper { -
trunk/Source/WebCore/platform/graphics/GraphicsLayerUpdater.cpp
r256512 r261113 36 36 : m_client(client) 37 37 { 38 DisplayRefreshMonitorManager::sharedManager().registerClient(*this);39 38 DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this); 40 39 DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this); -
trunk/Source/WebCore/platform/graphics/ios/DisplayRefreshMonitorIOS.mm
r256512 r261113 41 41 42 42 - (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor; 43 - (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond; 43 44 - (void)handleDisplayLink:(CADisplayLink *)sender; 44 45 - (void)invalidate; … … 64 65 ASSERT(!m_displayLink); // -invalidate should have been called already. 65 66 [super dealloc]; 67 } 68 69 - (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond 70 { 71 m_displayLink.preferredFramesPerSecond = preferredFramesPerSecond; 66 72 } 67 73 -
trunk/Source/WebCore/testing/Internals.cpp
r261056 r261113 1388 1388 } 1389 1389 1390 bool Internals::isRequestAnimationFrameThrottled() const1390 String Internals::requestAnimationFrameThrottlingReasons() const 1391 1391 { 1392 1392 auto* scriptedAnimationController = contextDocument()->scriptedAnimationController(); 1393 1393 if (!scriptedAnimationController) 1394 return false; 1395 return scriptedAnimationController->isThrottled(); 1394 return String(); 1395 1396 TextStream ts; 1397 ts << scriptedAnimationController->throttlingReasons(); 1398 return ts.release(); 1396 1399 } 1397 1400 -
trunk/Source/WebCore/testing/Internals.h
r261056 r261113 206 206 // DOMTimers throttling testing. 207 207 ExceptionOr<bool> isTimerThrottled(int timeoutId); 208 bool isRequestAnimationFrameThrottled() const;208 String requestAnimationFrameThrottlingReasons() const; 209 209 double requestAnimationFrameInterval() const; 210 210 bool scriptedAnimationsAreSuspended() const; -
trunk/Source/WebCore/testing/Internals.idl
r261056 r261113 558 558 [MayThrowException] boolean isTimerThrottled(long timerHandle); 559 559 560 boolean isRequestAnimationFrameThrottled();560 DOMString requestAnimationFrameThrottlingReasons(); 561 561 boolean areTimersThrottled(); 562 562 -
trunk/Source/WebKit/ChangeLog
r261112 r261113 1 2020-05-04 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 Throttling requestAnimationFrame should be controlled by RenderingUpdateScheduler 4 https://bugs.webkit.org/show_bug.cgi?id=204713 5 6 Reviewed by Simon Fraser. 7 8 Create an IPC message on the DrawingArea to send a message from the 9 WebProcess to the UIProcess to setPreferredFramesPerSecond of the 10 DisplayRefreshMonitor. 11 12 * UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.h: 13 * UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.messages.in: 14 * UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.mm: 15 (-[WKOneShotDisplayLinkHandler setPreferredFramesPerSecond:]): 16 (WebKit::RemoteLayerTreeDrawingAreaProxy::setPreferredFramesPerSecond): 17 Set the preferredFramesPerSecond of the CADisplayLink. 18 19 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h: 20 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm: 21 (WebKit::RemoteLayerTreeDisplayRefreshMonitor::setPreferredFramesPerSecond): 22 Forward the call to RemoteLayerTreeDrawingArea. 23 24 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h: 25 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm: 26 (WebKit::RemoteLayerTreeDrawingArea::setPreferredFramesPerSecond): 27 Send the IPC message from the WebProcess to the UIProcess. 28 1 29 2020-05-04 Alex Christensen <achristensen@webkit.org> 2 30 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.h
r261044 r261113 29 29 #include "RemoteLayerTreeHost.h" 30 30 #include "TransactionID.h" 31 #include <WebCore/AnimationFrameRate.h> 31 32 #include <WebCore/FloatPoint.h> 32 33 #include <WebCore/IntPoint.h> … … 98 99 99 100 // Message handlers 101 void setPreferredFramesPerSecond(WebCore::FramesPerSecond); 100 102 void willCommitLayerTree(TransactionID); 101 103 void commitLayerTree(const RemoteLayerTreeTransaction&, const RemoteScrollingCoordinatorTransaction&); -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.messages.in
r256512 r261113 22 22 23 23 messages -> RemoteLayerTreeDrawingAreaProxy : DrawingAreaProxy NotRefCounted { 24 void SetPreferredFramesPerSecond(unsigned preferredFramesPerSecond) 24 25 void WillCommitLayerTree(WebKit::TransactionID transactionID) 25 26 void CommitLayerTree(WebKit::RemoteLayerTreeTransaction layerTreeTransaction, WebKit::RemoteScrollingCoordinatorTransaction scrollingTreeTransaction) -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.mm
r261044 r261113 50 50 51 51 - (id)initWithDrawingAreaProxy:(WebKit::RemoteLayerTreeDrawingAreaProxy*)drawingAreaProxy; 52 - (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond; 52 53 - (void)displayLinkFired:(CADisplayLink *)sender; 53 54 - (void)invalidate; … … 77 78 } 78 79 80 - (void)setPreferredFramesPerSecond:(NSInteger)preferredFramesPerSecond 81 { 82 _displayLink.preferredFramesPerSecond = preferredFramesPerSecond; 83 } 84 79 85 - (void)displayLinkFired:(CADisplayLink *)sender 80 86 { … … 182 188 send(Messages::DrawingArea::UpdateGeometry(m_size, false /* flushSynchronously */, MachSendRight())); 183 189 m_isWaitingForDidUpdateGeometry = true; 190 } 191 192 void RemoteLayerTreeDrawingAreaProxy::setPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond) 193 { 194 #if PLATFORM(IOS_FAMILY) 195 [displayLinkHandler() setPreferredFramesPerSecond:preferredFramesPerSecond]; 196 #else 197 UNUSED_PARAM(preferredFramesPerSecond); 198 #endif 184 199 } 185 200 -
trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h
r256512 r261113 29 29 30 30 #include "RemoteLayerTreeDrawingArea.h" 31 #include <WebCore/AnimationFrameRate.h> 31 32 #include <WebCore/DisplayRefreshMonitor.h> 32 33 … … 42 43 virtual ~RemoteLayerTreeDisplayRefreshMonitor(); 43 44 45 void setPreferredFramesPerSecond(WebCore::FramesPerSecond) override; 44 46 bool requestRefreshCallback() override; 45 47 -
trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm
r256834 r261113 44 44 } 45 45 46 void RemoteLayerTreeDisplayRefreshMonitor::setPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond) 47 { 48 if (m_drawingArea) 49 m_drawingArea->setPreferredFramesPerSecond(preferredFramesPerSecond); 50 } 51 46 52 bool RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback() 47 53 { -
trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h
r261044 r261113 30 30 #include "GraphicsLayerCARemote.h" 31 31 #include "RemoteLayerTreeTransaction.h" 32 #include <WebCore/AnimationFrameRate.h> 32 33 #include <WebCore/GraphicsLayerClient.h> 33 34 #include <WebCore/Timer.h> … … 73 74 RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) override; 74 75 void willDestroyDisplayRefreshMonitor(WebCore::DisplayRefreshMonitor*); 76 void setPreferredFramesPerSecond(WebCore::FramesPerSecond); 75 77 76 78 bool shouldUseTiledBackingForFrameView(const WebCore::FrameView&) const override; -
trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm
r261044 r261113 127 127 } 128 128 129 void RemoteLayerTreeDrawingArea::setPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond) 130 { 131 send(Messages::RemoteLayerTreeDrawingAreaProxy::SetPreferredFramesPerSecond(preferredFramesPerSecond)); 132 } 133 129 134 void RemoteLayerTreeDrawingArea::updateRootLayers() 130 135 {
Note: See TracChangeset
for help on using the changeset viewer.