Title: [233140] trunk
Revision
233140
Author
[email protected]
Date
2018-06-25 02:54:34 -0700 (Mon, 25 Jun 2018)

Log Message

[Web Animations] Ensure animations are updated prior to requestAnimationFrame callbacks
https://bugs.webkit.org/show_bug.cgi?id=186997
<rdar://problem/41419414>

Reviewed by Dean Jackson.

LayoutTests/imported/mozilla:

Mark progressions in the Mozilla CSS Animations tests.

* css-animations/test_animation-pausing-expected.txt:

Source/WebCore:

Some sub-tests of imported/mozilla/css-animations/test_animation-pausing.html clearly expect that animations
would be resolved prior to firing a requestAnimationFrame() callback, as the HTML5 event loop mandates. But until
now, both DocumentTimeline and ScriptedAnimationController would make calls to DisplayRefreshMonitorManager::scheduleAnimation()
that were not coordinated and so the order in which the DocumentTimeline and ScriptedAnimationController callbacks
were performed was not guaranteed.

In this patch we add a new DocumentAnimationScheduler class which is created by a Document to manage this specific
situation. Now DocumentTimeline and ScriptedAnimationController use this supporting object instead of being their
own DisplayRefreshMonitorClient and call scheduleWebAnimationsResolution() and scheduleScriptedAnimationResolution()
respectively to indicate the need to schedule an animation through the DisplayRefreshMonitorManager to serve the specific
needs of either, or both, classes. Then DocumentAnimationScheduler ensures that Web Animations resolution happens
prior to requestAnimationFrame callbacks when both are scheduled.

In the future we should be able to move more code from DocumentTimeline and ScriptedAnimationController over to
DocumentAnimationScheduler, such as support for throttling and using a timer-based fallback, but this patch provides
the minimal functionality required to provide a sounder foundation.

* Modules/webvr/VRDisplay.cpp:
(WebCore::VRDisplay::requestAnimationFrame):
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* animation/DocumentAnimationScheduler.cpp: Added.
(WebCore::DocumentAnimationScheduler::create):
(WebCore::DocumentAnimationScheduler::DocumentAnimationScheduler):
(WebCore::DocumentAnimationScheduler::detachFromDocument):
(WebCore::DocumentAnimationScheduler::scheduleWebAnimationsResolution):
(WebCore::DocumentAnimationScheduler::scheduleScriptedAnimationResolution):
(WebCore::DocumentAnimationScheduler::displayRefreshFired):
(WebCore::DocumentAnimationScheduler::windowScreenDidChange):
(WebCore::DocumentAnimationScheduler::createDisplayRefreshMonitor const):
* animation/DocumentAnimationScheduler.h: Copied from Source/WebCore/animation/CSSAnimation.h.
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::create):
(WebCore::DocumentTimeline::DocumentTimeline):
(WebCore::DocumentTimeline::scheduleAnimationResolution):
(WebCore::DocumentTimeline::windowScreenDidChange): Deleted.
(WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Deleted.
* animation/DocumentTimeline.h:
* dom/Document.cpp:
(WebCore::Document::prepareForDestruction):
(WebCore::Document::windowScreenDidChange):
(WebCore::Document::requestAnimationFrame):
(WebCore::Document::animationScheduler):
(WebCore::Document::timeline):
* dom/Document.h:
* dom/ScriptedAnimationController.cpp:
(WebCore::ScriptedAnimationController::ScriptedAnimationController):
(WebCore::ScriptedAnimationController::scheduleAnimation):
(WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire):
(WebCore::ScriptedAnimationController::windowScreenDidChange): Deleted.
(WebCore::ScriptedAnimationController::displayRefreshFired): Deleted.
(WebCore::ScriptedAnimationController::createDisplayRefreshMonitor const): Deleted.
* dom/ScriptedAnimationController.h:
(WebCore::ScriptedAnimationController::create):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/mozilla/ChangeLog (233139 => 233140)


--- trunk/LayoutTests/imported/mozilla/ChangeLog	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/LayoutTests/imported/mozilla/ChangeLog	2018-06-25 09:54:34 UTC (rev 233140)
@@ -1,3 +1,15 @@
+2018-06-25  Antoine Quint  <[email protected]>
+
+        [Web Animations] Ensure animations are updated prior to requestAnimationFrame callbacks
+        https://bugs.webkit.org/show_bug.cgi?id=186997
+        <rdar://problem/41419414>
+
+        Reviewed by Dean Jackson.
+
+        Mark progressions in the Mozilla CSS Animations tests.
+
+        * css-animations/test_animation-pausing-expected.txt:
+
 2018-06-20  Antoine Quint  <[email protected]>
 
         [Web Animations] Make imported/mozilla/css-animations/test_animation-ready.html pass reliably

Modified: trunk/LayoutTests/imported/mozilla/css-animations/test_animation-pausing-expected.txt (233139 => 233140)


--- trunk/LayoutTests/imported/mozilla/css-animations/test_animation-pausing-expected.txt	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/LayoutTests/imported/mozilla/css-animations/test_animation-pausing-expected.txt	2018-06-25 09:54:34 UTC (rev 233140)
@@ -1,8 +1,8 @@
 
 PASS play() overrides animation-play-state 
-FAIL pause() overrides animation-play-state undefined is not an object (evaluating 'animation.pause')
-FAIL play() is overridden by later setting "animation-play-state: paused" undefined is not an object (evaluating 'animation.play')
-FAIL play() flushes pending changes to animation-play-state first assert_greater_than: Playing value of margin-left is increasing expected a number greater than 0 but got 0
-FAIL pause() applies pending changes to animation-play-state first undefined is not an object (evaluating 'animation.pause')
-FAIL Setting the current time completes a pending pause assert_true: Animation is pause-pending expected true got false
+FAIL pause() overrides animation-play-state assert_equals: Paused value of margin-left is zero expected 0 but got 0.03600386157631874
+PASS play() is overridden by later setting "animation-play-state: paused" 
+PASS play() flushes pending changes to animation-play-state first 
+PASS pause() applies pending changes to animation-play-state first 
+PASS Setting the current time completes a pending pause 
 

Modified: trunk/Source/WebCore/ChangeLog (233139 => 233140)


--- trunk/Source/WebCore/ChangeLog	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/ChangeLog	2018-06-25 09:54:34 UTC (rev 233140)
@@ -1,3 +1,66 @@
+2018-06-25  Antoine Quint  <[email protected]>
+
+        [Web Animations] Ensure animations are updated prior to requestAnimationFrame callbacks
+        https://bugs.webkit.org/show_bug.cgi?id=186997
+        <rdar://problem/41419414>
+
+        Reviewed by Dean Jackson.
+
+        Some sub-tests of imported/mozilla/css-animations/test_animation-pausing.html clearly expect that animations
+        would be resolved prior to firing a requestAnimationFrame() callback, as the HTML5 event loop mandates. But until
+        now, both DocumentTimeline and ScriptedAnimationController would make calls to DisplayRefreshMonitorManager::scheduleAnimation()
+        that were not coordinated and so the order in which the DocumentTimeline and ScriptedAnimationController callbacks
+        were performed was not guaranteed.
+
+        In this patch we add a new DocumentAnimationScheduler class which is created by a Document to manage this specific
+        situation. Now DocumentTimeline and ScriptedAnimationController use this supporting object instead of being their
+        own DisplayRefreshMonitorClient and call scheduleWebAnimationsResolution() and scheduleScriptedAnimationResolution()
+        respectively to indicate the need to schedule an animation through the DisplayRefreshMonitorManager to serve the specific
+        needs of either, or both, classes. Then DocumentAnimationScheduler ensures that Web Animations resolution happens
+        prior to requestAnimationFrame callbacks when both are scheduled.
+
+        In the future we should be able to move more code from DocumentTimeline and ScriptedAnimationController over to
+        DocumentAnimationScheduler, such as support for throttling and using a timer-based fallback, but this patch provides
+        the minimal functionality required to provide a sounder foundation.
+
+        * Modules/webvr/VRDisplay.cpp:
+        (WebCore::VRDisplay::requestAnimationFrame):
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * animation/DocumentAnimationScheduler.cpp: Added.
+        (WebCore::DocumentAnimationScheduler::create):
+        (WebCore::DocumentAnimationScheduler::DocumentAnimationScheduler):
+        (WebCore::DocumentAnimationScheduler::detachFromDocument):
+        (WebCore::DocumentAnimationScheduler::scheduleWebAnimationsResolution):
+        (WebCore::DocumentAnimationScheduler::scheduleScriptedAnimationResolution):
+        (WebCore::DocumentAnimationScheduler::displayRefreshFired):
+        (WebCore::DocumentAnimationScheduler::windowScreenDidChange):
+        (WebCore::DocumentAnimationScheduler::createDisplayRefreshMonitor const):
+        * animation/DocumentAnimationScheduler.h: Copied from Source/WebCore/animation/CSSAnimation.h.
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::create):
+        (WebCore::DocumentTimeline::DocumentTimeline):
+        (WebCore::DocumentTimeline::scheduleAnimationResolution):
+        (WebCore::DocumentTimeline::windowScreenDidChange): Deleted.
+        (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Deleted.
+        * animation/DocumentTimeline.h:
+        * dom/Document.cpp:
+        (WebCore::Document::prepareForDestruction):
+        (WebCore::Document::windowScreenDidChange):
+        (WebCore::Document::requestAnimationFrame):
+        (WebCore::Document::animationScheduler):
+        (WebCore::Document::timeline):
+        * dom/Document.h:
+        * dom/ScriptedAnimationController.cpp:
+        (WebCore::ScriptedAnimationController::ScriptedAnimationController):
+        (WebCore::ScriptedAnimationController::scheduleAnimation):
+        (WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire):
+        (WebCore::ScriptedAnimationController::windowScreenDidChange): Deleted.
+        (WebCore::ScriptedAnimationController::displayRefreshFired): Deleted.
+        (WebCore::ScriptedAnimationController::createDisplayRefreshMonitor const): Deleted.
+        * dom/ScriptedAnimationController.h:
+        (WebCore::ScriptedAnimationController::create):
+
 2018-06-25  Zan Dobersek  <[email protected]>
 
         [GCrypt] Zero-prefix (if necessary) output of RSA-based encryption and signing operations

Modified: trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp (233139 => 233140)


--- trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp	2018-06-25 09:54:34 UTC (rev 233140)
@@ -110,13 +110,7 @@
 {
     if (!m_scriptedAnimationController) {
         auto* document = downcast<Document>(scriptExecutionContext());
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-        // FIXME: Get the display id of the HMD as it should use the HMD native refresh rate.
-        PlatformDisplayID displayID = document->page() ? document->page()->chrome().displayID() : 0;
-        m_scriptedAnimationController = ScriptedAnimationController::create(*document, displayID);
-#else
-        m_scriptedAnimationController = ScriptedAnimationController::create(*document, 0);
-#endif
+        m_scriptedAnimationController = ScriptedAnimationController::create(*document);
     }
 
     return m_scriptedAnimationController->registerCallback(WTFMove(callback));

Modified: trunk/Source/WebCore/Sources.txt (233139 => 233140)


--- trunk/Source/WebCore/Sources.txt	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/Sources.txt	2018-06-25 09:54:34 UTC (rev 233140)
@@ -339,6 +339,7 @@
 animation/CSSAnimation.cpp
 animation/CSSTransition.cpp
 animation/DeclarativeAnimation.cpp
+animation/DocumentAnimationScheduler.cpp
 animation/DocumentTimeline.cpp
 animation/KeyframeEffect.cpp
 animation/KeyframeEffectReadOnly.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (233139 => 233140)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-06-25 09:54:34 UTC (rev 233140)
@@ -2025,6 +2025,7 @@
 		71556CBE1F9F0A4900E78D08 /* JSKeyframeEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 71556CB71F9F09FC00E78D08 /* JSKeyframeEffect.h */; };
 		715AD7202050513200D592DC /* DeclarativeAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 715AD71D2050512400D592DC /* DeclarativeAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		715AD7212050513F00D592DC /* CSSTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 7123C186204739BA00789392 /* CSSTransition.h */; };
+		716E55B020DBABF100F0CF29 /* DocumentAnimationScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 716E55AD20DBABDC00F0CF29 /* DocumentAnimationScheduler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		71A1B6081DEE5AD70073BCFB /* modern-media-controls-localized-strings.js in Resources */ = {isa = PBXBuildFile; fileRef = 71A1B6061DEE5A820073BCFB /* modern-media-controls-localized-strings.js */; };
 		71A57DF2154BE25C0009D120 /* SVGPathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A57DF0154BE25C0009D120 /* SVGPathUtilities.h */; };
 		71B28427203CEC4C0036AA5D /* JSCSSAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B28426203CEC0D0036AA5D /* JSCSSAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9058,6 +9059,8 @@
 		716C8DF61E48B2B5005BD0DA /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
 		716C8DF71E48B2B5005BD0DA /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
 		716C8DF81E48B2B5005BD0DA /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
+		716E55AD20DBABDC00F0CF29 /* DocumentAnimationScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentAnimationScheduler.h; sourceTree = "<group>"; };
+		716E55AF20DBABDD00F0CF29 /* DocumentAnimationScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentAnimationScheduler.cpp; sourceTree = "<group>"; };
 		716FA0D81DB26591007323CC /* airplay-button.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = "airplay-button.css"; sourceTree = "<group>"; };
 		716FA0D91DB26591007323CC /* airplay-button.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "airplay-button.js"; sourceTree = "<group>"; };
 		716FA0DA1DB26591007323CC /* airplay-placard.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "airplay-placard.js"; sourceTree = "<group>"; };
@@ -19507,6 +19510,8 @@
 				7123C185204739B900789392 /* CSSTransition.idl */,
 				715AD71F2050512400D592DC /* DeclarativeAnimation.cpp */,
 				715AD71D2050512400D592DC /* DeclarativeAnimation.h */,
+				716E55AF20DBABDD00F0CF29 /* DocumentAnimationScheduler.cpp */,
+				716E55AD20DBABDC00F0CF29 /* DocumentAnimationScheduler.h */,
 				71025EC41F99F096004A250C /* DocumentTimeline.cpp */,
 				71025EC51F99F096004A250C /* DocumentTimeline.h */,
 				71025ECA1F99F096004A250C /* DocumentTimeline.idl */,
@@ -27680,6 +27685,7 @@
 				B2F34FE60E82F81400F627CD /* DNS.h in Headers */,
 				7EE6846F12D26E3800E73215 /* DNSResolveQueueCFNet.h in Headers */,
 				A8185F4009765766005826D9 /* Document.h in Headers */,
+				716E55B020DBABF100F0CF29 /* DocumentAnimationScheduler.h in Headers */,
 				A3BB59F41457A40D00AC56FE /* DocumentEventQueue.h in Headers */,
 				A8185F3D09765766005826D9 /* DocumentFragment.h in Headers */,
 				46E1666E1FCC86A200C9710B /* DocumentIdentifier.h in Headers */,

Added: trunk/Source/WebCore/animation/DocumentAnimationScheduler.cpp (0 => 233140)


--- trunk/Source/WebCore/animation/DocumentAnimationScheduler.cpp	                        (rev 0)
+++ trunk/Source/WebCore/animation/DocumentAnimationScheduler.cpp	2018-06-25 09:54:34 UTC (rev 233140)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DocumentAnimationScheduler.h"
+
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DOMWindow.h"
+#include "DisplayRefreshMonitor.h"
+#include "DisplayRefreshMonitorManager.h"
+#include "Document.h"
+#include "DocumentTimeline.h"
+#include "Page.h"
+#include "ScriptedAnimationController.h"
+
+namespace WebCore {
+
+Ref<DocumentAnimationScheduler> DocumentAnimationScheduler::create(Document& document, PlatformDisplayID displayID)
+{
+    return adoptRef(*new DocumentAnimationScheduler(document, displayID));
+}
+
+DocumentAnimationScheduler::DocumentAnimationScheduler(Document& document, PlatformDisplayID displayID)
+    : m_document(&document)
+{
+    windowScreenDidChange(displayID);
+}
+
+DocumentAnimationScheduler::~DocumentAnimationScheduler() = default;
+
+void DocumentAnimationScheduler::detachFromDocument()
+{
+    m_document = nullptr;
+}
+
+bool DocumentAnimationScheduler::scheduleWebAnimationsResolution()
+{
+    m_scheduledWebAnimationsResolution = true;
+    return DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
+}
+
+bool DocumentAnimationScheduler::scheduleScriptedAnimationResolution()
+{
+    m_scheduledScriptedAnimationResolution = true;
+    return DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
+}
+
+void DocumentAnimationScheduler::displayRefreshFired()
+{
+    if (m_scheduledWebAnimationsResolution) {
+        m_scheduledWebAnimationsResolution = false;
+        m_document->timeline().documentAnimationSchedulerDidFire();
+    }
+
+    if (m_scheduledScriptedAnimationResolution) {
+        m_scheduledScriptedAnimationResolution = false;
+        if (auto* scriptedAnimationController = m_document->scriptedAnimationController())
+            scriptedAnimationController->documentAnimationSchedulerDidFire();
+    }
+}
+
+void DocumentAnimationScheduler::windowScreenDidChange(PlatformDisplayID displayID)
+{
+    DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this);
+}
+
+RefPtr<DisplayRefreshMonitor> DocumentAnimationScheduler::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
+{
+    if (!m_document || !m_document->page())
+        return nullptr;
+
+    if (auto monitor = m_document->page()->chrome().client().createDisplayRefreshMonitor(displayID))
+        return monitor;
+
+    return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID);
+}
+
+} // namespace WebCore
+
+#endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)

Added: trunk/Source/WebCore/animation/DocumentAnimationScheduler.h (0 => 233140)


--- trunk/Source/WebCore/animation/DocumentAnimationScheduler.h	                        (rev 0)
+++ trunk/Source/WebCore/animation/DocumentAnimationScheduler.h	2018-06-25 09:54:34 UTC (rev 233140)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+
+#include "DisplayRefreshMonitorClient.h"
+#include "PlatformScreen.h"
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Document;
+
+class DocumentAnimationScheduler : public RefCounted<DocumentAnimationScheduler>
+    , public DisplayRefreshMonitorClient {
+public:
+    static Ref<DocumentAnimationScheduler> create(Document&, PlatformDisplayID);
+    ~DocumentAnimationScheduler();
+
+    void detachFromDocument();
+    void windowScreenDidChange(PlatformDisplayID);
+
+    bool scheduleWebAnimationsResolution();
+    bool scheduleScriptedAnimationResolution();
+
+private:
+    DocumentAnimationScheduler(Document&, PlatformDisplayID);
+
+    RefPtr<Document> m_document;
+    bool m_scheduledWebAnimationsResolution { false };
+    bool m_scheduledScriptedAnimationResolution { false };
+
+    void displayRefreshFired() override;
+    RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const override;
+};
+
+} // namespace WebCore
+
+#endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)

Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (233139 => 233140)


--- trunk/Source/WebCore/animation/DocumentTimeline.cpp	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp	2018-06-25 09:54:34 UTC (rev 233140)
@@ -27,12 +27,8 @@
 #include "DocumentTimeline.h"
 
 #include "AnimationPlaybackEvent.h"
-#include "Chrome.h"
-#include "ChromeClient.h"
 #include "DOMWindow.h"
 #include "DeclarativeAnimation.h"
-#include "DisplayRefreshMonitor.h"
-#include "DisplayRefreshMonitorManager.h"
 #include "Document.h"
 #include "KeyframeEffect.h"
 #include "Page.h"
@@ -43,12 +39,12 @@
 
 namespace WebCore {
 
-Ref<DocumentTimeline> DocumentTimeline::create(Document& document, PlatformDisplayID displayID)
+Ref<DocumentTimeline> DocumentTimeline::create(Document& document)
 {
-    return adoptRef(*new DocumentTimeline(document, displayID));
+    return adoptRef(*new DocumentTimeline(document));
 }
 
-DocumentTimeline::DocumentTimeline(Document& document, PlatformDisplayID displayID)
+DocumentTimeline::DocumentTimeline(Document& document)
     : AnimationTimeline(DocumentTimelineClass)
     , m_document(&document)
     , m_animationScheduleTimer(*this, &DocumentTimeline::animationScheduleTimerFired)
@@ -56,7 +52,6 @@
     , m_animationResolutionTimer(*this, &DocumentTimeline::animationResolutionTimerFired)
 #endif
 {
-    windowScreenDidChange(displayID);
 }
 
 DocumentTimeline::~DocumentTimeline()
@@ -218,7 +213,7 @@
 void DocumentTimeline::scheduleAnimationResolution()
 {
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);
+    m_document->animationScheduler().scheduleWebAnimationsResolution();
 #else
     // FIXME: We need to use the same logic as ScriptedAnimationController here,
     // which will be addressed by the refactor tracked by webkit.org/b/179293.
@@ -227,7 +222,7 @@
 }
 
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-void DocumentTimeline::displayRefreshFired()
+void DocumentTimeline::documentAnimationSchedulerDidFire()
 #else
 void DocumentTimeline::animationResolutionTimerFired()
 #endif
@@ -392,26 +387,4 @@
         pendingEvent->target()->dispatchEvent(pendingEvent);
 }
 
-void DocumentTimeline::windowScreenDidChange(PlatformDisplayID displayID)
-{
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this);
-#else
-    UNUSED_PARAM(displayID);
-#endif
-}
-
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-RefPtr<DisplayRefreshMonitor> DocumentTimeline::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
-{
-    if (!m_document || !m_document->page())
-        return nullptr;
-
-    if (auto monitor = m_document->page()->chrome().client().createDisplayRefreshMonitor(displayID))
-        return monitor;
-
-    return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID);
-}
-#endif
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (233139 => 233140)


--- trunk/Source/WebCore/animation/DocumentTimeline.h	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h	2018-06-25 09:54:34 UTC (rev 233140)
@@ -27,14 +27,9 @@
 
 #include "AnimationTimeline.h"
 #include "GenericTaskQueue.h"
-#include "PlatformScreen.h"
 #include "Timer.h"
 #include <wtf/Ref.h>
 
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-#include "DisplayRefreshMonitorClient.h"
-#endif
-
 namespace WebCore {
 
 class AnimationPlaybackEvent;
@@ -41,12 +36,9 @@
 class RenderElement;
 
 class DocumentTimeline final : public AnimationTimeline
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    , public DisplayRefreshMonitorClient
-#endif
 {
 public:
-    static Ref<DocumentTimeline> create(Document&, PlatformDisplayID);
+    static Ref<DocumentTimeline> create(Document&);
     ~DocumentTimeline();
 
     Document* document() const { return m_document.get(); }
@@ -55,7 +47,6 @@
     void pause() override;
 
     void timingModelDidChange() override;
-    void windowScreenDidChange(PlatformDisplayID);
 
     // If possible, compute the visual extent of any transform animation on the given renderer
     // using the given rect, returning the result in the rect. Return false if there is some
@@ -71,6 +62,10 @@
 
     void enqueueAnimationPlaybackEvent(AnimationPlaybackEvent&);
 
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+    void documentAnimationSchedulerDidFire();
+#endif
+
     void updateThrottlingState();
     WEBCORE_EXPORT Seconds animationInterval() const;
     WEBCORE_EXPORT void suspendAnimations();
@@ -79,7 +74,7 @@
     WEBCORE_EXPORT unsigned numberOfActiveAnimationsForTesting() const;
 
 private:
-    DocumentTimeline(Document&, PlatformDisplayID);
+    DocumentTimeline(Document&);
 
     void scheduleInvalidationTaskIfNeeded();
     void performInvalidationTask();
@@ -100,11 +95,7 @@
     HashSet<RefPtr<WebAnimation>> m_acceleratedAnimationsPendingRunningStateChange;
     Vector<Ref<AnimationPlaybackEvent>> m_pendingAnimationEvents;
 
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    // Override for DisplayRefreshMonitorClient
-    void displayRefreshFired() override;
-    RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const override;
-#else
+#if !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     void animationResolutionTimerFired();
     Timer m_animationResolutionTimer;
 #endif

Modified: trunk/Source/WebCore/dom/Document.cpp (233139 => 233140)


--- trunk/Source/WebCore/dom/Document.cpp	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/dom/Document.cpp	2018-06-25 09:54:34 UTC (rev 233140)
@@ -56,6 +56,7 @@
 #include "DOMWindow.h"
 #include "DateComponents.h"
 #include "DebugPageOverlays.h"
+#include "DocumentAnimationScheduler.h"
 #include "DocumentLoader.h"
 #include "DocumentMarkerController.h"
 #include "DocumentSharedObjectPool.h"
@@ -2443,6 +2444,11 @@
         m_timeline = nullptr;
     }
 
+    if (m_animationScheduler) {
+        m_animationScheduler->detachFromDocument();
+        m_animationScheduler = nullptr;
+    }
+
     m_hasPreparedForDestruction = true;
 
     // Note that m_pageCacheState can be Document::AboutToEnterPageCache if our frame
@@ -5919,12 +5925,9 @@
 
 void Document::windowScreenDidChange(PlatformDisplayID displayID)
 {
-    if (m_scriptedAnimationController)
-        m_scriptedAnimationController->windowScreenDidChange(displayID);
+    if (m_animationScheduler)
+        m_animationScheduler->windowScreenDidChange(displayID);
 
-    if (m_timeline)
-        m_timeline->windowScreenDidChange(displayID);
-
     if (RenderView* view = renderView()) {
         if (view->usesCompositing())
             view->compositor().windowScreenDidChange(displayID);
@@ -6526,11 +6529,8 @@
 int Document::requestAnimationFrame(Ref<RequestAnimationFrameCallback>&& callback)
 {
     if (!m_scriptedAnimationController) {
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-        m_scriptedAnimationController = ScriptedAnimationController::create(*this, page() ? page()->chrome().displayID() : 0);
-#else
-        m_scriptedAnimationController = ScriptedAnimationController::create(*this, 0);
-#endif
+        m_scriptedAnimationController = ScriptedAnimationController::create(*this);
+
         // It's possible that the Page may have suspended scripted animations before
         // we were created. We need to make sure that we don't start up the animation
         // controller on a background tab, for example.
@@ -7717,10 +7717,18 @@
     m_consoleMessageListener = listener;
 }
 
+DocumentAnimationScheduler& Document::animationScheduler()
+{
+    if (!m_animationScheduler)
+        m_animationScheduler = DocumentAnimationScheduler::create(*this, page() ? page()->chrome().displayID() : 0);
+
+    return *m_animationScheduler;
+}
+
 DocumentTimeline& Document::timeline()
 {
     if (!m_timeline)
-        m_timeline = DocumentTimeline::create(*this, page() ? page()->chrome().displayID() : 0);
+        m_timeline = DocumentTimeline::create(*this);
 
     return *m_timeline;
 }

Modified: trunk/Source/WebCore/dom/Document.h (233139 => 233140)


--- trunk/Source/WebCore/dom/Document.h	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/dom/Document.h	2018-06-25 09:54:34 UTC (rev 233140)
@@ -80,6 +80,7 @@
 
 namespace WebCore {
 
+class DocumentAnimationScheduler;
 class ApplicationStateChangeListener;
 class AXObjectCache;
 class Attr;
@@ -1406,6 +1407,8 @@
 
     WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing.
 
+    DocumentAnimationScheduler& animationScheduler();
+
     WEBCORE_EXPORT DocumentTimeline& timeline();
     DocumentTimeline* existingTimeline() const { return m_timeline.get(); }
     Vector<RefPtr<WebAnimation>> getAnimations();
@@ -1920,6 +1923,7 @@
     bool m_hasFrameSpecificStorageAccess { false };
     bool m_grantStorageAccessOverride { false };
 
+    RefPtr<DocumentAnimationScheduler> m_animationScheduler;
     RefPtr<DocumentTimeline> m_timeline;
     DocumentIdentifier m_identifier;
 

Modified: trunk/Source/WebCore/dom/ScriptedAnimationController.cpp (233139 => 233140)


--- trunk/Source/WebCore/dom/ScriptedAnimationController.cpp	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/dom/ScriptedAnimationController.cpp	2018-06-25 09:54:34 UTC (rev 233140)
@@ -29,9 +29,8 @@
 #include "Chrome.h"
 #include "ChromeClient.h"
 #include "DOMWindow.h"
-#include "DisplayRefreshMonitor.h"
-#include "DisplayRefreshMonitorManager.h"
 #include "Document.h"
+#include "DocumentAnimationScheduler.h"
 #include "DocumentLoader.h"
 #include "Frame.h"
 #include "FrameView.h"
@@ -55,11 +54,10 @@
 
 namespace WebCore {
 
-ScriptedAnimationController::ScriptedAnimationController(Document& document, PlatformDisplayID displayID)
+ScriptedAnimationController::ScriptedAnimationController(Document& document)
     : m_document(&document)
     , m_animationTimer(*this, &ScriptedAnimationController::animationTimerFired)
 {
-    windowScreenDidChange(displayID);
 }
 
 ScriptedAnimationController::~ScriptedAnimationController() = default;
@@ -234,17 +232,6 @@
         scheduleAnimation();
 }
 
-void ScriptedAnimationController::windowScreenDidChange(PlatformDisplayID displayID)
-{
-    if (!requestAnimationFrameEnabled())
-        return;
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this);
-#else
-    UNUSED_PARAM(displayID);
-#endif
-}
-
 Seconds ScriptedAnimationController::interval() const
 {
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
@@ -274,7 +261,7 @@
 
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     if (!m_isUsingTimer && !isThrottled()) {
-        if (DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this))
+        if (m_document->animationScheduler().scheduleScriptedAnimationResolution())
             return;
 
         m_isUsingTimer = true;
@@ -308,21 +295,10 @@
 }
 
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-void ScriptedAnimationController::displayRefreshFired()
+void ScriptedAnimationController::documentAnimationSchedulerDidFire()
 {
     serviceScriptedAnimations(m_document->domWindow()->nowTimestamp());
 }
-
-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
 
 }

Modified: trunk/Source/WebCore/dom/ScriptedAnimationController.h (233139 => 233140)


--- trunk/Source/WebCore/dom/ScriptedAnimationController.h	2018-06-25 09:26:22 UTC (rev 233139)
+++ trunk/Source/WebCore/dom/ScriptedAnimationController.h	2018-06-25 09:54:34 UTC (rev 233140)
@@ -25,7 +25,6 @@
 
 #pragma once
 
-#include "PlatformScreen.h"
 #include "Timer.h"
 #include <wtf/OptionSet.h>
 #include <wtf/RefCounted.h>
@@ -32,10 +31,6 @@
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-#include "DisplayRefreshMonitorClient.h"
-#endif
-
 namespace WebCore {
 
 class Document;
@@ -43,14 +38,11 @@
 class RequestAnimationFrameCallback;
 
 class ScriptedAnimationController : public RefCounted<ScriptedAnimationController>
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    , public DisplayRefreshMonitorClient
-#endif
 {
 public:
-    static Ref<ScriptedAnimationController> create(Document& document, PlatformDisplayID displayID)
+    static Ref<ScriptedAnimationController> create(Document& document)
     {
-        return adoptRef(*new ScriptedAnimationController(document, displayID));
+        return adoptRef(*new ScriptedAnimationController(document));
     }
     ~ScriptedAnimationController();
     void clearDocumentPointer() { m_document = nullptr; }
@@ -77,19 +69,16 @@
     WEBCORE_EXPORT bool isThrottled() const;
     WEBCORE_EXPORT Seconds interval() const;
 
-    void windowScreenDidChange(PlatformDisplayID);
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+    void documentAnimationSchedulerDidFire();
+#endif
 
 private:
-    ScriptedAnimationController(Document&, PlatformDisplayID);
+    ScriptedAnimationController(Document&);
 
     void scheduleAnimation();
     void animationTimerFired();
 
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    // Override for DisplayRefreshMonitorClient
-    void displayRefreshFired() override;
-#endif
-
     Page* page() const;
 
     typedef Vector<RefPtr<RequestAnimationFrameCallback>> CallbackList;
@@ -103,7 +92,6 @@
     double m_lastAnimationFrameTimestamp { 0 };
 
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const override;
     OptionSet<ThrottlingReason> m_throttlingReasons;
     bool m_isUsingTimer { false };
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to