diff options
Diffstat (limited to 'Source/WebCore/dom/ScriptedAnimationController.cpp')
-rw-r--r-- | Source/WebCore/dom/ScriptedAnimationController.cpp | 85 |
1 files changed, 55 insertions, 30 deletions
diff --git a/Source/WebCore/dom/ScriptedAnimationController.cpp b/Source/WebCore/dom/ScriptedAnimationController.cpp index ca582addd..b94ebdf36 100644 --- a/Source/WebCore/dom/ScriptedAnimationController.cpp +++ b/Source/WebCore/dom/ScriptedAnimationController.cpp @@ -26,15 +26,20 @@ #include "config.h" #include "ScriptedAnimationController.h" -#if ENABLE(REQUEST_ANIMATION_FRAME) - +#include "DOMWindow.h" +#include "DisplayRefreshMonitor.h" +#include "DisplayRefreshMonitorManager.h" #include "Document.h" #include "DocumentLoader.h" #include "FrameView.h" #include "InspectorInstrumentation.h" +#include "Logging.h" +#include "MainFrame.h" +#include "Page.h" #include "RequestAnimationFrameCallback.h" #include "Settings.h" #include <wtf/Ref.h> +#include <wtf/SystemTracing.h> #if USE(REQUEST_ANIMATION_FRAME_TIMER) #include <algorithm> @@ -49,15 +54,8 @@ namespace WebCore { ScriptedAnimationController::ScriptedAnimationController(Document* document, PlatformDisplayID displayID) : m_document(document) - , m_nextCallbackId(0) - , m_suspendCount(0) #if USE(REQUEST_ANIMATION_FRAME_TIMER) - , m_animationTimer(this, &ScriptedAnimationController::animationTimerFired) - , m_lastAnimationFrameTimeMonotonic(0) -#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) - , m_isUsingTimer(false) - , m_isThrottled(false) -#endif + , m_animationTimer(*this, &ScriptedAnimationController::animationTimerFired) #endif { windowScreenDidChange(displayID); @@ -67,6 +65,11 @@ ScriptedAnimationController::~ScriptedAnimationController() { } +bool ScriptedAnimationController::requestAnimationFrameEnabled() const +{ + return m_document && m_document->settings().requestAnimationFrameEnabled(); +} + void ScriptedAnimationController::suspend() { ++m_suspendCount; @@ -89,6 +92,8 @@ void ScriptedAnimationController::setThrottled(bool isThrottled) if (m_isThrottled == isThrottled) return; + LOG(Animations, "%p - Setting RequestAnimationFrame throttling state to %d in frame %p (isMainFrame: %d)", this, isThrottled, m_document->frame(), m_document->frame() ? m_document->frame()->isMainFrame() : 0); + m_isThrottled = isThrottled; if (m_animationTimer.isActive()) { m_animationTimer.stop(); @@ -99,12 +104,21 @@ void ScriptedAnimationController::setThrottled(bool isThrottled) #endif } -ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(PassRefPtr<RequestAnimationFrameCallback> callback) +bool ScriptedAnimationController::isThrottled() const +{ +#if USE(REQUEST_ANIMATION_FRAME_TIMER) && USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) + return m_isThrottled; +#else + return false; +#endif +} + +ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(Ref<RequestAnimationFrameCallback>&& callback) { ScriptedAnimationController::CallbackId id = ++m_nextCallbackId; callback->m_firedOrCancelled = false; callback->m_id = id; - m_callbacks.append(callback); + m_callbacks.append(WTFMove(callback)); InspectorInstrumentation::didRequestAnimationFrame(m_document, id); @@ -125,13 +139,15 @@ void ScriptedAnimationController::cancelCallback(CallbackId id) } } -void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTimeNow) +void ScriptedAnimationController::serviceScriptedAnimations(double timestamp) { - if (!m_callbacks.size() || m_suspendCount || (m_document->settings() && !m_document->settings()->requestAnimationFrameEnabled())) + if (!m_callbacks.size() || m_suspendCount || !requestAnimationFrameEnabled()) return; - double highResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicTimeNow); - double legacyHighResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToPseudoWallTime(monotonicTimeNow); + TraceScope tracingScope(RAFCallbackStart, RAFCallbackEnd); + + double highResNowMs = 1000 * timestamp; + double legacyHighResNowMs = 1000 * (timestamp + m_document->loader()->timing().referenceWallTime().secondsSinceEpoch().seconds()); // First, generate a list of callbacks to consider. Callbacks registered from this point // on are considered only for the "next" frame, not this one. @@ -139,10 +155,9 @@ void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTime // Invoking callbacks may detach elements from our document, which clears the document's // reference to us, so take a defensive reference. - Ref<ScriptedAnimationController> protect(*this); + Ref<ScriptedAnimationController> protectedThis(*this); - for (size_t i = 0; i < callbacks.size(); ++i) { - RequestAnimationFrameCallback* callback = callbacks[i].get(); + for (auto& callback : callbacks) { if (!callback->m_firedOrCancelled) { callback->m_firedOrCancelled = true; InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id); @@ -168,10 +183,10 @@ void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTime void ScriptedAnimationController::windowScreenDidChange(PlatformDisplayID displayID) { - if (m_document->settings() && !m_document->settings()->requestAnimationFrameEnabled()) + if (!requestAnimationFrameEnabled()) return; #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) - DisplayRefreshMonitorManager::sharedManager()->windowScreenDidChange(displayID, this); + DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this); #else UNUSED_PARAM(displayID); #endif @@ -179,13 +194,13 @@ void ScriptedAnimationController::windowScreenDidChange(PlatformDisplayID displa void ScriptedAnimationController::scheduleAnimation() { - if (!m_document || (m_document->settings() && !m_document->settings()->requestAnimationFrameEnabled())) + if (!requestAnimationFrameEnabled()) return; #if USE(REQUEST_ANIMATION_FRAME_TIMER) #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) if (!m_isUsingTimer && !m_isThrottled) { - if (DisplayRefreshMonitorManager::sharedManager()->scheduleAnimation(this)) + if (DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this)) return; m_isUsingTimer = true; @@ -200,7 +215,7 @@ void ScriptedAnimationController::scheduleAnimation() animationInterval = MinimumThrottledAnimationInterval; #endif - double scheduleDelay = std::max<double>(animationInterval - (monotonicallyIncreasingTime() - m_lastAnimationFrameTimeMonotonic), 0); + double scheduleDelay = std::max<double>(animationInterval - (m_document->domWindow()->nowTimestamp() - m_lastAnimationFrameTimestamp), 0); m_animationTimer.startOneShot(scheduleDelay); #else if (FrameView* frameView = m_document->view()) @@ -209,21 +224,31 @@ void ScriptedAnimationController::scheduleAnimation() } #if USE(REQUEST_ANIMATION_FRAME_TIMER) -void ScriptedAnimationController::animationTimerFired(Timer<ScriptedAnimationController>&) +void ScriptedAnimationController::animationTimerFired() { - m_lastAnimationFrameTimeMonotonic = monotonicallyIncreasingTime(); - serviceScriptedAnimations(m_lastAnimationFrameTimeMonotonic); + m_lastAnimationFrameTimestamp = m_document->domWindow()->nowTimestamp(); + serviceScriptedAnimations(m_lastAnimationFrameTimestamp); } #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) -void ScriptedAnimationController::displayRefreshFired(double monotonicTimeNow) +void ScriptedAnimationController::displayRefreshFired() { - serviceScriptedAnimations(monotonicTimeNow); + serviceScriptedAnimations(m_document->domWindow()->nowTimestamp()); } #endif #endif +#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) +RefPtr<DisplayRefreshMonitor> ScriptedAnimationController::createDisplayRefreshMonitor(PlatformDisplayID displayID) const +{ + if (!m_document->page()) + return nullptr; + + if (auto monitor = m_document->page()->chrome().client().createDisplayRefreshMonitor(displayID)) + return monitor; + return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID); } - #endif + +} |