Sync requestAnimationFrame callback to CVDisplayLink on Mac
authorcmarrin@apple.com <cmarrin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Oct 2011 21:59:25 +0000 (21:59 +0000)
committercmarrin@apple.com <cmarrin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Oct 2011 21:59:25 +0000 (21:59 +0000)
commit488c3acffae4ec0bead82003a5f5c203a07a8a37
treee9a44d32d7d79e701faf78a0a0378ce4e85317e8
parente17b5dd530325264b7a9a6a5e36810aa658eb9b3
Sync requestAnimationFrame callback to CVDisplayLink on Mac
https://bugs.webkit.org/show_bug.cgi?id=68911

Reviewed by Simon Fraser.

Source/JavaScriptCore:

Add REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR for implementations
that use the DisplayRefreshMonitor logic.

* wtf/Platform.h:

Source/WebCore:

Test: fast/animation/request-animation-frame-iframe.html

Implement CVDisplayLink which checks to see if any scheduleAnimation requests
have come in. If so, remember the timestamp and do a callOnMainThread to fire
the callbacks. A DisplayRefreshMonitorManager is a singleton which has a list
of DisplayRefreshMonitors, one for each display. Each monitor has one or more
DisplayRefreshMonitorClients, which is a abstract virtual class implemented
by ScriptAnimationController. When an animation is scheduled, the
displayRefreshFired method is called on the client, which in turn calls the
requestAnimationFrame callbacks.

DisplayRefreshMonitor and therefore the CVDisplayLink it owns is discarded
when it no longer has any clients. This minimizes the number of concurrent
CVDisplayLink threads.

* WebCore.exp.in:
* WebCore.xcodeproj/project.pbxproj:
* dom/Document.cpp:
(WebCore::Document::windowScreenDidChange):
(WebCore::Document::webkitRequestAnimationFrame):
* dom/Document.h:
* dom/ScriptedAnimationController.cpp:
(WebCore::ScriptedAnimationController::ScriptedAnimationController):
(WebCore::ScriptedAnimationController::windowScreenDidChange):
(WebCore::ScriptedAnimationController::scheduleAnimation):
* dom/ScriptedAnimationController.h:
(WebCore::ScriptedAnimationController::displayRefreshFired):
* page/Page.cpp:
(WebCore::Page::Page):
(WebCore::Page::windowScreenDidChange):
* page/Page.h:
(WebCore::Page::displayID):
* platform/PlatformScreen.h:
* platform/graphics/DisplayRefreshMonitor.cpp: Added.
(WebCore::DisplayRefreshMonitorClient::DisplayRefreshMonitorClient):
(WebCore::DisplayRefreshMonitorClient::~DisplayRefreshMonitorClient):
(WebCore::DisplayRefreshMonitorClient::fireDisplayRefreshIfNeeded):
(WebCore::DisplayRefreshMonitor::DisplayRefreshMonitor):
(WebCore::DisplayRefreshMonitor::refreshDisplayOnMainThread):
(WebCore::DisplayRefreshMonitorManager::sharedManager):
(WebCore::DisplayRefreshMonitorManager::findMonitor):
(WebCore::DisplayRefreshMonitorManager::registerClient):
(WebCore::DisplayRefreshMonitorManager::unregisterClient):
(WebCore::DisplayRefreshMonitorManager::scheduleAnimation):
(WebCore::DisplayRefreshMonitorManager::windowScreenDidChange):
* platform/graphics/DisplayRefreshMonitor.h: Added.
(WebCore::DisplayRefreshMonitorClient::scheduleAnimation):
(WebCore::DisplayRefreshMonitor::hasClients):
(WebCore::DisplayRefreshMonitor::addClient):
(WebCore::DisplayRefreshMonitor::removeClient):
(WebCore::DisplayRefreshMonitor::displayID):
(WebCore::DisplayRefreshMonitorManager::DisplayRefreshMonitorManager):
* platform/graphics/mac/DisplayRefreshMonitorMac.cpp: Added.
(WebCore::DisplayRefreshMonitor::displayLinkCallback):
(WebCore::DisplayRefreshMonitor::~DisplayRefreshMonitor):
(WebCore::DisplayRefreshMonitor::scheduleAnimation):

Source/WebKit/mac:

Add windowDidChangeScreen function which listens for the window changing
screens and passes the new displayID along to WebCore::Page. It also sends
one on windowWillOrderOnScreen, so the Page has a fresh displayID after it's
created.

* WebView/WebView.mm:
(-[WebView addWindowObserversForWindow:]):
(-[WebView removeWindowObservers]):
(-[WebView _windowDidChangeScreen:]):
(-[WebView _windowWillOrderOnScreen:]):

Source/WebKit2:

Add windowDidChangeScreen function which listens for the window changing
screens and passes the new displayID along to WebCore::Page. It also sends
one on windowDidBecomeKey, so the Page has a fresh displayID after it's
created. Event is generated in the UIProcess and then sent over to the
WebProcess, which actually sends it to WebCore::Page.

* UIProcess/API/mac/WKView.mm:
(-[WKView addWindowObserversForWindow:]):
(-[WKView removeWindowObservers]):
(-[WKView _windowDidChangeScreen:]):
(-[WKView _windowDidBecomeKey:]):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::windowScreenDidChange):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::windowScreenDidChange):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

LayoutTests:

Test to make sure requestAnimationFrame events fire inside iframe

* fast/animation/request-animation-frame-iframe-expected.txt: Added.
* fast/animation/request-animation-frame-iframe.html: Added.
* fast/animation/script-tests/request-animation-frame-subframe.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@97405 268f45cc-cd09-0410-ab3c-d52691b4dbfc
28 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/animation/request-animation-frame-iframe-expected.txt [new file with mode: 0644]
LayoutTests/fast/animation/request-animation-frame-iframe.html [new file with mode: 0644]
LayoutTests/fast/animation/script-tests/request-animation-frame-subframe.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/wtf/Platform.h
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/ScriptedAnimationController.cpp
Source/WebCore/dom/ScriptedAnimationController.h
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/platform/PlatformScreen.h
Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/DisplayRefreshMonitor.h [new file with mode: 0644]
Source/WebCore/platform/graphics/mac/DisplayRefreshMonitorMac.cpp [new file with mode: 0644]
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/mac/WKView.mm
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in