Changeset 94908 in webkit


Ignore:
Timestamp:
Sep 10, 2011 7:21:01 AM (13 years ago)
Author:
cmarrin@apple.com
Message:

requestAnimationFrame doesn't throttle on Mac
https://bugs.webkit.org/show_bug.cgi?id=67171

Reviewed by Simon Fraser.

Source/JavaScriptCore:

Added WTF_USE_REQUEST_ANIMATION_FRAME_TIMER to allow any platform to run
requestAnimationFrame callbacks on a Timer defined in ScriptedAnimationController.
Currently only enabled for PLATFORM(MAC)

  • wtf/Platform.h:

Source/WebCore:

Changed requestAnimationFrame to use a Timer in ScriptedAnimationController
on Mac, rather than runLoopObservers. The Timer is throttled to fire no
faster than every 15ms. It is behind a WTF_USE_REQUEST_ANIMATION_FRAME_TIMER
flag and can be used by any implementation, but currently it is only enabled
by PLATFORM(MAC).

  • dom/ScriptedAnimationController.cpp:

(WebCore::ScriptedAnimationController::ScriptedAnimationController):
(WebCore::ScriptedAnimationController::resume):
(WebCore::ScriptedAnimationController::registerCallback):
(WebCore::ScriptedAnimationController::serviceScriptedAnimations):
(WebCore::ScriptedAnimationController::scheduleAnimation):
(WebCore::ScriptedAnimationController::animationTimerFired):

  • dom/ScriptedAnimationController.h:
  • loader/EmptyClients.h:
  • page/Chrome.cpp:

(WebCore::Chrome::scheduleAnimation):

  • page/ChromeClient.h:

Source/WebKit/mac:

Removed runLoopObserver for requestAnimationFrame. It's now
done by a Timer in ScriptedAnimationController in WebCore.

  • WebCoreSupport/WebChromeClient.h:
  • WebCoreSupport/WebChromeClient.mm:
  • WebView/WebView.mm:

(-[WebView _close]):

  • WebView/WebViewData.h:
  • WebView/WebViewInternal.h:

Source/WebKit2:

Removed runLoopObserver for requestAnimationFrame. It's now
done by a Timer in ScriptedAnimationController in WebCore.

  • WebProcess/WebCoreSupport/WebChromeClient.cpp:
  • WebProcess/WebCoreSupport/WebChromeClient.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::~WebPage):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/mac/WebPageMac.mm:
Location:
trunk/Source
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r94890 r94908  
     12011-09-09  Chris Marrin  <cmarrin@apple.com>
     2
     3        requestAnimationFrame doesn't throttle on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=67171
     5
     6        Reviewed by Simon Fraser.
     7
     8        Added WTF_USE_REQUEST_ANIMATION_FRAME_TIMER to allow any platform to run
     9        requestAnimationFrame callbacks on a Timer defined in ScriptedAnimationController.
     10        Currently only enabled for PLATFORM(MAC)
     11
     12        * wtf/Platform.h:
     13
    1142011-09-09  Geoffrey Garen  <ggaren@apple.com>
    215
  • trunk/Source/JavaScriptCore/wtf/Platform.h

    r94890 r94908  
    11601160#endif
    11611161
     1162#if PLATFORM(MAC)
     1163#define WTF_USE_REQUEST_ANIMATION_FRAME_TIMER 1
     1164#endif
     1165
    11621166#endif /* WTF_Platform_h */
  • trunk/Source/WebCore/ChangeLog

    r94906 r94908  
     12011-09-09  Chris Marrin  <cmarrin@apple.com>
     2
     3        requestAnimationFrame doesn't throttle on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=67171
     5
     6        Reviewed by Simon Fraser.
     7
     8        Changed requestAnimationFrame to use a Timer in ScriptedAnimationController
     9        on Mac, rather than runLoopObservers. The Timer is throttled to fire no
     10        faster than every 15ms. It is behind a WTF_USE_REQUEST_ANIMATION_FRAME_TIMER
     11        flag and can be used by any implementation, but currently it is only enabled
     12        by PLATFORM(MAC).
     13
     14        * dom/ScriptedAnimationController.cpp:
     15        (WebCore::ScriptedAnimationController::ScriptedAnimationController):
     16        (WebCore::ScriptedAnimationController::resume):
     17        (WebCore::ScriptedAnimationController::registerCallback):
     18        (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
     19        (WebCore::ScriptedAnimationController::scheduleAnimation):
     20        (WebCore::ScriptedAnimationController::animationTimerFired):
     21        * dom/ScriptedAnimationController.h:
     22        * loader/EmptyClients.h:
     23        * page/Chrome.cpp:
     24        (WebCore::Chrome::scheduleAnimation):
     25        * page/ChromeClient.h:
     26
    1272011-09-10  Jarred Nicholls  <jarred@sencha.com>
    228
  • trunk/Source/WebCore/dom/ScriptedAnimationController.cpp

    r78648 r94908  
    3434#include "RequestAnimationFrameCallback.h"
    3535
     36#if USE(REQUEST_ANIMATION_FRAME_TIMER)
     37#include <algorithm>
     38#include <wtf/CurrentTime.h>
     39
     40using namespace std;
     41
     42// Allow a little more than 60fps to make sure we can at least hit that frame rate.
     43#define MinimumAnimationInterval 0.015
     44#endif
     45
    3646namespace WebCore {
    3747
     
    4050    , m_nextCallbackId(0)
    4151    , m_suspendCount(0)
     52#if USE(REQUEST_ANIMATION_FRAME_TIMER)
     53    , m_animationTimer(this, &ScriptedAnimationController::animationTimerFired)
     54    , m_lastAnimationFrameTime(0)
     55#endif
    4256{
    4357}
     
    5266    --m_suspendCount;
    5367    if (!m_suspendCount && m_callbacks.size())
    54         if (FrameView* fv = m_document->view())
    55             fv->scheduleAnimation();
     68        scheduleAnimation();
    5669}
    5770
     
    6477    m_callbacks.append(callback);
    6578    if (!m_suspendCount)
    66         if (FrameView* view = m_document->view())
    67             view->scheduleAnimation();
     79        scheduleAnimation();
    6880    return id;
    6981}
     
    125137
    126138    if (m_callbacks.size())
    127         if (FrameView* view = m_document->view())
    128             view->scheduleAnimation();
     139        scheduleAnimation();
    129140}
     141   
     142void ScriptedAnimationController::scheduleAnimation()
     143{
     144#if USE(REQUEST_ANIMATION_FRAME_TIMER)
     145    double scheduleDelay = max<double>(MinimumAnimationInterval - (currentTime() - m_lastAnimationFrameTime), 0);
     146    m_animationTimer.startOneShot(scheduleDelay);
     147#else
     148    if (FrameView* frameView = m_document->view())
     149        frameView->scheduleAnimation();
     150#endif
     151}
     152
     153#if USE(REQUEST_ANIMATION_FRAME_TIMER)
     154void ScriptedAnimationController::animationTimerFired(Timer<ScriptedAnimationController>*)
     155{
     156    m_lastAnimationFrameTime = currentTime();
     157    serviceScriptedAnimations(m_lastAnimationFrameTime);
     158}
     159#endif
    130160
    131161}
  • trunk/Source/WebCore/dom/ScriptedAnimationController.h

    r78852 r94908  
    2929#if ENABLE(REQUEST_ANIMATION_FRAME)
    3030#include "DOMTimeStamp.h"
     31#if USE(REQUEST_ANIMATION_FRAME_TIMER)
     32#include "Timer.h"
     33#endif
    3134#include <wtf/Noncopyable.h>
    3235#include <wtf/PassOwnPtr.h>
     
    5962private:
    6063    explicit ScriptedAnimationController(Document*);
     64   
    6165    typedef Vector<RefPtr<RequestAnimationFrameCallback> > CallbackList;
    6266    CallbackList m_callbacks;
     
    6569    CallbackId m_nextCallbackId;
    6670    int m_suspendCount;
     71
     72    void scheduleAnimation();
     73
     74#if USE(REQUEST_ANIMATION_FRAME_TIMER)
     75    void animationTimerFired(Timer<ScriptedAnimationController>*);
     76    Timer<ScriptedAnimationController> m_animationTimer;
     77    double m_lastAnimationFrameTime;
     78#endif
    6779};
    6880
  • trunk/Source/WebCore/loader/EmptyClients.h

    r94270 r94908  
    165165    virtual void delegatedScrollRequested(const IntPoint&) { }
    166166#endif
    167 #if ENABLE(REQUEST_ANIMATION_FRAME)
     167#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
    168168    virtual void scheduleAnimation() { }
    169169#endif
  • trunk/Source/WebCore/page/Chrome.cpp

    r94640 r94908  
    515515void Chrome::scheduleAnimation()
    516516{
     517#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
    517518    m_client->scheduleAnimation();
     519#endif
    518520}
    519521#endif
  • trunk/Source/WebCore/page/ChromeClient.h

    r94270 r94908  
    160160        virtual void setCursor(const Cursor&) = 0;
    161161        virtual void setCursorHiddenUntilMouseMoves(bool) = 0;
    162 #if ENABLE(REQUEST_ANIMATION_FRAME)
     162#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
    163163        virtual void scheduleAnimation() = 0;
    164164#endif
  • trunk/Source/WebKit/mac/ChangeLog

    r94889 r94908  
     12011-09-09  Chris Marrin  <cmarrin@apple.com>
     2
     3        requestAnimationFrame doesn't throttle on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=67171
     5
     6        Reviewed by Simon Fraser.
     7
     8        Removed runLoopObserver for requestAnimationFrame. It's now
     9        done by a Timer in ScriptedAnimationController in WebCore.
     10
     11        * WebCoreSupport/WebChromeClient.h:
     12        * WebCoreSupport/WebChromeClient.mm:
     13        * WebView/WebView.mm:
     14        (-[WebView _close]):
     15        * WebView/WebViewData.h:
     16        * WebView/WebViewInternal.h:
     17
    1182011-09-09  Fady Samuel  <fsamuel@chromium.org>
    219
  • trunk/Source/WebKit/mac/WebCoreSupport/WebChromeClient.h

    r94080 r94908  
    129129    virtual void setCursorHiddenUntilMouseMoves(bool);
    130130
    131 #if ENABLE(REQUEST_ANIMATION_FRAME)
    132         virtual void scheduleAnimation();
    133 #endif
    134 
    135131    virtual WebCore::FloatRect customHighlightRect(WebCore::Node*, const WTF::AtomicString& type,
    136132        const WebCore::FloatRect& lineRect);
  • trunk/Source/WebKit/mac/WebCoreSupport/WebChromeClient.mm

    r94080 r94908  
    943943#endif
    944944
    945 #if ENABLE(REQUEST_ANIMATION_FRAME)
    946 void WebChromeClient::scheduleAnimation()
    947 {
    948     BEGIN_BLOCK_OBJC_EXCEPTIONS;
    949     [m_webView _scheduleAnimation];
    950     END_BLOCK_OBJC_EXCEPTIONS;
    951 }
    952 #endif
    953 
    954945#if ENABLE(VIDEO)
    955946
  • trunk/Source/WebKit/mac/WebView/WebView.mm

    r94889 r94908  
    396396- (void)_clearLayerSyncLoopObserver;
    397397#endif
    398 #if ENABLE(REQUEST_ANIMATION_FRAME)
    399 - (void)_unscheduleAnimation;
    400 #endif
    401398#if ENABLE(GLIB_SUPPORT)
    402399- (void)_clearGlibLoopObserver;
     
    12271224#endif
    12281225   
    1229 #if ENABLE(REQUEST_ANIMATION_FRAME)
    1230     [self _unscheduleAnimation];
    1231 #endif
    1232 
    12331226#if ENABLE(GLIB_SUPPORT)
    12341227    [self _clearGlibLoopObserver];
     
    59225915#endif
    59235916
    5924 #if ENABLE(REQUEST_ANIMATION_FRAME)
    5925 - (void)_unscheduleAnimation
    5926 {
    5927     if (!_private->requestAnimationFrameRunLoopObserver)
    5928         return;
    5929 
    5930     CFRunLoopObserverInvalidate(_private->requestAnimationFrameRunLoopObserver);
    5931     CFRelease(_private->requestAnimationFrameRunLoopObserver);
    5932     _private->requestAnimationFrameRunLoopObserver = 0;
    5933 }
    5934 #endif
    5935 
    59365917#if ENABLE(GLIB_SUPPORT)
    59375918- (void)_clearGlibLoopObserver
     
    62136194#endif
    62146195
    6215 #if ENABLE(REQUEST_ANIMATION_FRAME)
    6216 static void requestAnimationFrameRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* info)
    6217 {
    6218     WebView *webView = reinterpret_cast<WebView*>(info);
    6219     [webView _unscheduleAnimation];
    6220    
    6221     if (Frame* frame = [webView _mainCoreFrame])
    6222         if (FrameView* frameView = frame->view())
    6223             frameView->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
    6224 }
    6225 
    6226 - (void)_scheduleAnimation
    6227 {
    6228     if (!_private->requestAnimationFrameRunLoopObserver) {
    6229         CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
    6230    
    6231         // Make sure we wake up the loop or the observer could be delayed until some other source fires.
    6232         CFRunLoopWakeUp(currentRunLoop);
    6233 
    6234         // Run before the layerSyncRunLoopObserver, which has order NSDisplayWindowRunLoopOrdering + 2.
    6235         const CFIndex runLoopOrder = NSDisplayWindowRunLoopOrdering + 1;
    6236         CFRunLoopObserverContext context = { 0, self, 0, 0, 0 };
    6237         _private->requestAnimationFrameRunLoopObserver = CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting | kCFRunLoopExit, NO, runLoopOrder, requestAnimationFrameRunLoopObserverCallback, &context);
    6238         CFRunLoopAddObserver(currentRunLoop, _private->requestAnimationFrameRunLoopObserver, kCFRunLoopCommonModes);
    6239     }
    6240 }
    6241 #endif
    6242 
    62436196#if ENABLE(VIDEO)
    62446197
  • trunk/Source/WebKit/mac/WebView/WebViewData.h

    r94247 r94908  
    156156#endif
    157157
    158 #if ENABLE(REQUEST_ANIMATION_FRAME)
    159     CFRunLoopObserverRef requestAnimationFrameRunLoopObserver;
    160 #endif
    161 
    162158    NSPasteboard *insertionPasteboard;
    163159           
  • trunk/Source/WebKit/mac/WebView/WebViewInternal.h

    r94124 r94908  
    9292- (void)_setNeedsOneShotDrawingSynchronization:(BOOL)needsSynchronization;
    9393- (void)_scheduleCompositingLayerSync;
    94 #endif
    95 
    96 #if ENABLE(REQUEST_ANIMATION_FRAME)
    97 - (void)_scheduleAnimation;
    9894#endif
    9995
  • trunk/Source/WebKit2/ChangeLog

    r94889 r94908  
     12011-09-09  Chris Marrin  <cmarrin@apple.com>
     2
     3        requestAnimationFrame doesn't throttle on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=67171
     5
     6        Reviewed by Simon Fraser.
     7
     8        Removed runLoopObserver for requestAnimationFrame. It's now
     9        done by a Timer in ScriptedAnimationController in WebCore.
     10
     11        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     12        * WebProcess/WebCoreSupport/WebChromeClient.h:
     13        * WebProcess/WebPage/WebPage.cpp:
     14        (WebKit::WebPage::~WebPage):
     15        * WebProcess/WebPage/WebPage.h:
     16        * WebProcess/WebPage/mac/WebPageMac.mm:
     17
    1182011-09-09  Fady Samuel  <fsamuel@chromium.org>
    219
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r94080 r94908  
    655655}
    656656
    657 #if ENABLE(REQUEST_ANIMATION_FRAME)
    658 void WebChromeClient::scheduleAnimation()
    659 {
    660     m_page->scheduleAnimation();
    661 }
    662 #endif
    663 
    664657void WebChromeClient::formStateDidChange(const Node*)
    665658{
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h

    r94080 r94908  
    173173    virtual void setCursorHiddenUntilMouseMoves(bool);
    174174
    175 #if ENABLE(REQUEST_ANIMATION_FRAME)
    176     virtual void scheduleAnimation();
    177 #endif
    178 
    179175    // Notification that the given form element has changed. This function
    180176    // will be called frequently, so handling should be very fast.
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r94889 r94908  
    263263#if PLATFORM(MAC)
    264264    ASSERT(m_pluginViews.isEmpty());
    265 
    266 #if ENABLE(REQUEST_ANIMATION_FRAME)
    267     unscheduleAnimation();
    268     ASSERT(!m_requestAnimationFrameRunLoopObserver);
    269 #endif
    270 
    271265#endif
    272266
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r94613 r94908  
    352352    bool performNonEditingBehaviorForSelector(const String&);
    353353
    354 #if ENABLE(REQUEST_ANIMATION_FRAME)
    355     void scheduleAnimation();
    356     void unscheduleAnimation();
    357 #endif
    358354#elif PLATFORM(WIN)
    359355    void confirmComposition(const String& compositionString);
     
    613609    WebCore::KeyboardEvent* m_keyboardEventBeingInterpreted;
    614610
    615 #if ENABLE(REQUEST_ANIMATION_FRAME)
    616     static void requestAnimationFrameRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*);
    617     RetainPtr<CFRunLoopObserverRef> m_requestAnimationFrameRunLoopObserver;
    618 #endif
    619 
    620611#elif PLATFORM(WIN)
    621612    // Our view's window (in the UI process).
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm

    r94613 r94908  
    3131#import "DataReference.h"
    3232#import "EditorState.h"
    33 #import "LayerTreeHostCAMac.h"
    3433#import "PluginView.h"
    3534#import "WebCoreArgumentCoders.h"
     
    585584}
    586585
    587 #if ENABLE(REQUEST_ANIMATION_FRAME)
    588 void WebPage::requestAnimationFrameRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context)
    589 {
    590     WebPage* webPage = static_cast<WebPage*>(context);
    591     webPage->unscheduleAnimation();
    592    
    593     // This gets called outside of the normal event loop so wrap in an autorelease pool
    594     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    595     if (webPage->corePage()->mainFrame() && webPage->corePage()->mainFrame()->view())
    596         webPage->corePage()->mainFrame()->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
    597     [pool drain];
    598 }
    599 
    600 void WebPage::scheduleAnimation()
    601 {
    602     if (!m_requestAnimationFrameRunLoopObserver) {
    603         CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
    604    
    605         // Make sure we wake up the loop or the observer could be delayed until some other source fires.
    606         CFRunLoopWakeUp(currentRunLoop);
    607 
    608         // Run before the flushPendingLayerChangesRunLoopObserver, which has order CoreAnimationRunLoopOrder - 1.
    609         const CFIndex runLoopOrder = CoreAnimationRunLoopOrder - 2;
    610         CFRunLoopObserverContext context = { 0, this, 0, 0, 0 };
    611         m_requestAnimationFrameRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting | kCFRunLoopExit, false, runLoopOrder, requestAnimationFrameRunLoopObserverCallback, &context));
    612 
    613         CFRunLoopAddObserver(currentRunLoop, m_requestAnimationFrameRunLoopObserver.get(), kCFRunLoopCommonModes);
    614     }
    615 }
    616 
    617 void WebPage::unscheduleAnimation()
    618 {
    619     if (m_requestAnimationFrameRunLoopObserver) {
    620         CFRunLoopObserverInvalidate(m_requestAnimationFrameRunLoopObserver.get());
    621         m_requestAnimationFrameRunLoopObserver = nullptr;
    622     }
    623 }
    624 #endif
    625 
    626586bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&)
    627587{
Note: See TracChangeset for help on using the changeset viewer.