Changeset 230581 in webkit
- Timestamp:
- Apr 12, 2018 10:37:55 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r230579 r230581 1 2018-04-12 Antoine Quint <graouts@apple.com> 2 3 [Web Animations] Suspend animations when required 4 https://bugs.webkit.org/show_bug.cgi?id=184541 5 6 Reviewed by Jon Lee. 7 8 Mark more tests as passing when the CSS Animations and CSS Transitions as Web Animations flag is on. 9 10 * animations/animation-controller-drt-api.html: 11 * animations/animation-followed-by-transition.html: 12 * fast/animation/css-animation-resuming-when-visible-with-style-change.html: 13 * fast/animation/css-animation-resuming-when-visible.html: 14 1 15 2018-04-12 Antoine Quint <graouts@apple.com> 2 16 -
trunk/LayoutTests/animations/added-while-suspended.html
r180441 r230581 1 <!DOCTYPE html> 1 2 <title>Test that new animations do not run while we are suspended</title> 2 3 <style> -
trunk/LayoutTests/animations/animation-controller-drt-api.html
r141849 r230581 1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 2 "http://www.w3.org/TR/html4/loose.dtd"> 1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 3 2 4 3 <html lang="en"> -
trunk/LayoutTests/animations/animation-followed-by-transition.html
r209675 r230581 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 <html> 3 3 <head> -
trunk/LayoutTests/fast/animation/css-animation-resuming-when-visible-with-style-change.html
r218257 r230581 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 <html> 3 3 <head> -
trunk/LayoutTests/fast/animation/css-animation-resuming-when-visible.html
r217997 r230581 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 <html> 3 3 <head> -
trunk/LayoutTests/transitions/created-while-suspended.html
r218277 r230581 1 <!DOCTYPE html> 1 2 <title>Test that newly created transitions do not run while we are suspended</title> 2 3 <style> -
trunk/Source/WebCore/ChangeLog
r230579 r230581 1 2018-04-12 Antoine Quint <graouts@apple.com> 2 3 [Web Animations] Suspend animations when required 4 https://bugs.webkit.org/show_bug.cgi?id=184541 5 6 Reviewed by Jon Lee. 7 8 Animations managed by CSSAnimationController get suspended under a number of scenarios, we now add the possibility 9 to suspend animations on a DocumentTimeline as well such that Web Animations and CSS Animations and CSS Transitions 10 implemented as Web Animations get suspended under the same conditions as well. We also update the implementation for 11 Internals::numberOfActiveAnimations() such that tests checking that animations get suspended pass. 12 13 * animation/DocumentTimeline.cpp: 14 (WebCore::DocumentTimeline::suspendAnimations): When asked to be suspended, the DocumentTimeline cancels pending 15 invalidation tasks and updates all of the animations it manages, including those running on the compositor. 16 (WebCore::DocumentTimeline::resumeAnimations): When asked to be resumed, the DocumentTimeline resumes animations 17 it manages and rewinds its invalidation timer. 18 (WebCore::DocumentTimeline::animationsAreSuspended): 19 (WebCore::DocumentTimeline::numberOfActiveAnimationsForTesting const): Called by Internals::numberOfActiveAnimations(), 20 this returns the number of animations managed by this timeline that are not suspended. 21 (WebCore::DocumentTimeline::currentTime): 22 (WebCore::DocumentTimeline::timingModelDidChange): Ensure the invalidation timer is not rewound if the timeline 23 is suspended. 24 * animation/DocumentTimeline.h: 25 * animation/WebAnimation.cpp: 26 (WebCore::WebAnimation::setTimeline): When moving to a new timeline, ensure we match the new timeline's animation state. 27 (WebCore::WebAnimation::setSuspended): Toggle the accelerated running state of any backing hardware animations when 28 the suspension state of an animation changes. 29 * animation/WebAnimation.h: 30 (WebCore::WebAnimation::isSuspended const): 31 * dom/Document.cpp: 32 (WebCore::Document::didBecomeCurrentDocumentInFrame): 33 (WebCore::Document::resume): 34 * dom/Document.h: 35 * history/CachedFrame.cpp: 36 (WebCore::CachedFrameBase::restore): 37 * page/Frame.cpp: 38 (WebCore::Frame::clearTimers): 39 * page/Page.cpp: 40 (WebCore::Page::setIsVisibleInternal): 41 (WebCore::Page::hiddenPageCSSAnimationSuspensionStateChanged): 42 * testing/Internals.cpp: 43 (WebCore::Internals::numberOfActiveAnimations const): 44 (WebCore::Internals::animationsAreSuspended const): 45 (WebCore::Internals::suspendAnimations const): 46 (WebCore::Internals::resumeAnimations const): 47 1 48 2018-04-12 Antoine Quint <graouts@apple.com> 2 49 -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r230579 r230581 84 84 } 85 85 86 void DocumentTimeline::suspendAnimations() 87 { 88 if (animationsAreSuspended()) 89 return; 90 91 m_isSuspended = true; 92 93 m_invalidationTaskQueue.cancelAllTasks(); 94 if (m_animationScheduleTimer.isActive()) 95 m_animationScheduleTimer.stop(); 96 97 for (const auto& animation : animations()) 98 animation->setSuspended(true); 99 100 applyPendingAcceleratedAnimations(); 101 } 102 103 void DocumentTimeline::resumeAnimations() 104 { 105 if (!animationsAreSuspended()) 106 return; 107 108 m_isSuspended = false; 109 110 for (const auto& animation : animations()) 111 animation->setSuspended(false); 112 113 m_needsUpdateAnimationSchedule = false; 114 timingModelDidChange(); 115 } 116 117 bool DocumentTimeline::animationsAreSuspended() 118 { 119 return m_isSuspended; 120 } 121 122 unsigned DocumentTimeline::numberOfActiveAnimationsForTesting() const 123 { 124 unsigned count = 0; 125 for (const auto& animation : animations()) { 126 if (!animation->isSuspended()) 127 ++count; 128 } 129 return count; 130 } 131 86 132 std::optional<Seconds> DocumentTimeline::currentTime() 87 133 { 88 if (m_paused || !m_document || !m_document->domWindow())134 if (m_paused || m_isSuspended || !m_document || !m_document->domWindow()) 89 135 return AnimationTimeline::currentTime(); 90 136 … … 103 149 void DocumentTimeline::timingModelDidChange() 104 150 { 105 if (m_needsUpdateAnimationSchedule )151 if (m_needsUpdateAnimationSchedule || m_isSuspended) 106 152 return; 107 153 -
trunk/Source/WebCore/animation/DocumentTimeline.h
r230579 r230581 74 74 void updateThrottlingState(); 75 75 WEBCORE_EXPORT Seconds animationInterval() const; 76 WEBCORE_EXPORT void suspendAnimations(); 77 WEBCORE_EXPORT void resumeAnimations(); 78 WEBCORE_EXPORT bool animationsAreSuspended(); 79 WEBCORE_EXPORT unsigned numberOfActiveAnimationsForTesting() const; 76 80 77 81 private: … … 88 92 RefPtr<Document> m_document; 89 93 bool m_paused { false }; 94 bool m_isSuspended { false }; 90 95 std::optional<Seconds> m_cachedCurrentTime; 91 96 GenericTaskQueue<Timer> m_invalidationTaskQueue; -
trunk/Source/WebCore/animation/WebAnimation.cpp
r230574 r230581 177 177 178 178 m_timeline = WTFMove(timeline); 179 180 setSuspended(is<DocumentTimeline>(m_timeline) && downcast<DocumentTimeline>(*m_timeline).animationsAreSuspended()); 179 181 180 182 updatePendingTasks(); … … 1018 1020 } 1019 1021 1022 void WebAnimation::setSuspended(bool isSuspended) 1023 { 1024 if (m_isSuspended == isSuspended) 1025 return; 1026 1027 m_isSuspended = isSuspended; 1028 1029 if (!is<KeyframeEffectReadOnly>(m_effect)) 1030 return; 1031 1032 auto& keyframeEffect = downcast<KeyframeEffectReadOnly>(*m_effect); 1033 if (keyframeEffect.isRunningAccelerated() && playState() == PlayState::Running) 1034 keyframeEffect.animationPlayStateDidChange(isSuspended ? PlayState::Paused : PlayState::Running); 1035 } 1036 1020 1037 void WebAnimation::acceleratedStateDidChange() 1021 1038 { -
trunk/Source/WebCore/animation/WebAnimation.h
r230574 r230581 107 107 void suspendEffectInvalidation(); 108 108 void unsuspendEffectInvalidation(); 109 void setSuspended(bool); 110 bool isSuspended() const { return m_isSuspended; } 109 111 110 112 String description(); … … 155 157 double m_playbackRate { 1 }; 156 158 bool m_isStopped { false }; 159 bool m_isSuspended { false }; 157 160 bool m_finishNotificationStepsMicrotaskPending; 158 161 bool m_scheduledMicrotask; -
trunk/Source/WebCore/dom/Document.cpp
r230368 r230581 2260 2260 // page cache, or simply newly created). 2261 2261 if (m_frame->activeDOMObjectsAndAnimationsSuspended()) { 2262 m_frame->animation().suspendAnimationsForDocument(this); 2262 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 2263 timeline().suspendAnimations(); 2264 else 2265 m_frame->animation().suspendAnimationsForDocument(this); 2263 2266 suspendScheduledTasks(ActiveDOMObject::PageWillBeSuspended); 2264 2267 } else { 2265 2268 resumeScheduledTasks(ActiveDOMObject::PageWillBeSuspended); 2266 m_frame->animation().resumeAnimationsForDocument(this); 2269 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 2270 timeline().resumeAnimations(); 2271 else 2272 m_frame->animation().resumeAnimationsForDocument(this); 2267 2273 } 2268 2274 } … … 4924 4930 ASSERT(m_frame); 4925 4931 m_frame->loader().client().dispatchDidBecomeFrameset(isFrameSet()); 4926 m_frame->animation().resumeAnimationsForDocument(this); 4932 4933 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 4934 timeline().resumeAnimations(); 4935 else 4936 m_frame->animation().resumeAnimationsForDocument(this); 4927 4937 4928 4938 resumeScheduledTasks(reason); -
trunk/Source/WebCore/dom/Document.h
r230368 r230581 1393 1393 WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing. 1394 1394 1395 DocumentTimeline& timeline();1395 WEBCORE_EXPORT DocumentTimeline& timeline(); 1396 1396 DocumentTimeline* existingTimeline() const { return m_timeline.get(); } 1397 1397 Vector<RefPtr<WebAnimation>> getAnimations(); -
trunk/Source/WebCore/history/CachedFrame.cpp
r230211 r230581 33 33 #include "Document.h" 34 34 #include "DocumentLoader.h" 35 #include "DocumentTimeline.h" 35 36 #include "Frame.h" 36 37 #include "FrameLoader.h" … … 40 41 #include "Page.h" 41 42 #include "PageCache.h" 43 #include "RuntimeEnabledFeatures.h" 42 44 #include "SVGDocumentExtensions.h" 43 45 #include "ScriptController.h" … … 97 99 m_document->accessSVGExtensions().unpauseAnimations(); 98 100 99 frame.animation().resumeAnimationsForDocument(m_document.get()); 101 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 102 m_document->timeline().resumeAnimations(); 103 else 104 frame.animation().resumeAnimationsForDocument(m_document.get()); 100 105 101 106 m_document->resume(ActiveDOMObject::PageCache); -
trunk/Source/WebCore/page/Frame.cpp
r230211 r230581 41 41 #include "ChromeClient.h" 42 42 #include "DOMWindow.h" 43 #include "DocumentTimeline.h" 43 44 #include "DocumentType.h" 44 45 #include "Editing.h" … … 778 779 if (view) { 779 780 view->layoutContext().unscheduleLayout(); 780 view->frame().animation().suspendAnimationsForDocument(document); 781 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 782 document->timeline().suspendAnimations(); 783 else 784 view->frame().animation().suspendAnimationsForDocument(document); 781 785 view->frame().eventHandler().stopAutoscrollTimer(); 782 786 } -
trunk/Source/WebCore/page/Page.cpp
r230579 r230581 1638 1638 view->show(); 1639 1639 1640 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) 1641 mainFrame().animation().resumeAnimations(); 1640 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) { 1641 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 1642 forEachDocument([&] (Document& document) { 1643 document.timeline().resumeAnimations(); 1644 }); 1645 } else 1646 mainFrame().animation().resumeAnimations(); 1647 } 1642 1648 1643 1649 setSVGAnimationsState(*this, SVGAnimationsState::Resumed); … … 1652 1658 1653 1659 if (!isVisible) { 1654 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) 1655 mainFrame().animation().suspendAnimations(); 1660 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) { 1661 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 1662 forEachDocument([&] (Document& document) { 1663 document.timeline().suspendAnimations(); 1664 }); 1665 } else 1666 mainFrame().animation().suspendAnimations(); 1667 } 1656 1668 1657 1669 setSVGAnimationsState(*this, SVGAnimationsState::Paused); … … 1999 2011 { 2000 2012 if (!isVisible()) { 2001 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) 2002 mainFrame().animation().suspendAnimations(); 2003 else 2004 mainFrame().animation().resumeAnimations(); 2013 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 2014 forEachDocument([&] (Document& document) { 2015 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) 2016 document.timeline().suspendAnimations(); 2017 else 2018 document.timeline().resumeAnimations(); 2019 }); 2020 } else { 2021 if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) 2022 mainFrame().animation().suspendAnimations(); 2023 else 2024 mainFrame().animation().resumeAnimations(); 2025 } 2005 2026 } 2006 2027 } -
trunk/Source/WebCore/testing/Internals.cpp
r230579 r230581 916 916 unsigned Internals::numberOfActiveAnimations() const 917 917 { 918 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 919 return frame()->document()->timeline().numberOfActiveAnimationsForTesting(); 918 920 return frame()->animation().numberOfActiveAnimations(frame()->document()); 919 921 } … … 925 927 return Exception { InvalidAccessError }; 926 928 929 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) 930 return document->timeline().animationsAreSuspended(); 927 931 return document->frame()->animation().animationsAreSuspendedForDocument(document); 928 932 } … … 951 955 return Exception { InvalidAccessError }; 952 956 953 document->frame()->animation().suspendAnimationsForDocument(document); 954 955 for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) { 956 if (Document* document = frame->document()) 957 frame->animation().suspendAnimationsForDocument(document); 957 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 958 document->timeline().suspendAnimations(); 959 for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) { 960 if (Document* document = frame->document()) 961 document->timeline().suspendAnimations(); 962 } 963 } else { 964 document->frame()->animation().suspendAnimationsForDocument(document); 965 966 for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) { 967 if (Document* document = frame->document()) 968 frame->animation().suspendAnimationsForDocument(document); 969 } 958 970 } 959 971 … … 967 979 return Exception { InvalidAccessError }; 968 980 969 document->frame()->animation().resumeAnimationsForDocument(document); 970 971 for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) { 972 if (Document* document = frame->document()) 973 frame->animation().resumeAnimationsForDocument(document); 981 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 982 document->timeline().resumeAnimations(); 983 for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) { 984 if (Document* document = frame->document()) 985 document->timeline().resumeAnimations(); 986 } 987 } else { 988 document->frame()->animation().resumeAnimationsForDocument(document); 989 990 for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) { 991 if (Document* document = frame->document()) 992 frame->animation().resumeAnimationsForDocument(document); 993 } 974 994 } 975 995
Note: See TracChangeset
for help on using the changeset viewer.