diff options
Diffstat (limited to 'Source/WebCore/dom')
-rw-r--r-- | Source/WebCore/dom/Document.cpp | 6 | ||||
-rw-r--r-- | Source/WebCore/dom/Document.h | 4 | ||||
-rw-r--r-- | Source/WebCore/dom/RequestAnimationFrameCallback.h | 4 | ||||
-rw-r--r-- | Source/WebCore/dom/ScriptedAnimationController.cpp | 78 | ||||
-rw-r--r-- | Source/WebCore/dom/ScriptedAnimationController.h | 15 |
5 files changed, 63 insertions, 44 deletions
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index a5f6cb4..e338c8e 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -5032,15 +5032,15 @@ void Document::loadEventDelayTimerFired(Timer<Document>*) } #if ENABLE(REQUEST_ANIMATION_FRAME) -int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback, Element* animationElement) +int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback) { if (!m_scriptedAnimationController) m_scriptedAnimationController = ScriptedAnimationController::create(this); - return m_scriptedAnimationController->registerCallback(callback, animationElement); + return m_scriptedAnimationController->registerCallback(callback); } -void Document::webkitCancelRequestAnimationFrame(int id) +void Document::webkitCancelAnimationFrame(int id) { if (!m_scriptedAnimationController) return; diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h index 353013e..685e3b7 100644 --- a/Source/WebCore/dom/Document.h +++ b/Source/WebCore/dom/Document.h @@ -1097,8 +1097,8 @@ public: const DocumentTiming* timing() const { return &m_documentTiming; } #if ENABLE(REQUEST_ANIMATION_FRAME) - int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>, Element*); - void webkitCancelRequestAnimationFrame(int id); + int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>); + void webkitCancelAnimationFrame(int id); void serviceScriptedAnimations(DOMTimeStamp); #endif diff --git a/Source/WebCore/dom/RequestAnimationFrameCallback.h b/Source/WebCore/dom/RequestAnimationFrameCallback.h index 3edeb9e..a867922 100644 --- a/Source/WebCore/dom/RequestAnimationFrameCallback.h +++ b/Source/WebCore/dom/RequestAnimationFrameCallback.h @@ -31,8 +31,7 @@ #ifndef RequestAnimationFrameCallback_h #define RequestAnimationFrameCallback_h -#include "Element.h" -#include <wtf/PassRefPtr.h> +#include "DOMTimeStamp.h" #include <wtf/RefCounted.h> namespace WebCore { @@ -42,7 +41,6 @@ public: virtual ~RequestAnimationFrameCallback() { } virtual bool handleEvent(DOMTimeStamp) = 0; - RefPtr<Element> m_element; int m_id; bool m_firedOrCancelled; }; 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 diff --git a/Source/WebCore/dom/ScriptedAnimationController.h b/Source/WebCore/dom/ScriptedAnimationController.h index 7141968..f6f06a9 100644 --- a/Source/WebCore/dom/ScriptedAnimationController.h +++ b/Source/WebCore/dom/ScriptedAnimationController.h @@ -28,6 +28,9 @@ #if ENABLE(REQUEST_ANIMATION_FRAME) #include "DOMTimeStamp.h" +#if USE(REQUEST_ANIMATION_FRAME_TIMER) +#include "Timer.h" +#endif #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> #include <wtf/RefPtr.h> @@ -36,7 +39,6 @@ namespace WebCore { class Document; -class Element; class RequestAnimationFrameCallback; class ScriptedAnimationController { @@ -49,7 +51,7 @@ public: typedef int CallbackId; - CallbackId registerCallback(PassRefPtr<RequestAnimationFrameCallback>, Element*); + CallbackId registerCallback(PassRefPtr<RequestAnimationFrameCallback>); void cancelCallback(CallbackId); void serviceScriptedAnimations(DOMTimeStamp); @@ -58,12 +60,21 @@ public: private: explicit ScriptedAnimationController(Document*); + typedef Vector<RefPtr<RequestAnimationFrameCallback> > CallbackList; CallbackList m_callbacks; Document* m_document; CallbackId m_nextCallbackId; int m_suspendCount; + + void scheduleAnimation(); + +#if USE(REQUEST_ANIMATION_FRAME_TIMER) + void animationTimerFired(Timer<ScriptedAnimationController>*); + Timer<ScriptedAnimationController> m_animationTimer; + double m_lastAnimationFrameTime; +#endif }; } |