Changeset 233140 in webkit
- Timestamp:
- Jun 25, 2018 2:54:34 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/mozilla/ChangeLog
r233051 r233140 1 2018-06-25 Antoine Quint <graouts@apple.com> 2 3 [Web Animations] Ensure animations are updated prior to requestAnimationFrame callbacks 4 https://bugs.webkit.org/show_bug.cgi?id=186997 5 <rdar://problem/41419414> 6 7 Reviewed by Dean Jackson. 8 9 Mark progressions in the Mozilla CSS Animations tests. 10 11 * css-animations/test_animation-pausing-expected.txt: 12 1 13 2018-06-20 Antoine Quint <graouts@apple.com> 2 14 -
trunk/LayoutTests/imported/mozilla/css-animations/test_animation-pausing-expected.txt
r229864 r233140 1 1 2 2 PASS play() overrides animation-play-state 3 FAIL pause() overrides animation-play-state undefined is not an object (evaluating 'animation.pause')4 FAIL play() is overridden by later setting "animation-play-state: paused" undefined is not an object (evaluating 'animation.play') 5 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 6 FAIL pause() applies pending changes to animation-play-state first undefined is not an object (evaluating 'animation.pause') 7 FAIL Setting the current time completes a pending pause assert_true: Animation is pause-pending expected true got false 3 FAIL pause() overrides animation-play-state assert_equals: Paused value of margin-left is zero expected 0 but got 0.03600386157631874 4 PASS play() is overridden by later setting "animation-play-state: paused" 5 PASS play() flushes pending changes to animation-play-state first 6 PASS pause() applies pending changes to animation-play-state first 7 PASS Setting the current time completes a pending pause 8 8 -
trunk/Source/WebCore/ChangeLog
r233138 r233140 1 2018-06-25 Antoine Quint <graouts@apple.com> 2 3 [Web Animations] Ensure animations are updated prior to requestAnimationFrame callbacks 4 https://bugs.webkit.org/show_bug.cgi?id=186997 5 <rdar://problem/41419414> 6 7 Reviewed by Dean Jackson. 8 9 Some sub-tests of imported/mozilla/css-animations/test_animation-pausing.html clearly expect that animations 10 would be resolved prior to firing a requestAnimationFrame() callback, as the HTML5 event loop mandates. But until 11 now, both DocumentTimeline and ScriptedAnimationController would make calls to DisplayRefreshMonitorManager::scheduleAnimation() 12 that were not coordinated and so the order in which the DocumentTimeline and ScriptedAnimationController callbacks 13 were performed was not guaranteed. 14 15 In this patch we add a new DocumentAnimationScheduler class which is created by a Document to manage this specific 16 situation. Now DocumentTimeline and ScriptedAnimationController use this supporting object instead of being their 17 own DisplayRefreshMonitorClient and call scheduleWebAnimationsResolution() and scheduleScriptedAnimationResolution() 18 respectively to indicate the need to schedule an animation through the DisplayRefreshMonitorManager to serve the specific 19 needs of either, or both, classes. Then DocumentAnimationScheduler ensures that Web Animations resolution happens 20 prior to requestAnimationFrame callbacks when both are scheduled. 21 22 In the future we should be able to move more code from DocumentTimeline and ScriptedAnimationController over to 23 DocumentAnimationScheduler, such as support for throttling and using a timer-based fallback, but this patch provides 24 the minimal functionality required to provide a sounder foundation. 25 26 * Modules/webvr/VRDisplay.cpp: 27 (WebCore::VRDisplay::requestAnimationFrame): 28 * Sources.txt: 29 * WebCore.xcodeproj/project.pbxproj: 30 * animation/DocumentAnimationScheduler.cpp: Added. 31 (WebCore::DocumentAnimationScheduler::create): 32 (WebCore::DocumentAnimationScheduler::DocumentAnimationScheduler): 33 (WebCore::DocumentAnimationScheduler::detachFromDocument): 34 (WebCore::DocumentAnimationScheduler::scheduleWebAnimationsResolution): 35 (WebCore::DocumentAnimationScheduler::scheduleScriptedAnimationResolution): 36 (WebCore::DocumentAnimationScheduler::displayRefreshFired): 37 (WebCore::DocumentAnimationScheduler::windowScreenDidChange): 38 (WebCore::DocumentAnimationScheduler::createDisplayRefreshMonitor const): 39 * animation/DocumentAnimationScheduler.h: Copied from Source/WebCore/animation/CSSAnimation.h. 40 * animation/DocumentTimeline.cpp: 41 (WebCore::DocumentTimeline::create): 42 (WebCore::DocumentTimeline::DocumentTimeline): 43 (WebCore::DocumentTimeline::scheduleAnimationResolution): 44 (WebCore::DocumentTimeline::windowScreenDidChange): Deleted. 45 (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Deleted. 46 * animation/DocumentTimeline.h: 47 * dom/Document.cpp: 48 (WebCore::Document::prepareForDestruction): 49 (WebCore::Document::windowScreenDidChange): 50 (WebCore::Document::requestAnimationFrame): 51 (WebCore::Document::animationScheduler): 52 (WebCore::Document::timeline): 53 * dom/Document.h: 54 * dom/ScriptedAnimationController.cpp: 55 (WebCore::ScriptedAnimationController::ScriptedAnimationController): 56 (WebCore::ScriptedAnimationController::scheduleAnimation): 57 (WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire): 58 (WebCore::ScriptedAnimationController::windowScreenDidChange): Deleted. 59 (WebCore::ScriptedAnimationController::displayRefreshFired): Deleted. 60 (WebCore::ScriptedAnimationController::createDisplayRefreshMonitor const): Deleted. 61 * dom/ScriptedAnimationController.h: 62 (WebCore::ScriptedAnimationController::create): 63 1 64 2018-06-25 Zan Dobersek <zdobersek@igalia.com> 2 65 -
trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp
r233122 r233140 111 111 if (!m_scriptedAnimationController) { 112 112 auto* document = downcast<Document>(scriptExecutionContext()); 113 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 114 // FIXME: Get the display id of the HMD as it should use the HMD native refresh rate. 115 PlatformDisplayID displayID = document->page() ? document->page()->chrome().displayID() : 0; 116 m_scriptedAnimationController = ScriptedAnimationController::create(*document, displayID); 117 #else 118 m_scriptedAnimationController = ScriptedAnimationController::create(*document, 0); 119 #endif 113 m_scriptedAnimationController = ScriptedAnimationController::create(*document); 120 114 } 121 115 -
trunk/Source/WebCore/Sources.txt
r233053 r233140 340 340 animation/CSSTransition.cpp 341 341 animation/DeclarativeAnimation.cpp 342 animation/DocumentAnimationScheduler.cpp 342 343 animation/DocumentTimeline.cpp 343 344 animation/KeyframeEffect.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r233116 r233140 2026 2026 715AD7202050513200D592DC /* DeclarativeAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 715AD71D2050512400D592DC /* DeclarativeAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2027 2027 715AD7212050513F00D592DC /* CSSTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 7123C186204739BA00789392 /* CSSTransition.h */; }; 2028 716E55B020DBABF100F0CF29 /* DocumentAnimationScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 716E55AD20DBABDC00F0CF29 /* DocumentAnimationScheduler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2028 2029 71A1B6081DEE5AD70073BCFB /* modern-media-controls-localized-strings.js in Resources */ = {isa = PBXBuildFile; fileRef = 71A1B6061DEE5A820073BCFB /* modern-media-controls-localized-strings.js */; }; 2029 2030 71A57DF2154BE25C0009D120 /* SVGPathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A57DF0154BE25C0009D120 /* SVGPathUtilities.h */; }; … … 9059 9060 716C8DF71E48B2B5005BD0DA /* volume-up-fullscreen@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "volume-up-fullscreen@1x.png"; sourceTree = "<group>"; }; 9060 9061 716C8DF81E48B2B5005BD0DA /* volume-up-fullscreen@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "volume-up-fullscreen@2x.png"; sourceTree = "<group>"; }; 9062 716E55AD20DBABDC00F0CF29 /* DocumentAnimationScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentAnimationScheduler.h; sourceTree = "<group>"; }; 9063 716E55AF20DBABDD00F0CF29 /* DocumentAnimationScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentAnimationScheduler.cpp; sourceTree = "<group>"; }; 9061 9064 716FA0D81DB26591007323CC /* airplay-button.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = "airplay-button.css"; sourceTree = "<group>"; }; 9062 9065 716FA0D91DB26591007323CC /* airplay-button.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "airplay-button.js"; sourceTree = "<group>"; }; … … 19508 19511 715AD71F2050512400D592DC /* DeclarativeAnimation.cpp */, 19509 19512 715AD71D2050512400D592DC /* DeclarativeAnimation.h */, 19513 716E55AF20DBABDD00F0CF29 /* DocumentAnimationScheduler.cpp */, 19514 716E55AD20DBABDC00F0CF29 /* DocumentAnimationScheduler.h */, 19510 19515 71025EC41F99F096004A250C /* DocumentTimeline.cpp */, 19511 19516 71025EC51F99F096004A250C /* DocumentTimeline.h */, … … 27681 27686 7EE6846F12D26E3800E73215 /* DNSResolveQueueCFNet.h in Headers */, 27682 27687 A8185F4009765766005826D9 /* Document.h in Headers */, 27688 716E55B020DBABF100F0CF29 /* DocumentAnimationScheduler.h in Headers */, 27683 27689 A3BB59F41457A40D00AC56FE /* DocumentEventQueue.h in Headers */, 27684 27690 A8185F3D09765766005826D9 /* DocumentFragment.h in Headers */, -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r232185 r233140 28 28 29 29 #include "AnimationPlaybackEvent.h" 30 #include "Chrome.h"31 #include "ChromeClient.h"32 30 #include "DOMWindow.h" 33 31 #include "DeclarativeAnimation.h" 34 #include "DisplayRefreshMonitor.h"35 #include "DisplayRefreshMonitorManager.h"36 32 #include "Document.h" 37 33 #include "KeyframeEffect.h" … … 44 40 namespace WebCore { 45 41 46 Ref<DocumentTimeline> DocumentTimeline::create(Document& document , PlatformDisplayID displayID)47 { 48 return adoptRef(*new DocumentTimeline(document , displayID));49 } 50 51 DocumentTimeline::DocumentTimeline(Document& document , PlatformDisplayID displayID)42 Ref<DocumentTimeline> DocumentTimeline::create(Document& document) 43 { 44 return adoptRef(*new DocumentTimeline(document)); 45 } 46 47 DocumentTimeline::DocumentTimeline(Document& document) 52 48 : AnimationTimeline(DocumentTimelineClass) 53 49 , m_document(&document) … … 57 53 #endif 58 54 { 59 windowScreenDidChange(displayID);60 55 } 61 56 … … 219 214 { 220 215 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 221 DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this);216 m_document->animationScheduler().scheduleWebAnimationsResolution(); 222 217 #else 223 218 // FIXME: We need to use the same logic as ScriptedAnimationController here, … … 228 223 229 224 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 230 void DocumentTimeline::d isplayRefreshFired()225 void DocumentTimeline::documentAnimationSchedulerDidFire() 231 226 #else 232 227 void DocumentTimeline::animationResolutionTimerFired() … … 393 388 } 394 389 395 void DocumentTimeline::windowScreenDidChange(PlatformDisplayID displayID)396 {397 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)398 DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this);399 #else400 UNUSED_PARAM(displayID);401 #endif402 }403 404 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)405 RefPtr<DisplayRefreshMonitor> DocumentTimeline::createDisplayRefreshMonitor(PlatformDisplayID displayID) const406 {407 if (!m_document || !m_document->page())408 return nullptr;409 410 if (auto monitor = m_document->page()->chrome().client().createDisplayRefreshMonitor(displayID))411 return monitor;412 413 return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID);414 }415 #endif416 417 390 } // namespace WebCore -
trunk/Source/WebCore/animation/DocumentTimeline.h
r230581 r233140 28 28 #include "AnimationTimeline.h" 29 29 #include "GenericTaskQueue.h" 30 #include "PlatformScreen.h"31 30 #include "Timer.h" 32 31 #include <wtf/Ref.h> 33 34 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)35 #include "DisplayRefreshMonitorClient.h"36 #endif37 32 38 33 namespace WebCore { … … 42 37 43 38 class DocumentTimeline final : public AnimationTimeline 44 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)45 , public DisplayRefreshMonitorClient46 #endif47 39 { 48 40 public: 49 static Ref<DocumentTimeline> create(Document& , PlatformDisplayID);41 static Ref<DocumentTimeline> create(Document&); 50 42 ~DocumentTimeline(); 51 43 … … 56 48 57 49 void timingModelDidChange() override; 58 void windowScreenDidChange(PlatformDisplayID);59 50 60 51 // If possible, compute the visual extent of any transform animation on the given renderer … … 72 63 void enqueueAnimationPlaybackEvent(AnimationPlaybackEvent&); 73 64 65 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 66 void documentAnimationSchedulerDidFire(); 67 #endif 68 74 69 void updateThrottlingState(); 75 70 WEBCORE_EXPORT Seconds animationInterval() const; … … 80 75 81 76 private: 82 DocumentTimeline(Document& , PlatformDisplayID);77 DocumentTimeline(Document&); 83 78 84 79 void scheduleInvalidationTaskIfNeeded(); … … 101 96 Vector<Ref<AnimationPlaybackEvent>> m_pendingAnimationEvents; 102 97 103 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 104 // Override for DisplayRefreshMonitorClient 105 void displayRefreshFired() override; 106 RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const override; 107 #else 98 #if !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 108 99 void animationResolutionTimerFired(); 109 100 Timer m_animationResolutionTimer; -
trunk/Source/WebCore/dom/Document.cpp
r233122 r233140 57 57 #include "DateComponents.h" 58 58 #include "DebugPageOverlays.h" 59 #include "DocumentAnimationScheduler.h" 59 60 #include "DocumentLoader.h" 60 61 #include "DocumentMarkerController.h" … … 2444 2445 } 2445 2446 2447 if (m_animationScheduler) { 2448 m_animationScheduler->detachFromDocument(); 2449 m_animationScheduler = nullptr; 2450 } 2451 2446 2452 m_hasPreparedForDestruction = true; 2447 2453 … … 5920 5926 void Document::windowScreenDidChange(PlatformDisplayID displayID) 5921 5927 { 5922 if (m_scriptedAnimationController) 5923 m_scriptedAnimationController->windowScreenDidChange(displayID); 5924 5925 if (m_timeline) 5926 m_timeline->windowScreenDidChange(displayID); 5928 if (m_animationScheduler) 5929 m_animationScheduler->windowScreenDidChange(displayID); 5927 5930 5928 5931 if (RenderView* view = renderView()) { … … 6527 6530 { 6528 6531 if (!m_scriptedAnimationController) { 6529 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 6530 m_scriptedAnimationController = ScriptedAnimationController::create(*this, page() ? page()->chrome().displayID() : 0); 6531 #else 6532 m_scriptedAnimationController = ScriptedAnimationController::create(*this, 0); 6533 #endif 6532 m_scriptedAnimationController = ScriptedAnimationController::create(*this); 6533 6534 6534 // It's possible that the Page may have suspended scripted animations before 6535 6535 // we were created. We need to make sure that we don't start up the animation … … 7718 7718 } 7719 7719 7720 DocumentAnimationScheduler& Document::animationScheduler() 7721 { 7722 if (!m_animationScheduler) 7723 m_animationScheduler = DocumentAnimationScheduler::create(*this, page() ? page()->chrome().displayID() : 0); 7724 7725 return *m_animationScheduler; 7726 } 7727 7720 7728 DocumentTimeline& Document::timeline() 7721 7729 { 7722 7730 if (!m_timeline) 7723 m_timeline = DocumentTimeline::create(*this , page() ? page()->chrome().displayID() : 0);7731 m_timeline = DocumentTimeline::create(*this); 7724 7732 7725 7733 return *m_timeline; -
trunk/Source/WebCore/dom/Document.h
r233066 r233140 81 81 namespace WebCore { 82 82 83 class DocumentAnimationScheduler; 83 84 class ApplicationStateChangeListener; 84 85 class AXObjectCache; … … 1407 1408 WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing. 1408 1409 1410 DocumentAnimationScheduler& animationScheduler(); 1411 1409 1412 WEBCORE_EXPORT DocumentTimeline& timeline(); 1410 1413 DocumentTimeline* existingTimeline() const { return m_timeline.get(); } … … 1921 1924 bool m_grantStorageAccessOverride { false }; 1922 1925 1926 RefPtr<DocumentAnimationScheduler> m_animationScheduler; 1923 1927 RefPtr<DocumentTimeline> m_timeline; 1924 1928 DocumentIdentifier m_identifier; -
trunk/Source/WebCore/dom/ScriptedAnimationController.cpp
r233122 r233140 30 30 #include "ChromeClient.h" 31 31 #include "DOMWindow.h" 32 #include "DisplayRefreshMonitor.h"33 #include "DisplayRefreshMonitorManager.h"34 32 #include "Document.h" 33 #include "DocumentAnimationScheduler.h" 35 34 #include "DocumentLoader.h" 36 35 #include "Frame.h" … … 56 55 namespace WebCore { 57 56 58 ScriptedAnimationController::ScriptedAnimationController(Document& document , PlatformDisplayID displayID)57 ScriptedAnimationController::ScriptedAnimationController(Document& document) 59 58 : m_document(&document) 60 59 , m_animationTimer(*this, &ScriptedAnimationController::animationTimerFired) 61 60 { 62 windowScreenDidChange(displayID);63 61 } 64 62 … … 235 233 } 236 234 237 void ScriptedAnimationController::windowScreenDidChange(PlatformDisplayID displayID)238 {239 if (!requestAnimationFrameEnabled())240 return;241 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)242 DisplayRefreshMonitorManager::sharedManager().windowScreenDidChange(displayID, *this);243 #else244 UNUSED_PARAM(displayID);245 #endif246 }247 248 235 Seconds ScriptedAnimationController::interval() const 249 236 { … … 275 262 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 276 263 if (!m_isUsingTimer && !isThrottled()) { 277 if ( DisplayRefreshMonitorManager::sharedManager().scheduleAnimation(*this))264 if (m_document->animationScheduler().scheduleScriptedAnimationResolution()) 278 265 return; 279 266 … … 309 296 310 297 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 311 void ScriptedAnimationController::d isplayRefreshFired()298 void ScriptedAnimationController::documentAnimationSchedulerDidFire() 312 299 { 313 300 serviceScriptedAnimations(m_document->domWindow()->nowTimestamp()); 314 301 } 315 316 RefPtr<DisplayRefreshMonitor> ScriptedAnimationController::createDisplayRefreshMonitor(PlatformDisplayID displayID) const 317 { 318 if (!m_document->page()) 319 return nullptr; 320 321 if (auto monitor = m_document->page()->chrome().client().createDisplayRefreshMonitor(displayID)) 322 return monitor; 323 324 return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID); 325 } 326 #endif 327 328 } 302 #endif 303 304 } -
trunk/Source/WebCore/dom/ScriptedAnimationController.h
r224797 r233140 26 26 #pragma once 27 27 28 #include "PlatformScreen.h"29 28 #include "Timer.h" 30 29 #include <wtf/OptionSet.h> … … 32 31 #include <wtf/RefPtr.h> 33 32 #include <wtf/Vector.h> 34 35 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)36 #include "DisplayRefreshMonitorClient.h"37 #endif38 33 39 34 namespace WebCore { … … 44 39 45 40 class ScriptedAnimationController : public RefCounted<ScriptedAnimationController> 46 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)47 , public DisplayRefreshMonitorClient48 #endif49 41 { 50 42 public: 51 static Ref<ScriptedAnimationController> create(Document& document , PlatformDisplayID displayID)43 static Ref<ScriptedAnimationController> create(Document& document) 52 44 { 53 return adoptRef(*new ScriptedAnimationController(document , displayID));45 return adoptRef(*new ScriptedAnimationController(document)); 54 46 } 55 47 ~ScriptedAnimationController(); … … 78 70 WEBCORE_EXPORT Seconds interval() const; 79 71 80 void windowScreenDidChange(PlatformDisplayID); 72 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 73 void documentAnimationSchedulerDidFire(); 74 #endif 81 75 82 76 private: 83 ScriptedAnimationController(Document& , PlatformDisplayID);77 ScriptedAnimationController(Document&); 84 78 85 79 void scheduleAnimation(); 86 80 void animationTimerFired(); 87 88 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)89 // Override for DisplayRefreshMonitorClient90 void displayRefreshFired() override;91 #endif92 81 93 82 Page* page() const; … … 104 93 105 94 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 106 RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const override;107 95 OptionSet<ThrottlingReason> m_throttlingReasons; 108 96 bool m_isUsingTimer { false };
Note: See TracChangeset
for help on using the changeset viewer.