summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/dom
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom')
-rw-r--r--Source/WebCore/dom/Document.cpp6
-rw-r--r--Source/WebCore/dom/Document.h4
-rw-r--r--Source/WebCore/dom/RequestAnimationFrameCallback.h4
-rw-r--r--Source/WebCore/dom/ScriptedAnimationController.cpp78
-rw-r--r--Source/WebCore/dom/ScriptedAnimationController.h15
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
};
}