requestAnimationFrame should execute before the next frame
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Mar 2019 00:52:57 +0000 (00:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Mar 2019 00:52:57 +0000 (00:52 +0000)
commitfae0bde5da2f651972338339c343af0dcf0bdb6e
tree556b76e843efb65d12d8188a9dea5508303e9697
parentf7362eab1f3c1abd8dad0a7e4615b43d3f6da6f6
requestAnimationFrame should execute before the next frame
https://bugs.webkit.org/show_bug.cgi?id=177484

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2019-03-07
Reviewed by Simon Fraser.

Source/WebCore:

This change fixes two issues with animation timing:

1. Calling the requestAnimationFrame callbacks would have happened when
   the DisplayLink fires. This may have happened even if the frame is
   missed and no display is committed.

2. Style changes and layout triggered by script could trigger painting
   at more than 60fps. CoreAnimation commits could happen at more than
   60fps, although WindowServer will throttle those, and only some will
   be shown on the screen.

This change introduces a new paint scheduling model where painting is
driven by a "RenderingUpdateScheduler", which only triggers paints once
per 16.7ms frame.

Code that previously scheduled a compositing layer flush now schedules a
"RenderingUpdate", and that update is driven by a DisplayRefreshMonitor
callback. When the render happens, we service requestAnimationFrame callbacks,
Web Animations and intersection observations per the "Update the rendering"
step of the HTML Event Loop specification
<https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>.

In the future, more rendering steps will be added to this code.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* accessibility/mac/AXObjectCacheMac.mm:
Fix layout tests by adding null check.

* animation/DocumentAnimationScheduler.cpp: Removed.
* animation/DocumentAnimationScheduler.h: Removed.
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::DocumentTimeline):
(WebCore::DocumentTimeline::updateThrottlingState):
(WebCore::DocumentTimeline::resumeAnimations):
(WebCore::DocumentTimeline::liveCurrentTime const):
(WebCore::DocumentTimeline::currentTime):
(WebCore::DocumentTimeline::animationTimingDidChange):
(WebCore::DocumentTimeline::scheduleAnimationResolution):
(WebCore::DocumentTimeline::unscheduleAnimationResolution):
(WebCore::DocumentTimeline::updateAnimationsAndSendEvents):
(WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents):
(WebCore::DocumentTimeline::scheduleNextTick):
(WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement):
Simplify this function by handling the case of no-animations separately.

(WebCore::DocumentTimeline::resolveAnimationsForElement):
Simplify the loop and delete hasPendingAcceleratedAnimations because it
is initialized to true and is not changed inside the loop.

(WebCore::DocumentTimeline::scheduleAnimationResolutionIfNeeded): Deleted.
(WebCore::DocumentTimeline::animationResolutionTimerFired): Deleted.
* animation/DocumentTimeline.h:
* dom/Document.cpp:
(WebCore::Document::resolveStyle):
There is no need to force update in resolveStyle(). notifyFlushRequired()
will be called eventually which will scheduleRenderingUpdate().

(WebCore::Document::prepareForDestruction):
(WebCore::Document::updateAnimationsAndSendEvents):
(WebCore::Document::serviceRequestAnimationFrameCallbacks):
(WebCore::Document::windowScreenDidChange):
(WebCore::Document::updateIntersectionObservations):
(WebCore::Document::scheduleForcedIntersectionObservationUpdate): Deleted.
(WebCore::Document::animationScheduler): Deleted.
* dom/Document.h:
(WebCore::Document::numberOfIntersectionObservers const):
* dom/ScriptedAnimationController.cpp:
(WebCore::ScriptedAnimationController::serviceRequestAnimationFrameCallbacks):
(WebCore::ScriptedAnimationController::scheduleAnimation):
(WebCore::ScriptedAnimationController::animationTimerFired):
(WebCore::ScriptedAnimationController::serviceScriptedAnimations): Deleted.
(WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire): Deleted.
* dom/ScriptedAnimationController.h:
* page/FrameView.cpp:
(WebCore::FrameView::viewportContentsChanged):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::observe):
* page/Page.cpp:
(WebCore::Page::Page):
(WebCore::Page::layoutIfNeeded):
(WebCore::Page::renderingUpdate):
(WebCore::Page::renderingUpdateScheduler):
(WebCore::Page::willDisplayPage): Deleted.
(WebCore::Page::addDocumentNeedingIntersectionObservationUpdate): Deleted.
(WebCore::Page::updateIntersectionObservations): Deleted.
(WebCore::Page::scheduleForcedIntersectionObservationUpdate): Deleted.
* page/Page.h:
* page/PageOverlayController.cpp:
(WebCore::PageOverlayController::didChangeViewExposedRect):
(WebCore::PageOverlayController::notifyFlushRequired):
* page/ResourceUsageData.h:
Include header files that become missing because of adding
RenderingUpdateScheduler.cpp.

* page/RenderingUpdateScheduler.cpp: Added.
(WebCore::RenderingUpdateScheduler::RenderingUpdateScheduler):
(WebCore::RenderingUpdateScheduler::scheduleRenderingUpdate):
(WebCore::RenderingUpdateScheduler::startTimer):
(WebCore::RenderingUpdateScheduler::clearTimer):
(WebCore::RenderingUpdateScheduler::windowScreenDidChange):
(WebCore::RenderingUpdateScheduler::createDisplayRefreshMonitor const):
(WebCore::RenderingUpdateScheduler::displayRefreshFired):
* page/RenderingUpdateScheduler.h: Added.
(WebCore::RenderingUpdateScheduler::create):
* page/ios/ContentChangeObserver.h:
Include header files that become missing because of adding
RenderingUpdateScheduler.cpp.

* page/mac/ServicesOverlayController.mm:
(WebCore::ServicesOverlayController::Highlight::notifyFlushRequired):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::scheduleLayerFlushNow):

Source/WebKit:

Replace the calls to Page::layoutIfNeeded() and willDisplayPage() by
a single call to Page::renderingUpdate(). This new function implements
"Update the rendering" step of the HTML Event Loop specification
<https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>.

* WebProcess/WebPage/AcceleratedDrawingArea.cpp:
(WebKit::AcceleratedDrawingArea::updateBackingStoreState):
* WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp:
(WebKit::LayerTreeHost::layerFlushTimerFired):
* WebProcess/WebPage/DrawingAreaImpl.cpp:
(WebKit::DrawingAreaImpl::display):
* WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::flushLayers):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::layoutIfNeeded):
(WebKit::WebPage::renderingUpdate):
(WebKit::WebPage::willDisplayPage): Deleted.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::flushLayers):

Source/WebKitLegacy/mac:

* WebView/WebView.mm:
(-[WebView _viewWillDrawInternal]):
Call Page::renderingUpdate() which implements  "Update the rendering"
step of the HTML Event Loop specification.

Source/WebKitLegacy/win:

* WebView.cpp:
(WebView::updateBackingStore):
(WebView::flushPendingGraphicsLayerChangesSoon):
(WebView::flushPendingGraphicsLayerChanges):
Call Page::renderingUpdate() which implements  "Update the rendering"
step of the HTML Event Loop specification.

Source/WTF:

Add trace points for the page RenderingUpdate.

* wtf/SystemTracing.h:

Tools:

Add trace points for the page RenderingUpdate.

* Tracing/SystemTracePoints.plist:

LayoutTests:

* TestExpectations:
There is a slight difference between the actual DRT and the expected DRT
due to animation timing change. But these two tests are not animating
correctly if they are opened in Safari with web animation turned on.

* animations/animation-multiple-callbacks-timestamp.html:
Fix variable names used by an error message.
* animations/no-style-recalc-during-accelerated-animation-expected.txt:
* animations/no-style-recalc-during-accelerated-animation.html:
One extra styleReclc was incurred due to the document styleRecalcTimer.
I think this timer is not needed anymore. I will look at removing it in
a separate patch.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242624 268f45cc-cd09-0410-ab3c-d52691b4dbfc
41 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/animations/animation-multiple-callbacks-timestamp.html
LayoutTests/animations/no-style-recalc-during-accelerated-animation-expected.txt
LayoutTests/animations/no-style-recalc-during-accelerated-animation.html
Source/WTF/ChangeLog
Source/WTF/wtf/SystemTracing.h
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/accessibility/mac/AXObjectCacheMac.mm
Source/WebCore/animation/DocumentAnimationScheduler.cpp [deleted file]
Source/WebCore/animation/DocumentTimeline.cpp
Source/WebCore/animation/DocumentTimeline.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/ScriptedAnimationController.cpp
Source/WebCore/dom/ScriptedAnimationController.h
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/IntersectionObserver.cpp
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/page/PageOverlayController.cpp
Source/WebCore/page/RenderingUpdateScheduler.cpp [new file with mode: 0644]
Source/WebCore/page/RenderingUpdateScheduler.h [moved from Source/WebCore/animation/DocumentAnimationScheduler.h with 58% similarity]
Source/WebCore/page/ios/ContentChangeObserver.h
Source/WebCore/page/mac/ServicesOverlayController.mm
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp
Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp
Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebView.mm
Source/WebKitLegacy/win/ChangeLog
Source/WebKitLegacy/win/WebView.cpp
Tools/ChangeLog
Tools/Tracing/SystemTracePoints.plist