diff options
author | Yida Wang <yidaw@codeaurora.org> | 2012-08-23 12:51:00 -0400 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2013-01-20 18:38:31 -0800 |
commit | 77ab7f788fa2de43390a0ddb447c94a191284e88 (patch) | |
tree | aa2021d922d649581c1473ee21cb509e0eb236ea /Source/WebCore/dom/ScriptedAnimationController.cpp | |
parent | 70f026a42cf1bee061389fa6ce790ea1186f0703 (diff) | |
download | external_webkit-77ab7f788fa2de43390a0ddb447c94a191284e88.zip external_webkit-77ab7f788fa2de43390a0ddb447c94a191284e88.tar.gz external_webkit-77ab7f788fa2de43390a0ddb447c94a191284e88.tar.bz2 |
Implement requestAnimationFrame
Cherry-pick from webkit-org branch on Code Aurora Forum:
requestAnimationFrame doesn't throttle on Mac
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=d9dca741b4762c433ae18f7a1bc59a3a81861fc8
Timestamp parameter to requestAnimationFrame is busted in USE(REQUEST_ANIMATION_FRAME_TIMER) path
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=f0909a46fa167c84062c63caffef340a6054bc1e
Rename webkitCancelRequestAnimationFrame to webkitCancelAnimationFrame to match spec change
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=cd5d11d662d638b3e4dfda33f23cda907f007f12
Remove partially implemented per-Element visibility checks from requestAnimationFrame logic
https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commit;h=9fb90af3cebd0e595990cded0941d230cf77dcc1
(cherry picked from commit 47ff59a279eab9ae5dd1fd17ce7057431750a0b5)
Change-Id: I7e77200006bb0c4cd4b4209082296c425bd207c1
Diffstat (limited to 'Source/WebCore/dom/ScriptedAnimationController.cpp')
-rw-r--r-- | Source/WebCore/dom/ScriptedAnimationController.cpp | 78 |
1 files changed, 44 insertions, 34 deletions
diff --git a/Source/WebCore/dom/ScriptedAnimationController.cpp b/Source/WebCore/dom/ScriptedAnimationController.cpp index 0c70359..4fbf6d9 100644 --- a/Source/WebCore/dom/ScriptedAnimationController.cpp +++ b/Source/WebCore/dom/ScriptedAnimationController.cpp @@ -29,16 +29,29 @@ #if ENABLE(REQUEST_ANIMATION_FRAME) #include "Document.h" -#include "Element.h" #include "FrameView.h" #include "RequestAnimationFrameCallback.h" +#if USE(REQUEST_ANIMATION_FRAME_TIMER) +#include <algorithm> +#include <wtf/CurrentTime.h> + +using namespace std; + +// Allow a little more than 60fps to make sure we can at least hit that frame rate. +#define MinimumAnimationInterval 0.015 +#endif + namespace WebCore { ScriptedAnimationController::ScriptedAnimationController(Document* document) : m_document(document) , m_nextCallbackId(0) , m_suspendCount(0) +#if USE(REQUEST_ANIMATION_FRAME_TIMER) + , m_animationTimer(this, &ScriptedAnimationController::animationTimerFired) + , m_lastAnimationFrameTime(0) +#endif { } @@ -51,20 +64,17 @@ void ScriptedAnimationController::resume() { --m_suspendCount; if (!m_suspendCount && m_callbacks.size()) - if (FrameView* fv = m_document->view()) - fv->scheduleAnimation(); + scheduleAnimation(); } -ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(PassRefPtr<RequestAnimationFrameCallback> callback, Element* animationElement) +ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(PassRefPtr<RequestAnimationFrameCallback> callback) { ScriptedAnimationController::CallbackId id = m_nextCallbackId++; callback->m_firedOrCancelled = false; callback->m_id = id; - callback->m_element = animationElement; m_callbacks.append(callback); if (!m_suspendCount) - if (FrameView* view = m_document->view()) - view->scheduleAnimation(); + scheduleAnimation(); return id; } @@ -83,37 +93,19 @@ void ScriptedAnimationController::serviceScriptedAnimations(DOMTimeStamp time) { if (!m_callbacks.size() || m_suspendCount) return; - // We want to run the callback for all elements in the document that have registered - // for a callback and that are visible. Running the callbacks can cause new callbacks - // to be registered, existing callbacks to be cancelled, and elements to gain or lose - // visibility so this code has to iterate carefully. - - // FIXME: Currently, this code doesn't do any visibility tests beyond checking display: // First, generate a list of callbacks to consider. Callbacks registered from this point // on are considered only for the "next" frame, not this one. CallbackList callbacks(m_callbacks); - // Firing the callback may cause the visibility of other elements to change. To avoid - // missing any callbacks, we keep iterating through the list of candiate callbacks and firing - // them until nothing new becomes visible. - bool firedCallback; - do { - firedCallback = false; - // A previous iteration may have invalidated style (or layout). Update styles for each iteration - // for now since all we check is the existence of a renderer. - m_document->updateStyleIfNeeded(); - for (size_t i = 0; i < callbacks.size(); ++i) { - RequestAnimationFrameCallback* callback = callbacks[i].get(); - if (!callback->m_firedOrCancelled && (!callback->m_element || callback->m_element->renderer())) { - callback->m_firedOrCancelled = true; - callback->handleEvent(time); - firedCallback = true; - callbacks.remove(i); - break; - } + for (size_t i = 0; i < callbacks.size(); ++i) { + RequestAnimationFrameCallback* callback = callbacks[i].get(); + if (!callback->m_firedOrCancelled) { + callback->m_firedOrCancelled = true; + callback->handleEvent(time); } - } while (firedCallback); + } + m_document->updateStyleIfNeeded(); // Remove any callbacks we fired from the list of pending callbacks. for (size_t i = 0; i < m_callbacks.size();) { @@ -124,10 +116,28 @@ void ScriptedAnimationController::serviceScriptedAnimations(DOMTimeStamp time) } if (m_callbacks.size()) - if (FrameView* view = m_document->view()) - view->scheduleAnimation(); + scheduleAnimation(); } +void ScriptedAnimationController::scheduleAnimation() +{ +#if USE(REQUEST_ANIMATION_FRAME_TIMER) + double scheduleDelay = max<double>(MinimumAnimationInterval - (currentTime() - m_lastAnimationFrameTime), 0); + m_animationTimer.startOneShot(scheduleDelay); +#else + if (FrameView* frameView = m_document->view()) + frameView->scheduleAnimation(); +#endif +} + +#if USE(REQUEST_ANIMATION_FRAME_TIMER) +void ScriptedAnimationController::animationTimerFired(Timer<ScriptedAnimationController>*) +{ + m_lastAnimationFrameTime = currentTime(); + serviceScriptedAnimations(convertSecondsToDOMTimeStamp(m_lastAnimationFrameTime)); +} +#endif + } #endif |