Changeset 253299 in webkit
- Timestamp:
- Dec 9, 2019 1:12:17 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r253297 r253299 1 2019-12-09 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-throttling-outside-viewport-expected.txt: Added. 9 * fast/animation/request-animation-frame-throttling-outside-viewport.html: Added. 10 * fast/animation/request-animation-frame-throttling-lowPowerMode-expected.txt: 11 * fast/animation/request-animation-frame-throttling-lowPowerMode.html: 12 * fast/animation/resources/frame-with-animation-2.html: Added. 13 1 14 2019-12-09 youenn fablet <youenn@apple.com> 2 15 -
trunk/LayoutTests/fast/animation/request-animation-frame-throttling-lowPowerMode-expected.txt
r213169 r253299 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
r213169 r253299 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 7 8 let rAFHandle; 9 let i = 0; 10 function doWork() 11 { 12 i++; 13 rAFHandle = requestAnimationFrame(doWork); 14 } 8 window.jsTestIsAsync = true; 15 9 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> 10 if (window.internals) 11 internals.setLowPowerModeEnabled(true); 12 13 var start = null; 14 var farmesPerSecond = 0; 15 function doWork(timestamp) { 16 if (!start) 17 start = timestamp; 18 if (timestamp - start < 1000) { 19 ++farmesPerSecond; 20 window.requestAnimationFrame(doWork); 21 } 22 else { 23 // The LowPowerMode throttling interval = 30_ms. The frame rate ~= 33.3 fps. 24 shouldBeTrue("farmesPerSecond < 35"); 25 finishJSTest(); 26 } 27 } 28 window.requestAnimationFrame(doWork); 29 </script> 30 <script src="../../resources/js-test-post.js"></script> 35 31 </body> 36 32 </html> -
trunk/Source/WebCore/ChangeLog
r253296 r253299 1 2019-12-09 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 Test: fast/animation/request-animation-frame-throttling-outside-viewport.html 9 10 requestAnimationFrame is throttled by a timer although its callback are 11 serviced by the page RenderingUpdate. This led to excessive rAF firing 12 which makes it more than the preferred frame per seconds. 13 14 The solution is to have two throttling types: 15 16 1) Page throttling (or full throttling) which slows down all the steps of 17 RenderingUpdate for the main document and all the sub-documents. 18 2) Document throttling (or partial throttling) which only slows down the 19 rAF of a certain document. 20 21 * Headers.cmake: 22 * WebCore.xcodeproj/project.pbxproj: 23 24 * animation/DocumentTimeline.cpp: 25 (WebCore::DocumentTimeline::animationInterval const): 26 (WebCore::DocumentTimeline::updateThrottlingState): Deleted. 27 * animation/DocumentTimeline.h: 28 There is no need to have DocumentTimeline throttling. It is throttled 29 when the page RenderingUpdate is throttled. 30 31 * dom/Document.cpp: 32 (WebCore::Document::requestAnimationFrame): 33 (WebCore::Document::updateLastHandledUserGestureTimestamp): 34 LowPowerMode throttling is now handled by the page. So remove its handling 35 in the Document side. 36 37 * dom/ScriptedAnimationController.cpp: 38 (WebCore::ScriptedAnimationController::ScriptedAnimationController): 39 (WebCore::ScriptedAnimationController::page const): 40 (WebCore::ScriptedAnimationController::interval const): 41 (WebCore::ScriptedAnimationController::isThrottled const): 42 (WebCore::ScriptedAnimationController::registerCallback): 43 (WebCore::ScriptedAnimationController::cancelCallback): 44 (WebCore::ScriptedAnimationController::serviceRequestAnimationFrameCallbacks): 45 (WebCore::ScriptedAnimationController::scheduleAnimation): 46 (WebCore::throttlingReasonToString): Deleted. 47 (WebCore::throttlingReasonsToString): Deleted. 48 (WebCore::ScriptedAnimationController::addThrottlingReason): Deleted. 49 (WebCore::ScriptedAnimationController::removeThrottlingReason): Deleted. 50 (WebCore::ScriptedAnimationController::animationTimerFired): Deleted. 51 * dom/ScriptedAnimationController.h: 52 (WebCore::ScriptedAnimationController::addThrottlingReason): 53 (WebCore::ScriptedAnimationController::removeThrottlingReason): 54 Get rid of the rAF throttling timer. Service the rAF callback only when 55 the period from the current time stamp till the last service time stamp 56 is greater than the preferred rAF interval . 57 58 * page/FrameView.cpp: 59 (WebCore::FrameView::updateScriptedAnimationsAndTimersThrottlingState): 60 ThrottlingReason is now defined outside ScriptedAnimationController. 61 62 * page/Page.cpp: 63 (WebCore::Page::suspendScriptedAnimations): 64 (WebCore::Page::resumeScriptedAnimations): 65 Use forEachDocument(). 66 67 (WebCore::Page::preferredRenderingUpdateInterval const): 68 Calculate the preferred RenderingUpdate interval from the throttling 69 reasons. 70 71 (WebCore::Page::setIsVisuallyIdleInternal): 72 (WebCore::Page::handleLowModePowerChange): 73 Call adjustRenderingUpdateFrequency() when isLowPowerModeEnabled or 74 IsVisuallyIdle is toggled. 75 76 (WebCore::updateScriptedAnimationsThrottlingReason): Deleted. 77 * page/Page.h: 78 (WebCore::Page::isRenderingUpdateThrottled const): 79 80 * page/RenderingUpdateScheduler.cpp: 81 (WebCore::RenderingUpdateScheduler::adjustFramesPerSecond): 82 (WebCore::RenderingUpdateScheduler::adjustRenderingUpdateFrequency): 83 Change the preferredFramesPerSecond of the DisplayRefreshMonitor if the 84 throttling is not aggressive e.g. 10_s. Otherwise use the timer. 85 86 (WebCore::RenderingUpdateScheduler::scheduleTimedRenderingUpdate): 87 Call adjustFramesPerSecond() when DisplayRefreshMonitor is created. 88 89 (WebCore::RenderingUpdateScheduler::startTimer): 90 * page/RenderingUpdateScheduler.h: 91 92 * platform/graphics/AnimationFrameRate.h: Added. 93 (WebCore::preferredFrameInterval): 94 (WebCore::preferredFramesPerSecond): 95 * platform/graphics/DisplayRefreshMonitor.h: 96 (WebCore::DisplayRefreshMonitor::setPreferredFramesPerSecond): 97 98 * platform/graphics/DisplayRefreshMonitorManager.cpp: 99 (WebCore::DisplayRefreshMonitorManager::monitorForClient): 100 Rename createMonitorForClient() to monitorForClient() since it may return 101 a cached DisplayRefreshMonitor. 102 103 (WebCore::DisplayRefreshMonitorManager::setPreferredFramesPerSecond): 104 (WebCore::DisplayRefreshMonitorManager::scheduleAnimation): 105 (WebCore::DisplayRefreshMonitorManager::displayDidRefresh): 106 No need to call registerClient(). This function was just ensuring the 107 DisplayRefreshMonitor is created. scheduleAnimation() does the same thing. 108 109 (WebCore::DisplayRefreshMonitorManager::createMonitorForClient): Deleted. 110 (WebCore::DisplayRefreshMonitorManager::registerClient): Deleted. 111 * platform/graphics/DisplayRefreshMonitorManager.h: 112 (WebCore::DisplayRefreshMonitorManager::DisplayRefreshMonitorManager): Deleted. 113 114 * platform/graphics/GraphicsLayerUpdater.cpp: 115 (WebCore::GraphicsLayerUpdater::GraphicsLayerUpdater): 116 * platform/graphics/ios/DisplayRefreshMonitorIOS.mm: 117 (-[WebDisplayLinkHandler setPreferredFramesPerSecond:]): 118 Set the preferredFramesPerSecond of the CADisplayLink. 119 1 120 2019-12-09 Per Arne Vollan <pvollan@apple.com> 2 121 -
trunk/Source/WebCore/Headers.cmake
r253249 r253299 1012 1012 1013 1013 platform/graphics/ANGLEWebKitBridge.h 1014 platform/graphics/AnimationFrameRate.h 1014 1015 platform/graphics/AudioTrackPrivate.h 1015 1016 platform/graphics/BitmapImage.h -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r253258 r253299 2121 2121 72144334223EC91600F12FF7 /* SVGPropertyOwner.h in Headers */ = {isa = PBXBuildFile; fileRef = 55EE5360223B2A2100FBA944 /* SVGPropertyOwner.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2122 2122 72283F0E230B268C00F5D828 /* ImagePaintingOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 72C18A3F230B04B7006847C7 /* ImagePaintingOptions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2123 722A815D238FDAF000C00583 /* AnimationFrameRate.h in Headers */ = {isa = PBXBuildFile; fileRef = 722A815C238FD50500C00583 /* AnimationFrameRate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2123 2124 724ED3321A3A8B2300F5F13C /* JSEXTBlendMinMax.h in Headers */ = {isa = PBXBuildFile; fileRef = 724ED3301A3A8B2300F5F13C /* JSEXTBlendMinMax.h */; }; 2124 2125 724EE5501DC80D7F00A91FFB /* ActivityState.h in Headers */ = {isa = PBXBuildFile; fileRef = 724EE54E1DC7F25B00A91FFB /* ActivityState.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 9564 9565 721443452240C8BA00F12FF7 /* SVGAnimatedValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedValueProperty.h; sourceTree = "<group>"; }; 9565 9566 721443462240CAD200F12FF7 /* SVGValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGValueProperty.h; sourceTree = "<group>"; }; 9567 722A815C238FD50500C00583 /* AnimationFrameRate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimationFrameRate.h; sourceTree = "<group>"; }; 9566 9568 724ED3291A3A7E5400F5F13C /* EXTBlendMinMax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXTBlendMinMax.cpp; sourceTree = "<group>"; }; 9567 9569 724ED32A1A3A7E5400F5F13C /* EXTBlendMinMax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTBlendMinMax.h; sourceTree = "<group>"; }; … … 16748 16750 E4FB4B35239BEB10003C336A /* DisplayInlineContent.cpp */, 16749 16751 E451C6332394058E00993190 /* DisplayInlineContent.h */, 16752 112FB350239C23C40087054A /* DisplayInlineRect.h */, 16750 16753 6FB47E612277425A00C7BCB0 /* DisplayLineBox.h */, 16751 16754 6F77868523491AC6004D9636 /* DisplayPainter.cpp */, 16752 16755 6F77868723491AD7004D9636 /* DisplayPainter.h */, 16753 16756 6FD9CD52227E21C800E53957 /* DisplayRect.h */, 16754 112FB350239C23C40087054A /* DisplayInlineRect.h */,16755 16757 6FCE1A1822618AB3004F0343 /* DisplayRun.h */, 16756 16758 ); … … 24914 24916 490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */, 24915 24917 490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */, 24918 722A815C238FD50500C00583 /* AnimationFrameRate.h */, 24916 24919 BEF29EE91715DD0900C4B4C9 /* AudioTrackPrivate.h */, 24917 24920 A89943270B42338700D7C802 /* BitmapImage.cpp */, … … 28930 28933 71E2C42621C935280024F8C8 /* AnimationEffectPhase.h in Headers */, 28931 28934 319848011A1D817B00A13318 /* AnimationEvent.h in Headers */, 28935 722A815D238FDAF000C00583 /* AnimationFrameRate.h in Headers */, 28932 28936 49E912AD0EFAC906009D0CAF /* AnimationList.h in Headers */, 28933 28937 714C7C661FDAD2A100F2BEE1 /* AnimationPlaybackEvent.h in Headers */, … … 29607 29611 1199FA5B208E3C7F002358CC /* DisplayBox.h in Headers */, 29608 29612 E451C6342394058F00993190 /* DisplayInlineContent.h in Headers */, 29613 112FB352239C23C40087054A /* DisplayInlineRect.h in Headers */, 29614 6FB47E632277425A00C7BCB0 /* DisplayLineBox.h in Headers */, 29609 29615 0FE5FBD31C3DD51E0007A2CA /* DisplayList.h in Headers */, 29610 29616 0FE5FBD51C3DD51E0007A2CA /* DisplayListItems.h in Headers */, … … 30266 30272 6FE7CFA22177EEF2005B1573 /* InlineItem.h in Headers */, 30267 30273 BCE789161120D6080060ECE5 /* InlineIterator.h in Headers */, 30268 6FB47E632277425A00C7BCB0 /* DisplayLineBox.h in Headers */,30269 30274 6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */, 30270 30275 6F0CD695229ED32700C5994E /* InlineLineBuilder.h in Headers */, … … 31928 31933 436708C112D9CA4B00044234 /* RenderSVGBlock.h in Headers */, 31929 31934 436708C312D9CA4B00044234 /* RenderSVGContainer.h in Headers */, 31930 112FB352239C23C40087054A /* DisplayInlineRect.h in Headers */,31931 31935 2B365C841525119E0091D27B /* RenderSVGEllipse.h in Headers */, 31932 31936 43C092BC12D9E4EE00A989C3 /* RenderSVGForeignObject.h in Headers */, -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r253091 r253299 45 45 #include <JavaScriptCore/VM.h> 46 46 47 static const Seconds defaultAnimationInterval { 15_ms };48 static const Seconds throttledAnimationInterval { 30_ms };49 50 47 namespace WebCore { 51 48 … … 194 191 } 195 192 196 void DocumentTimeline::updateThrottlingState()197 {198 scheduleAnimationResolution();199 }200 201 193 Seconds DocumentTimeline::animationInterval() const 202 194 { 203 195 if (!m_document || !m_document->page()) 204 196 return Seconds::infinity(); 205 return m_document->page()-> isLowPowerModeEnabled() ? throttledAnimationInterval : defaultAnimationInterval;197 return m_document->page()->preferredRenderingUpdateInterval(); 206 198 } 207 199 -
trunk/Source/WebCore/animation/DocumentTimeline.h
r252527 r253299 74 74 void updateAnimationsAndSendEvents(DOMHighResTimeStamp timestamp); 75 75 76 void updateThrottlingState();77 76 WEBCORE_EXPORT Seconds animationInterval() const; 78 77 WEBCORE_EXPORT void suspendAnimations(); -
trunk/Source/WebCore/dom/Document.cpp
r253279 r253299 6492 6492 m_scriptedAnimationController->suspend(); 6493 6493 6494 if (page() && page()->isLowPowerModeEnabled())6495 m_scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::LowPowerMode);6496 6497 6494 if (!topOrigin().canAccess(securityOrigin()) && !hasHadUserInteraction()) 6498 m_scriptedAnimationController->addThrottlingReason( ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame);6495 m_scriptedAnimationController->addThrottlingReason(ThrottlingReason::NonInteractedCrossOriginFrame); 6499 6496 } 6500 6497 … … 6735 6732 if (static_cast<bool>(time) && m_scriptedAnimationController) { 6736 6733 // It's OK to always remove NonInteractedCrossOriginFrame even if this frame isn't cross-origin. 6737 m_scriptedAnimationController->removeThrottlingReason( ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame);6734 m_scriptedAnimationController->removeThrottlingReason(ThrottlingReason::NonInteractedCrossOriginFrame); 6738 6735 } 6739 6736 -
trunk/Source/WebCore/dom/ScriptedAnimationController.cpp
r250672 r253299 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All Rights Reserved. 3 * Copyright (C) 2019 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 32 #include "RequestAnimationFrameCallback.h" 41 33 #include "Settings.h" 42 #include <algorithm>43 #include <wtf/Ref.h>44 34 #include <wtf/SystemTracing.h> 45 #include <wtf/text/StringBuilder.h>46 47 // Allow a little more than 60fps to make sure we can at least hit that frame rate.48 static const Seconds fullSpeedAnimationInterval { 15_ms };49 // Allow a little more than 30fps to make sure we can at least hit that frame rate.50 static const Seconds halfSpeedThrottlingAnimationInterval { 30_ms };51 static const Seconds aggressiveThrottlingAnimationInterval { 10_s };52 53 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(page() && page()->isAlwaysOnLoggingAllowed(), PerformanceLogging, "%p - ScriptedAnimationController::" fmt, this, ##__VA_ARGS__)54 35 55 36 namespace WebCore { … … 57 38 ScriptedAnimationController::ScriptedAnimationController(Document& document) 58 39 : m_document(makeWeakPtr(document)) 59 , m_animationTimer(*this, &ScriptedAnimationController::animationTimerFired)60 40 { 61 41 } … … 66 46 { 67 47 return m_document && m_document->settings().requestAnimationFrameEnabled(); 48 } 49 50 Page* ScriptedAnimationController::page() const 51 { 52 return m_document ? m_document->page() : nullptr; 53 } 54 55 Seconds ScriptedAnimationController::interval() const 56 { 57 if (auto* page = this->page()) 58 return std::max(preferredFrameInterval(m_throttlingReasons), page->preferredRenderingUpdateInterval()); 59 return preferredFrameInterval(m_throttlingReasons); 68 60 } 69 61 … … 84 76 } 85 77 86 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && !RELEASE_LOG_DISABLED87 88 static const char* throttlingReasonToString(ScriptedAnimationController::ThrottlingReason reason)89 {90 switch (reason) {91 case ScriptedAnimationController::ThrottlingReason::VisuallyIdle:92 return "VisuallyIdle";93 case ScriptedAnimationController::ThrottlingReason::OutsideViewport:94 return "OutsideViewport";95 case ScriptedAnimationController::ThrottlingReason::LowPowerMode:96 return "LowPowerMode";97 case ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame:98 return "NonInteractiveCrossOriginFrame";99 }100 }101 102 static String throttlingReasonsToString(OptionSet<ScriptedAnimationController::ThrottlingReason> reasons)103 {104 if (reasons.isEmpty())105 return "[Unthrottled]"_s;106 107 StringBuilder builder;108 for (auto reason : reasons) {109 if (!builder.isEmpty())110 builder.append('|');111 builder.append(throttlingReasonToString(reason));112 }113 return builder.toString();114 }115 116 #endif117 118 void ScriptedAnimationController::addThrottlingReason(ThrottlingReason reason)119 {120 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)121 if (m_throttlingReasons.contains(reason))122 return;123 124 m_throttlingReasons.add(reason);125 126 RELEASE_LOG_IF_ALLOWED("addThrottlingReason(%s) -> %s", throttlingReasonToString(reason), throttlingReasonsToString(m_throttlingReasons).utf8().data());127 128 if (m_animationTimer.isActive()) {129 m_animationTimer.stop();130 scheduleAnimation();131 }132 #else133 UNUSED_PARAM(reason);134 #endif135 }136 137 void ScriptedAnimationController::removeThrottlingReason(ThrottlingReason reason)138 {139 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)140 if (!m_throttlingReasons.contains(reason))141 return;142 143 m_throttlingReasons.remove(reason);144 145 RELEASE_LOG_IF_ALLOWED("removeThrottlingReason(%s) -> %s", throttlingReasonToString(reason), throttlingReasonsToString(m_throttlingReasons).utf8().data());146 147 if (m_animationTimer.isActive()) {148 m_animationTimer.stop();149 scheduleAnimation();150 }151 #else152 UNUSED_PARAM(reason);153 #endif154 }155 156 78 bool ScriptedAnimationController::isThrottled() const 157 79 { 158 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 159 return !m_throttlingReasons.isEmpty(); 160 #else 80 auto* page = this->page(); 81 if (!m_throttlingReasons.isEmpty() || (page && page->isRenderingUpdateThrottled())) { 82 ASSERT(interval() > FullSpeedAnimationInterval); 83 return true; 84 } 161 85 return false; 162 #endif163 86 } 164 87 165 88 ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(Ref<RequestAnimationFrameCallback>&& callback) 166 89 { 167 ScriptedAnimationController::CallbackId id = ++m_nextCallbackId;90 CallbackId callbackId = ++m_nextCallbackId; 168 91 callback->m_firedOrCancelled = false; 169 callback->m_id = id;92 callback->m_id = callbackId; 170 93 m_callbacks.append(WTFMove(callback)); 171 94 172 95 if (m_document) 173 InspectorInstrumentation::didRequestAnimationFrame(*m_document, id);96 InspectorInstrumentation::didRequestAnimationFrame(*m_document, callbackId); 174 97 175 98 if (!m_suspendCount) 176 99 scheduleAnimation(); 177 return id;100 return callbackId; 178 101 } 179 102 180 void ScriptedAnimationController::cancelCallback(CallbackId id)103 void ScriptedAnimationController::cancelCallback(CallbackId callbackId) 181 104 { 182 for (size_t i = 0; i < m_callbacks.size(); ++i) { 183 if (m_callbacks[i]->m_id == id) { 184 m_callbacks[i]->m_firedOrCancelled = true; 185 InspectorInstrumentation::didCancelAnimationFrame(*m_document, id); 186 m_callbacks.remove(i); 187 return; 188 } 189 } 105 bool cancelled = m_callbacks.removeFirstMatching([&](auto& callback) { 106 if (callback->m_id != callbackId) 107 return false; 108 callback->m_firedOrCancelled = true; 109 return true; 110 }); 111 112 if (cancelled && m_document) 113 InspectorInstrumentation::didCancelAnimationFrame(*m_document, callbackId); 190 114 } 191 115 … … 195 119 return; 196 120 121 bool isThrottlingRelativeToPage = page() && page()->preferredRenderingUpdateInterval() < preferredFrameInterval(m_throttlingReasons); 122 bool canSkipFrame = Seconds(timestamp - m_lastAnimationFrameTimestamp) < preferredFrameInterval(m_throttlingReasons); 123 if (isThrottlingRelativeToPage && canSkipFrame) { 124 scheduleAnimation(); 125 return; 126 } 127 197 128 TraceScope tracingScope(RAFCallbackStart, RAFCallbackEnd); 198 129 … … 224 155 }); 225 156 157 m_lastAnimationFrameTimestamp = timestamp; 158 226 159 if (m_callbacks.size()) 227 160 scheduleAnimation(); 228 }229 230 Seconds ScriptedAnimationController::interval() const231 {232 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)233 if (m_throttlingReasons.contains(ThrottlingReason::VisuallyIdle) || m_throttlingReasons.contains(ThrottlingReason::OutsideViewport))234 return aggressiveThrottlingAnimationInterval;235 236 if (m_throttlingReasons.contains(ThrottlingReason::LowPowerMode))237 return halfSpeedThrottlingAnimationInterval;238 239 if (m_throttlingReasons.contains(ThrottlingReason::NonInteractedCrossOriginFrame))240 return halfSpeedThrottlingAnimationInterval;241 242 ASSERT(m_throttlingReasons.isEmpty());243 #endif244 return fullSpeedAnimationInterval;245 }246 247 Page* ScriptedAnimationController::page() const248 {249 return m_document ? m_document->page() : nullptr;250 161 } 251 162 … … 255 166 return; 256 167 257 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 258 if (!m_isUsingTimer && !isThrottled()) { 259 if (auto* page = this->page()) { 260 page->renderingUpdateScheduler().scheduleTimedRenderingUpdate(); 261 return; 262 } 263 264 m_isUsingTimer = true; 265 } 266 #endif 267 if (m_animationTimer.isActive()) 268 return; 269 270 Seconds animationInterval = interval(); 271 Seconds scheduleDelay = std::max(animationInterval - Seconds(m_document->domWindow()->nowTimestamp() - m_lastAnimationFrameTimestamp), 0_s); 272 273 if (isThrottled()) { 274 // FIXME: not ideal to snapshot time both in now() and nowTimestamp(), the latter of which also has reduced resolution. 275 MonotonicTime now = MonotonicTime::now(); 276 277 MonotonicTime fireTime = now + scheduleDelay; 278 Seconds alignmentInterval = 10_ms; 279 // Snap to the nearest alignmentInterval. 280 Seconds alignment = (fireTime + alignmentInterval / 2) % alignmentInterval; 281 MonotonicTime alignedFireTime = fireTime - alignment; 282 scheduleDelay = alignedFireTime - now; 283 } 284 285 m_animationTimer.startOneShot(scheduleDelay); 286 } 287 288 void ScriptedAnimationController::animationTimerFired() 289 { 290 m_lastAnimationFrameTimestamp = m_document->domWindow()->nowTimestamp(); 291 serviceRequestAnimationFrameCallbacks(m_lastAnimationFrameTimestamp); 168 if (auto* page = this->page()) 169 page->renderingUpdateScheduler().scheduleTimedRenderingUpdate(); 292 170 } 293 171 -
trunk/Source/WebCore/dom/ScriptedAnimationController.h
r244234 r253299 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All Rights Reserved. 3 * Copyright (C) 2019 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 29 #include "AnimationFrameRate.h" 28 30 #include "DOMHighResTimeStamp.h" 29 #include "Timer.h"30 31 #include <wtf/OptionSet.h> 31 32 #include <wtf/RefCounted.h> 32 33 #include <wtf/RefPtr.h> 33 34 #include <wtf/Vector.h> 35 #include <wtf/WeakPtr.h> 34 36 35 37 namespace WebCore { … … 49 51 void clearDocumentPointer() { m_document = nullptr; } 50 52 bool requestAnimationFrameEnabled() const; 53 WEBCORE_EXPORT Seconds interval() const; 51 54 52 55 typedef int CallbackId; … … 58 61 void suspend(); 59 62 void resume(); 60 61 enum class ThrottlingReason { 62 VisuallyIdle = 1 << 0, 63 OutsideViewport = 1 << 1, 64 LowPowerMode = 1 << 2, 65 NonInteractedCrossOriginFrame = 1 << 3, 66 }; 67 void addThrottlingReason(ThrottlingReason); 68 void removeThrottlingReason(ThrottlingReason); 69 63 64 void addThrottlingReason(ThrottlingReason reason) { m_throttlingReasons.add(reason); } 65 void removeThrottlingReason(ThrottlingReason reason) { m_throttlingReasons.remove(reason); } 70 66 WEBCORE_EXPORT bool isThrottled() const; 71 WEBCORE_EXPORT Seconds interval() const;72 67 73 68 private: 74 69 ScriptedAnimationController(Document&); 75 70 71 Page* page() const; 76 72 void scheduleAnimation(); 77 void animationTimerFired();78 73 79 Page* page() const; 80 81 typedef Vector<RefPtr<RequestAnimationFrameCallback>> CallbackList; 74 using CallbackList = Vector<RefPtr<RequestAnimationFrameCallback>>; 82 75 CallbackList m_callbacks; 76 DOMHighResTimeStamp m_lastAnimationFrameTimestamp { 0 }; 83 77 84 78 WeakPtr<Document> m_document; … … 86 80 int m_suspendCount { 0 }; 87 81 88 Timer m_animationTimer;89 double m_lastAnimationFrameTimestamp { 0 };90 91 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)92 82 OptionSet<ThrottlingReason> m_throttlingReasons; 93 bool m_isUsingTimer { false };94 #endif95 83 }; 96 84 -
trunk/Source/WebCore/page/FrameView.cpp
r252935 r253299 2525 2525 if (auto* scriptedAnimationController = document->scriptedAnimationController()) { 2526 2526 if (shouldThrottle) 2527 scriptedAnimationController->addThrottlingReason( ScriptedAnimationController::ThrottlingReason::OutsideViewport);2527 scriptedAnimationController->addThrottlingReason(ThrottlingReason::OutsideViewport); 2528 2528 else 2529 scriptedAnimationController->removeThrottlingReason( ScriptedAnimationController::ThrottlingReason::OutsideViewport);2529 scriptedAnimationController->removeThrottlingReason(ThrottlingReason::OutsideViewport); 2530 2530 } 2531 2531 -
trunk/Source/WebCore/page/Page.cpp
r253231 r253299 23 23 #include "ActivityStateChangeObserver.h" 24 24 #include "AlternativeTextClient.h" 25 #include "AnimationFrameRate.h" 25 26 #include "ApplicationCacheStorage.h" 26 27 #include "ApplicationStateChangeListener.h" … … 1370 1371 { 1371 1372 m_scriptedAnimationsSuspended = true; 1372 for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) { 1373 if (frame->document()) 1374 frame->document()->suspendScriptedAnimationControllerCallbacks(); 1375 } 1373 forEachDocument([&] (Document& document) { 1374 document.suspendScriptedAnimationControllerCallbacks(); 1375 }); 1376 1376 } 1377 1377 … … 1379 1379 { 1380 1380 m_scriptedAnimationsSuspended = false; 1381 for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) { 1382 if (frame->document()) 1383 frame->document()->resumeScriptedAnimationControllerCallbacks(); 1384 } 1385 } 1386 1387 enum class ThrottlingReasonOperation { Add, Remove }; 1388 static void updateScriptedAnimationsThrottlingReason(Page& page, ThrottlingReasonOperation operation, ScriptedAnimationController::ThrottlingReason reason) 1389 { 1390 for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) { 1391 auto* document = frame->document(); 1392 if (!document) 1393 continue; 1394 auto* scriptedAnimationController = document->scriptedAnimationController(); 1395 if (!scriptedAnimationController) 1396 continue; 1397 1398 if (operation == ThrottlingReasonOperation::Add) 1399 scriptedAnimationController->addThrottlingReason(reason); 1400 else 1401 scriptedAnimationController->removeThrottlingReason(reason); 1402 } 1381 forEachDocument([&] (Document& document) { 1382 document.resumeScriptedAnimationControllerCallbacks(); 1383 }); 1384 } 1385 1386 Seconds Page::preferredRenderingUpdateInterval() const 1387 { 1388 return preferredFrameInterval(m_throttlingReasons); 1403 1389 } 1404 1390 1405 1391 void Page::setIsVisuallyIdleInternal(bool isVisuallyIdle) 1406 1392 { 1407 updateScriptedAnimationsThrottlingReason(*this, isVisuallyIdle ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::VisuallyIdle); 1393 if (isVisuallyIdle == m_throttlingReasons.contains(ThrottlingReason::VisuallyIdle)) 1394 return; 1395 1396 m_throttlingReasons = m_throttlingReasons ^ ThrottlingReason::VisuallyIdle; 1397 renderingUpdateScheduler().adjustRenderingUpdateFrequency(); 1408 1398 } 1409 1399 1410 1400 void Page::handleLowModePowerChange(bool isLowPowerModeEnabled) 1411 1401 { 1412 updateScriptedAnimationsThrottlingReason(*this, isLowPowerModeEnabled ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::LowPowerMode);1413 if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {1414 forEachDocument([&] (Document& document) { 1415 if (auto timeline = document.existingTimeline())1416 timeline->updateThrottlingState();1417 }); 1418 } else1402 if (isLowPowerModeEnabled == m_throttlingReasons.contains(ThrottlingReason::LowPowerMode)) 1403 return; 1404 1405 m_throttlingReasons = m_throttlingReasons ^ ThrottlingReason::LowPowerMode; 1406 renderingUpdateScheduler().adjustRenderingUpdateFrequency(); 1407 1408 if (!RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) 1419 1409 mainFrame().animation().updateThrottlingState(); 1410 1420 1411 updateDOMTimerAlignmentInterval(); 1421 1412 } -
trunk/Source/WebCore/page/Page.h
r253279 r253299 22 22 23 23 #include "ActivityState.h" 24 #include "AnimationFrameRate.h" 24 25 #include "DisabledAdaptations.h" 25 26 #include "Document.h" … … 274 275 275 276 RenderingUpdateScheduler& renderingUpdateScheduler(); 277 bool isRenderingUpdateThrottled() const { return !m_throttlingReasons.isEmpty(); } 276 278 277 279 ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient.get(); } … … 714 716 WEBCORE_EXPORT void setLowPowerModeEnabledOverrideForTesting(Optional<bool>); 715 717 718 Seconds preferredRenderingUpdateInterval() const; 719 716 720 WEBCORE_EXPORT void applicationWillResignActive(); 717 721 WEBCORE_EXPORT void applicationDidEnterBackground(); … … 1009 1013 bool m_mediaBufferingIsSuspended { false }; 1010 1014 bool m_inUpdateRendering { false }; 1015 OptionSet<ThrottlingReason> m_throttlingReasons; 1011 1016 }; 1012 1017 -
trunk/Source/WebCore/page/RenderingUpdateScheduler.cpp
r248846 r253299 43 43 } 44 44 45 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && PLATFORM(IOS_FAMILY) 46 void RenderingUpdateScheduler::adjustFramesPerSecond() 47 { 48 Seconds interval = m_page.preferredRenderingUpdateInterval(); 49 // CADisplayLink.preferredFramesPerSecond is an integer. So a fraction PreferredFramesPerSecond can't be set. 50 if (interval < 1_s) 51 DisplayRefreshMonitorManager::sharedManager().setPreferredFramesPerSecond(*this, preferredFramesPerSecond(interval)); 52 } 53 #endif 54 55 void RenderingUpdateScheduler::adjustRenderingUpdateFrequency() 56 { 57 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && PLATFORM(IOS_FAMILY) 58 adjustFramesPerSecond(); 59 #endif 60 if (isScheduled()) { 61 clearScheduled(); 62 scheduleTimedRenderingUpdate(); 63 } 64 } 65 45 66 void RenderingUpdateScheduler::scheduleTimedRenderingUpdate() 46 67 { … … 56 77 tracePoint(ScheduleRenderingUpdate); 57 78 79 Seconds interval = m_page.preferredRenderingUpdateInterval(); 80 58 81 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 59 if (!DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this)) 82 // CADisplayLink.preferredFramesPerSecond is an integer. Fall back to timer if the PreferredFramesPerSecond is a fraction. 83 if (interval < 1_s) { 84 #if PLATFORM(IOS_FAMILY) 85 if (!m_isMonitorCreated) { 86 adjustFramesPerSecond(); 87 m_isMonitorCreated = true; 88 } 89 #else 90 if (interval == FullSpeedAnimationInterval) 60 91 #endif 61 startTimer(Seconds(1.0 / 60)); 92 m_scheduled = DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this); 93 } 94 #endif 62 95 63 m_scheduled = true; 96 if (!isScheduled()) 97 startTimer(interval); 64 98 } 65 99 … … 75 109 m_refreshTimer = makeUnique<Timer>(*this, &RenderingUpdateScheduler::displayRefreshFired); 76 110 m_refreshTimer->startOneShot(delay); 111 m_scheduled = true; 77 112 } 78 113 -
trunk/Source/WebCore/page/RenderingUpdateScheduler.h
r248846 r253299 47 47 48 48 RenderingUpdateScheduler(Page&); 49 50 void adjustRenderingUpdateFrequency(); 49 51 void scheduleTimedRenderingUpdate(); 50 52 void scheduleImmediateRenderingUpdate(); … … 53 55 private: 54 56 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 57 #if PLATFORM(IOS_FAMILY) 58 void adjustFramesPerSecond(); 59 #endif 55 60 RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const final; 56 61 void windowScreenDidChange(PlatformDisplayID); … … 65 70 66 71 Page& m_page; 72 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && PLATFORM(IOS_FAMILY) 73 bool m_isMonitorCreated; 74 #endif 67 75 bool m_scheduled { false }; 68 76 std::unique_ptr<Timer> m_refreshTimer; -
trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h
r247273 r253299 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
r247534 r253299 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
r247534 r253299 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
r202399 r253299 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
r237266 r253299 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/WebKit/ChangeLog
r253297 r253299 1 2019-12-09 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 15 * UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.mm: 16 (-[WKOneShotDisplayLinkHandler setPreferredFramesPerSecond:]): 17 (WebKit::RemoteLayerTreeDrawingAreaProxy::setPreferredFramesPerSecond): 18 Set the preferredFramesPerSecond of the CADisplayLink. 19 20 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.h: 21 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDisplayRefreshMonitor.mm: 22 (WebKit::RemoteLayerTreeDisplayRefreshMonitor::setPreferredFramesPerSecond): 23 Delegate the call to RemoteLayerTreeDrawingArea. 24 25 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h: 26 * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm: 27 (WebKit::RemoteLayerTreeDrawingArea::setPreferredFramesPerSecond): 28 Send the IPC message from the WebProcess to the UIProcess. 29 1 30 2019-12-09 youenn fablet <youenn@apple.com> 2 31 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.h
r249093 r253299 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
r252655 r253299 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
r253157 r253299 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
r250165 r253299 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
r250165 r253299 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
r249961 r253299 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> … … 74 75 RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) override; 75 76 void willDestroyDisplayRefreshMonitor(WebCore::DisplayRefreshMonitor*); 77 void setPreferredFramesPerSecond(WebCore::FramesPerSecond); 76 78 77 79 bool shouldUseTiledBackingForFrameView(const WebCore::FrameView&) override; -
trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm
r250165 r253299 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.