haikuwebkit/Source/WebCore/animation/DocumentTimeline.h

111 lines
4.6 KiB
C
Raw Permalink Normal View History

[Web Animations] Provide basic timeline and animation interfaces https://bugs.webkit.org/show_bug.cgi?id=178526 Patch by Antoine Quint <graouts@apple.com> on 2017-10-20 Reviewed by Dean Jackson. .: Remove the WEB_ANIMATIONS compile-time flag. * Source/cmake/OptionsWPE.cmake: * Source/cmake/OptionsWin.cmake: * Source/cmake/WebKitFeatures.cmake: * Source/cmake/tools/vsprops/FeatureDefines.props: * Source/cmake/tools/vsprops/FeatureDefinesCairo.props: Source/JavaScriptCore: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebCore: We're getting Web Animations work started by implementing a very minimal codebase which provides a DocumentTimeline class which has an instance created for each Document. The parent class, AnimationTimeline, allows for animations to be added and removed, and animations can be created using the Animation class, with an optional timeline as parameter. Tests: webanimations/animation-creation-basic.html webanimations/document-timeline.html * CMakeLists.txt: * Configurations/FeatureDefines.xcconfig: * DerivedSources.make: * PlatformWin.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: Added. (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::~AnimationTimeline): (WebCore::AnimationTimeline::addAnimation): (WebCore::AnimationTimeline::removeAnimation): * animation/AnimationTimeline.h: Added. (WebCore::AnimationTimeline::isDocumentTimeline const): (WebCore::AnimationTimeline::classType const): * animation/AnimationTimeline.idl: Added. * animation/DocumentTimeline.cpp: Added. (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: Added. * animation/DocumentTimeline.idl: Added. * animation/WebAnimation.cpp: Added. (WebCore::WebAnimation::create): (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::~WebAnimation): * animation/WebAnimation.h: Added. * animation/WebAnimation.idl: Added. * bindings/js/JSAnimationTimelineCustom.cpp: Added. (WebCore::toJSNewlyCreated): (WebCore::toJS): * bindings/js/WebCoreBuiltinNames.h: * dom/Document.cpp: (WebCore::Document::timeline): * dom/Document.h: * dom/Document.idl: * page/RuntimeEnabledFeatures.h: (WebCore::RuntimeEnabledFeatures::webAnimationsEnabled const): Source/WebCore/PAL: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebKit: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebProcess/InjectedBundle/InjectedBundle.cpp: (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): (WebKit::InjectedBundle::setWebAnimationsEnabled): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updatePreferences): Source/WebKitLegacy/mac: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Source/WebKitLegacy/win: Remove the WEB_ANIMATIONS compile-time flag. * WebView.cpp: (WebView::notifyPreferencesChanged): Source/WTF: Remove the WEB_ANIMATIONS compile-time flag. * wtf/FeatureDefines.h: Tools: Remove the WEB_ANIMATIONS compile-time flag. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: Basic test coverage to check that we are exposing a DocumentTimeline instance on the Document and that we can construct Animations, optionally associated with a timeline. * platform/mac-elcapitan/TestExpectations: * webanimations/animation-creation-basic-expected.txt: Added. * webanimations/animation-creation-basic.html: Added. * webanimations/document-timeline-expected.txt: Added. * webanimations/document-timeline.html: Added. Canonical link: https://commits.webkit.org/194785@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 18:41:23 +00:00
/*
* Copyright (C) 2017 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
#include "AnimationTimeline.h"
#include "DocumentTimelineOptions.h"
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
#include "Timer.h"
[Web Animations] Provide basic timeline and animation interfaces https://bugs.webkit.org/show_bug.cgi?id=178526 Patch by Antoine Quint <graouts@apple.com> on 2017-10-20 Reviewed by Dean Jackson. .: Remove the WEB_ANIMATIONS compile-time flag. * Source/cmake/OptionsWPE.cmake: * Source/cmake/OptionsWin.cmake: * Source/cmake/WebKitFeatures.cmake: * Source/cmake/tools/vsprops/FeatureDefines.props: * Source/cmake/tools/vsprops/FeatureDefinesCairo.props: Source/JavaScriptCore: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebCore: We're getting Web Animations work started by implementing a very minimal codebase which provides a DocumentTimeline class which has an instance created for each Document. The parent class, AnimationTimeline, allows for animations to be added and removed, and animations can be created using the Animation class, with an optional timeline as parameter. Tests: webanimations/animation-creation-basic.html webanimations/document-timeline.html * CMakeLists.txt: * Configurations/FeatureDefines.xcconfig: * DerivedSources.make: * PlatformWin.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: Added. (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::~AnimationTimeline): (WebCore::AnimationTimeline::addAnimation): (WebCore::AnimationTimeline::removeAnimation): * animation/AnimationTimeline.h: Added. (WebCore::AnimationTimeline::isDocumentTimeline const): (WebCore::AnimationTimeline::classType const): * animation/AnimationTimeline.idl: Added. * animation/DocumentTimeline.cpp: Added. (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: Added. * animation/DocumentTimeline.idl: Added. * animation/WebAnimation.cpp: Added. (WebCore::WebAnimation::create): (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::~WebAnimation): * animation/WebAnimation.h: Added. * animation/WebAnimation.idl: Added. * bindings/js/JSAnimationTimelineCustom.cpp: Added. (WebCore::toJSNewlyCreated): (WebCore::toJS): * bindings/js/WebCoreBuiltinNames.h: * dom/Document.cpp: (WebCore::Document::timeline): * dom/Document.h: * dom/Document.idl: * page/RuntimeEnabledFeatures.h: (WebCore::RuntimeEnabledFeatures::webAnimationsEnabled const): Source/WebCore/PAL: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebKit: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebProcess/InjectedBundle/InjectedBundle.cpp: (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): (WebKit::InjectedBundle::setWebAnimationsEnabled): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updatePreferences): Source/WebKitLegacy/mac: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Source/WebKitLegacy/win: Remove the WEB_ANIMATIONS compile-time flag. * WebView.cpp: (WebView::notifyPreferencesChanged): Source/WTF: Remove the WEB_ANIMATIONS compile-time flag. * wtf/FeatureDefines.h: Tools: Remove the WEB_ANIMATIONS compile-time flag. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: Basic test coverage to check that we are exposing a DocumentTimeline instance on the Document and that we can construct Animations, optionally associated with a timeline. * platform/mac-elcapitan/TestExpectations: * webanimations/animation-creation-basic-expected.txt: Added. * webanimations/animation-creation-basic.html: Added. * webanimations/document-timeline-expected.txt: Added. * webanimations/document-timeline.html: Added. Canonical link: https://commits.webkit.org/194785@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 18:41:23 +00:00
#include <wtf/Ref.h>
#include <wtf/WeakPtr.h>
[Web Animations] Provide basic timeline and animation interfaces https://bugs.webkit.org/show_bug.cgi?id=178526 Patch by Antoine Quint <graouts@apple.com> on 2017-10-20 Reviewed by Dean Jackson. .: Remove the WEB_ANIMATIONS compile-time flag. * Source/cmake/OptionsWPE.cmake: * Source/cmake/OptionsWin.cmake: * Source/cmake/WebKitFeatures.cmake: * Source/cmake/tools/vsprops/FeatureDefines.props: * Source/cmake/tools/vsprops/FeatureDefinesCairo.props: Source/JavaScriptCore: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebCore: We're getting Web Animations work started by implementing a very minimal codebase which provides a DocumentTimeline class which has an instance created for each Document. The parent class, AnimationTimeline, allows for animations to be added and removed, and animations can be created using the Animation class, with an optional timeline as parameter. Tests: webanimations/animation-creation-basic.html webanimations/document-timeline.html * CMakeLists.txt: * Configurations/FeatureDefines.xcconfig: * DerivedSources.make: * PlatformWin.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: Added. (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::~AnimationTimeline): (WebCore::AnimationTimeline::addAnimation): (WebCore::AnimationTimeline::removeAnimation): * animation/AnimationTimeline.h: Added. (WebCore::AnimationTimeline::isDocumentTimeline const): (WebCore::AnimationTimeline::classType const): * animation/AnimationTimeline.idl: Added. * animation/DocumentTimeline.cpp: Added. (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: Added. * animation/DocumentTimeline.idl: Added. * animation/WebAnimation.cpp: Added. (WebCore::WebAnimation::create): (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::~WebAnimation): * animation/WebAnimation.h: Added. * animation/WebAnimation.idl: Added. * bindings/js/JSAnimationTimelineCustom.cpp: Added. (WebCore::toJSNewlyCreated): (WebCore::toJS): * bindings/js/WebCoreBuiltinNames.h: * dom/Document.cpp: (WebCore::Document::timeline): * dom/Document.h: * dom/Document.idl: * page/RuntimeEnabledFeatures.h: (WebCore::RuntimeEnabledFeatures::webAnimationsEnabled const): Source/WebCore/PAL: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebKit: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebProcess/InjectedBundle/InjectedBundle.cpp: (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): (WebKit::InjectedBundle::setWebAnimationsEnabled): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updatePreferences): Source/WebKitLegacy/mac: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Source/WebKitLegacy/win: Remove the WEB_ANIMATIONS compile-time flag. * WebView.cpp: (WebView::notifyPreferencesChanged): Source/WTF: Remove the WEB_ANIMATIONS compile-time flag. * wtf/FeatureDefines.h: Tools: Remove the WEB_ANIMATIONS compile-time flag. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: Basic test coverage to check that we are exposing a DocumentTimeline instance on the Document and that we can construct Animations, optionally associated with a timeline. * platform/mac-elcapitan/TestExpectations: * webanimations/animation-creation-basic-expected.txt: Added. * webanimations/animation-creation-basic.html: Added. * webanimations/document-timeline-expected.txt: Added. * webanimations/document-timeline.html: Added. Canonical link: https://commits.webkit.org/194785@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 18:41:23 +00:00
namespace WebCore {
[Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline https://bugs.webkit.org/show_bug.cgi?id=207364 <rdar://problem/59370413> Reviewed by Simon Fraser. LayoutTests/imported/w3c: There are some progressions but also some "regressions". The progressions are real, showing the delivery of all animation events at the correct time. However, the regressions are misleading. The fact that the "style change" tests would work was due to a design issue in the test which would only wait one frame to detect whether a CSS Transition was started after a change made through the Web Animations API. These would work because events were queued in the next frame, but delivered later due to the dedicated per-animation queue used, which meant the test was fooled into thinking the CSS Transition did not start, as expected. Changing those test to use more than one frame to test for the lack of a CSS Transition would have shown the FAIL results. However, in order to not regress our WPT score, the issue of "style change" events will be addressed in a follow-up patch. * web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt: * web-platform-tests/web-animations/interfaces/Animatable/animate-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt: * web-platform-tests/web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt: * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: Until now, AnimationPlaybackEvent events, which are new events introduced by the Web Animations spec, were enqueued in a shared queue on the DocumentTimeline and dispatched during the "update animations and send events" procedure. However, AnimationEvent and TransitionEvent events, dispatched by CSS Animations and CSS Transitions, were dispatched via a dedicated per-animation queue, which meant typically that those events were dispathed one runloop after the AnimationPlaybackEvent events. We now remove the dedicated per-animation queue and enqueue all events in the shared DocumentTimeline queue for dispatch during the "update animations and send events" procedure. To do this correctly, we need to do a couple of other things that ensure we don't regress tests. First, we update the DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() to account for whether there are pending animation events, guaranteeing that an animation update is scheduled should there be any. Second, when animation events are enqueued in DocumentTimeline::enqueueAnimationEvent() we schedule an animation update if needed, since we know we now have pending events that will need to be delivered in an upcoming update. We also maintain a flag between the start of the "update animations and send events" procedure and the moment when the pending animation events queue is cleared prior to dispatching events so that events enqueued in the meantime do not prematurely schedule animation resolution. The need for a new animation resolution will be checked at the end of the procedure. Finally, declarative animations used to have a special suclass of WebAnimation::needsTick() that would check whether they had any pending events, ensuring they would not be removed prematurely. We now reset a flag to false as WebAnimation::tick() is called (as part of the "update animations and send events" procedure) and set it to true in case an animation is enqueued. This flag is then used in needsTick() to guarantee the animation is not removed before the DocumentTimeline has had a chance to dispatch the enqueued event. Note also that, for clarity, the DocumentTimeline::unscheduleAnimationResolution() was renamed to DocumentTimeline::clearTickScheduleTimer() since it wouldn't actually cancel a previous animation resolution schedule. * animation/CSSTransition.h: Fix a newly found build error due to the missing wtf/MonotonicTime.h header. * animation/DeclarativeAnimation.cpp: Remove all code related to the dedicated per-animation queue and instead call the new WebAnimation::enqueueAnimationEvent() method to enqueue events on the DocumentTimeline. (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::tick): (WebCore::DeclarativeAnimation::enqueueDOMEvent): * animation/DeclarativeAnimation.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): Ensure the pending events queue is cleared when the timeline is detached from a document, ensuring that there no longer events that would cause a ref-cycle (DocumentTimeline -> AnimationPlaybackEvent -> WebAnimation -> DocumentTimeline). (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::removeAnimation): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::clearTickScheduleTimer): (WebCore::DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState const): (WebCore::DocumentTimeline::updateCurrentTime): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): (WebCore::DocumentTimeline::enqueueAnimationEvent): * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::enqueueAnimationPlaybackEvent): (WebCore::WebAnimation::enqueueAnimationEvent): (WebCore::WebAnimation::needsTick const): (WebCore::WebAnimation::tick): * animation/WebAnimation.h: LayoutTests: Fix a couple of tests that made some incorrect assumptions. * TestExpectations: imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is no longer flaky. * compositing/backing/animate-into-view.html: Because the "animationstart" event is now dispatched during the "update animations and send events" procedure, which happens during page rendering _before_ rAF callbacks are serviced, we must remove the rAF callback used prior to adding the "animationstart" event listener or else we would never get it and the test would time out. * webanimations/css-transition-in-flight-reversal-accelerated.html: We must wait for the initial transition to start and then two frames before reversing the transition, to be certain that the animation did start. Indeed, the "transitionstart" event will be fired right before the next rAF callback is called, as the animation starts in that very same frame, and so progress will be 0 and the transition wouldn't be reversable until the next frame when the animation has progress > 0. Canonical link: https://commits.webkit.org/220724@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@256619 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-14 17:52:07 +00:00
class AnimationEventBase;
[Web Animations] Add a supporting object for Document to manage timelines https://bugs.webkit.org/show_bug.cgi?id=210817 Reviewed by Dean Jackson. Add a new DocumentTimelinesController object owned by Document to manage DocumentTimelines created for it. This simple piece of refactoring is the first step towards a coordinated "update animations and send events" procedure where all timelines are updated at once with a single microtask checkpoint instead of each timeline running one. No change in behavior, so no new tests. * Headers.cmake: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::~DocumentTimeline): (WebCore::DocumentTimeline::controller const): (WebCore::DocumentTimeline::detachFromDocument): * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: Added. (WebCore::DocumentTimelinesController::DocumentTimelinesController): (WebCore::DocumentTimelinesController::~DocumentTimelinesController): (WebCore::DocumentTimelinesController::addTimeline): (WebCore::DocumentTimelinesController::removeTimeline): (WebCore::DocumentTimelinesController::detachFromDocument): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): * animation/DocumentTimelinesController.h: Added. * dom/Document.cpp: (WebCore::Document::commonTeardown): (WebCore::Document::ensureTimelinesController): (WebCore::Document::updateAnimationsAndSendEvents): Deleted. (WebCore::Document::addTimeline): Deleted. (WebCore::Document::removeTimeline): Deleted. * dom/Document.h: (WebCore::Document::timelinesController const): * page/Page.cpp: (WebCore::Page::updateRendering): Canonical link: https://commits.webkit.org/223739@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260504 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 07:16:51 +00:00
class DocumentTimelinesController;
Reduce the reliance on PseudoElement in the animation code https://bugs.webkit.org/show_bug.cgi?id=216931 LayoutTests/imported/w3c: Reviewed by Antti Koivisto. Mark a WPT test progression. * web-platform-tests/css/css-transitions/non-rendered-element-002-expected.txt: Source/WebCore: <rdar://problem/69511682> Reviewed by Antti Koivisto. We have so far relied on PseudoElement as a foundation for supporting animations of pseudo-elements. This is not a great choice since PseudoElement is currently limited to ::before and ::after pseudo-elements only. This patch refactors animation-related code to rely on PseudoElement as little as possible without making changes outside of the animation code, as a first step towards supporting animation of more pseudo-elements. This patch introduces a new struct Styleable which combines an Element& and PseudoId. We use this struct instead of Element objects wherever necessary in the animation code. On top of that, we add a PseudoId parameter to all the Element methods wrapping access to ElementAnimationRareData and use a HashMap<PseudoId, std::unique_ptr<ElementAnimationRareData>> to be able to separate animation data per pseudo-element. * Headers.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::removeAnimation): (WebCore::AnimationTimeline::animationWasAddedToStyleable): (WebCore::AnimationTimeline::animationWasRemovedFromStyleable): (WebCore::AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement): (WebCore::AnimationTimeline::removeCSSAnimationCreatedByMarkup): (WebCore::AnimationTimeline::elementWasRemoved): (WebCore::AnimationTimeline::willChangeRendererForStyleable): (WebCore::AnimationTimeline::cancelDeclarativeAnimationsForStyleable): (WebCore::shouldConsiderAnimation): (WebCore::AnimationTimeline::updateCSSAnimationsForStyleable): (WebCore::keyframeEffectForElementAndProperty): (WebCore::AnimationTimeline::updateCSSTransitionsForStyleableAndProperty): (WebCore::AnimationTimeline::updateCSSTransitionsForStyleable): (WebCore::AnimationTimeline::animationWasAddedToElement): Deleted. (WebCore::AnimationTimeline::animationWasRemovedFromElement): Deleted. (WebCore::AnimationTimeline::willChangeRendererForElement): Deleted. (WebCore::AnimationTimeline::cancelDeclarativeAnimationsForElement): Deleted. (WebCore::AnimationTimeline::updateCSSAnimationsForElement): Deleted. (WebCore::AnimationTimeline::updateCSSTransitionsForElementAndProperty): Deleted. (WebCore::AnimationTimeline::updateCSSTransitionsForElement): Deleted. * animation/AnimationTimeline.h: * animation/CSSAnimation.cpp: (WebCore::CSSAnimation::create): (WebCore::CSSAnimation::CSSAnimation): * animation/CSSAnimation.h: * animation/CSSTransition.cpp: (WebCore::CSSTransition::create): (WebCore::CSSTransition::CSSTransition): * animation/CSSTransition.h: * animation/DeclarativeAnimation.cpp: (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::owningElement const): (WebCore::DeclarativeAnimation::disassociateFromOwningElement): (WebCore::DeclarativeAnimation::initialize): (WebCore::DeclarativeAnimation::enqueueDOMEvent): * animation/DeclarativeAnimation.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::animationCanBeRemoved): (WebCore::DocumentTimeline::transitionDidComplete): (WebCore::DocumentTimeline::computeExtentOfAnimation const): (WebCore::DocumentTimeline::isRunningAnimationOnRenderer const): (WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const): (WebCore::DocumentTimeline::animatedStyleForRenderer): (WebCore::DocumentTimeline::runningAnimationsForRendererAreAllAccelerated const): (WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Deleted. * animation/DocumentTimeline.h: * animation/ElementAnimationRareData.cpp: (WebCore::ElementAnimationRareData::ElementAnimationRareData): * animation/ElementAnimationRareData.h: (WebCore::ElementAnimationRareData::pseudoId const): * animation/KeyframeEffect.cpp: (WebCore::elementOrPseudoElementForStyleable): (WebCore::invalidateElement): (WebCore::KeyframeEffect::animationTimelineDidChange): (WebCore::KeyframeEffect::updateEffectStackMembership): (WebCore::KeyframeEffect::targetStyleable const): (WebCore::KeyframeEffect::setTarget): (WebCore::KeyframeEffect::setPseudoElement): (WebCore::KeyframeEffect::didChangeTargetStyleable): (WebCore::KeyframeEffect::invalidate): (WebCore::KeyframeEffect::applyPendingAcceleratedActions): (WebCore::KeyframeEffect::didChangeTargetElementOrPseudoElement): Deleted. * animation/KeyframeEffect.h: * animation/KeyframeEffectStack.cpp: (WebCore::KeyframeEffectStack::addEffect): * animation/WebAnimation.cpp: (WebCore::WebAnimation::setEffectInternal): (WebCore::WebAnimation::setTimeline): (WebCore::WebAnimation::effectTargetDidChange): (WebCore::WebAnimation::persist): (WebCore::WebAnimation::commitStyles): * animation/WebAnimation.h: * animation/WebAnimationUtilities.cpp: (WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder): (WebCore::compareCSSTransitions): (WebCore::compareCSSAnimations): * dom/Element.cpp: (WebCore::Element::removedFromAncestor): (WebCore::Element::animationRareData const): (WebCore::Element::ensureAnimationRareData): (WebCore::Element::keyframeEffectStack const): (WebCore::Element::ensureKeyframeEffectStack): (WebCore::Element::hasKeyframeEffects const): (WebCore::Element::applyKeyframeEffects): (WebCore::Element::animations const): (WebCore::Element::hasCompletedTransitionsForProperty const): (WebCore::Element::hasRunningTransitionsForProperty const): (WebCore::Element::hasRunningTransitions const): (WebCore::Element::ensureAnimations): (WebCore::Element::animationsCreatedByMarkup): (WebCore::Element::setAnimationsCreatedByMarkup): (WebCore::Element::ensureCompletedTransitionsByProperty): (WebCore::Element::ensureRunningTransitionsByProperty): (WebCore::Element::lastStyleChangeEventStyle const): (WebCore::Element::setLastStyleChangeEventStyle): (WebCore::Element::getAnimations): * dom/Element.h: * dom/ElementRareData.cpp: * dom/ElementRareData.h: (WebCore::ElementRareData::useTypes const): (WebCore::ElementRareData::animationRareData const): (WebCore::ElementRareData::ensureAnimationRareData): (WebCore::ElementRareData::elementAnimationRareData): Deleted. * dom/PseudoElement.cpp: (WebCore::PseudoElement::clearHostElement): (WebCore::PseudoElement::isTargetedByKeyframeEffectRequiringPseudoElement): * rendering/RenderBoxModelObject.cpp: (WebCore::RenderBoxModelObject::hasRunningAcceleratedAnimations const): * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::requiresCompositingForAnimation const): (WebCore::RenderLayerCompositor::isRunningTransformAnimation const): * rendering/style/RenderStyleConstants.cpp: (WebCore::operator<<): * rendering/updating/RenderTreeUpdater.cpp: (WebCore::RenderTreeUpdater::tearDownRenderers): * style/StyleTreeResolver.cpp: (WebCore::Style::TreeResolver::resolveElement): (WebCore::Style::TreeResolver::resolvePseudoStyle): (WebCore::Style::TreeResolver::createAnimatedElementUpdate): * style/StyleTreeResolver.h: * style/Styleable.h: Added. (WebCore::Styleable::Styleable): (WebCore::Styleable::fromElement): (WebCore::Styleable::fromRenderer): (WebCore::Styleable::operator== const): (WebCore::Styleable::operator!= const): (WebCore::Styleable::keyframeEffectStack const): (WebCore::Styleable::ensureKeyframeEffectStack const): (WebCore::Styleable::hasKeyframeEffects const): (WebCore::Styleable::applyKeyframeEffects const): (WebCore::Styleable::animations const): (WebCore::Styleable::hasCompletedTransitionsForProperty const): (WebCore::Styleable::hasRunningTransitionsForProperty const): (WebCore::Styleable::hasRunningTransitions const): (WebCore::Styleable::ensureAnimations const): (WebCore::Styleable::ensureCompletedTransitionsByProperty const): (WebCore::Styleable::ensureRunningTransitionsByProperty const): (WebCore::Styleable::animationsCreatedByMarkup const): (WebCore::Styleable::setAnimationsCreatedByMarkup const): (WebCore::Styleable::lastStyleChangeEventStyle const): (WebCore::Styleable::setLastStyleChangeEventStyle const): LayoutTests: <rdar://problem/69511682> Reviewed by Antti Koivisto. Update a couple of tests which relied on an internals method to get a pseudo element and instead use the Web Animations API to determine whether a given animation targets a pseudo-element. This has the added benefit of having the same code run in a testing environment as in a regular browser. * fast/css-generated-content/pseudo-animation.html: * fast/css-generated-content/pseudo-transition.html: Canonical link: https://commits.webkit.org/229750@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267571 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-09-25 15:22:00 +00:00
class RenderBoxModelObject;
[Web Animations] Allow getComputedStyle() to return animated values for accelerated animations https://bugs.webkit.org/show_bug.cgi?id=179975 <rdar://problem/35676811> Reviewed by Dean Jackson. Source/WebCore: In case we're running an accelerated animation, we are not blending RenderStyles as the animation progresses and thus we need to hook into computeRenderStyleForProperty() to query the DocumentTimeline for the animated style of running accelerated animations where we blend styles manually for the animation's current time. Test: http/wpt/wk-web-animations/interfaces/keyframe-effect-getComputedStyle.html * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::animatedStyleForRenderer): Iterate through all running accelerated animations for the element to which the provided renderer is attached and ask for their animated styles. * animation/DocumentTimeline.h: * animation/KeyframeEffect.cpp: (WebCore::KeyframeEffect::getAnimatedStyle): Manually blend all animated properties and populate the provided RenderStyle with their values, creating the RenderStyle if needed. * animation/KeyframeEffect.h: * css/CSSComputedStyleDeclaration.cpp: (WebCore::computeRenderStyleForProperty): Query the DocumentTimeline for accelerated animated properties in case such animations are running, otherwise let the CSS animation controller report the animated values. LayoutTests: Add a new test that checks that the computed style of accelerated animation returns the animated value. This test would fail for the accelerated case prior to this patch. * http/wpt/wk-web-animations/interfaces/keyframe-effect-getComputedStyle-expected.txt: Added. * http/wpt/wk-web-animations/interfaces/keyframe-effect-getComputedStyle.html: Added. Canonical link: https://commits.webkit.org/196001@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225133 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-24 13:30:36 +00:00
class RenderElement;
class DocumentTimeline final : public AnimationTimeline
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
{
[Web Animations] Provide basic timeline and animation interfaces https://bugs.webkit.org/show_bug.cgi?id=178526 Patch by Antoine Quint <graouts@apple.com> on 2017-10-20 Reviewed by Dean Jackson. .: Remove the WEB_ANIMATIONS compile-time flag. * Source/cmake/OptionsWPE.cmake: * Source/cmake/OptionsWin.cmake: * Source/cmake/WebKitFeatures.cmake: * Source/cmake/tools/vsprops/FeatureDefines.props: * Source/cmake/tools/vsprops/FeatureDefinesCairo.props: Source/JavaScriptCore: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebCore: We're getting Web Animations work started by implementing a very minimal codebase which provides a DocumentTimeline class which has an instance created for each Document. The parent class, AnimationTimeline, allows for animations to be added and removed, and animations can be created using the Animation class, with an optional timeline as parameter. Tests: webanimations/animation-creation-basic.html webanimations/document-timeline.html * CMakeLists.txt: * Configurations/FeatureDefines.xcconfig: * DerivedSources.make: * PlatformWin.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: Added. (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::~AnimationTimeline): (WebCore::AnimationTimeline::addAnimation): (WebCore::AnimationTimeline::removeAnimation): * animation/AnimationTimeline.h: Added. (WebCore::AnimationTimeline::isDocumentTimeline const): (WebCore::AnimationTimeline::classType const): * animation/AnimationTimeline.idl: Added. * animation/DocumentTimeline.cpp: Added. (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: Added. * animation/DocumentTimeline.idl: Added. * animation/WebAnimation.cpp: Added. (WebCore::WebAnimation::create): (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::~WebAnimation): * animation/WebAnimation.h: Added. * animation/WebAnimation.idl: Added. * bindings/js/JSAnimationTimelineCustom.cpp: Added. (WebCore::toJSNewlyCreated): (WebCore::toJS): * bindings/js/WebCoreBuiltinNames.h: * dom/Document.cpp: (WebCore::Document::timeline): * dom/Document.h: * dom/Document.idl: * page/RuntimeEnabledFeatures.h: (WebCore::RuntimeEnabledFeatures::webAnimationsEnabled const): Source/WebCore/PAL: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebKit: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebProcess/InjectedBundle/InjectedBundle.cpp: (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): (WebKit::InjectedBundle::setWebAnimationsEnabled): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updatePreferences): Source/WebKitLegacy/mac: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Source/WebKitLegacy/win: Remove the WEB_ANIMATIONS compile-time flag. * WebView.cpp: (WebView::notifyPreferencesChanged): Source/WTF: Remove the WEB_ANIMATIONS compile-time flag. * wtf/FeatureDefines.h: Tools: Remove the WEB_ANIMATIONS compile-time flag. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: Basic test coverage to check that we are exposing a DocumentTimeline instance on the Document and that we can construct Animations, optionally associated with a timeline. * platform/mac-elcapitan/TestExpectations: * webanimations/animation-creation-basic-expected.txt: Added. * webanimations/animation-creation-basic.html: Added. * webanimations/document-timeline-expected.txt: Added. * webanimations/document-timeline.html: Added. Canonical link: https://commits.webkit.org/194785@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 18:41:23 +00:00
public:
[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): Canonical link: https://commits.webkit.org/202231@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233140 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-06-25 09:54:34 +00:00
static Ref<DocumentTimeline> create(Document&);
static Ref<DocumentTimeline> create(Document&, DocumentTimelineOptions&&);
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
~DocumentTimeline();
[Web Animations] Audit Web Animations classes for memory reduction https://bugs.webkit.org/show_bug.cgi?id=193195 Reviewed by Simon Fraser and Yusuke Suzuki. The classes, enums and structs added to support Web Animations were not as memory-efficient as they could be. We now order members in a way that reduces padding, use Markable<T, Traits> instead of Optional<T> where applicable, declare enums as uint8_t and removed unnecessary members. As a result, classes and structs have shrunk as follows: WebAnimation: 256 > 216 DeclarativeAnimation: 392 > 344 CSSAnimation: 416 > 368 CSSTransition: 440 > 392 AnimationEffect: 88 > 72 KeyframeEffect: 208 > 184 AnimationPlaybackEvent: 104 > 88 EffectTiming: 72 > 64 ComputedEffectTiming: 136 > 112 AnimationTimeline: 264 > 248 DocumentTimeline: 496 > 464 OptionalEffectTiming: 112 > 80 BaseKeyframe: 32 > 24 ParsedKeyframe: 80 > 72 BaseComputedKeyframe: 40 > 32 * animation/AnimationEffect.h: Order members in decreasing size, except for m_fill and m_direction, which we put at the top to save 8 bytes (2 bytes of padding instead of 4 before m_animation and saving 6 bytes of padding at the end). * animation/AnimationPlaybackEvent.cpp: (WebCore::AnimationPlaybackEvent::AnimationPlaybackEvent): * animation/AnimationPlaybackEvent.h: * animation/AnimationPlaybackEventInit.h: * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::updateCSSTransitionsForElement): * animation/AnimationTimeline.h: We remove the m_classType member and instead make isDocumentTimeline() virtual. (WebCore::AnimationTimeline::isDocumentTimeline const): (): Deleted. (WebCore::AnimationTimeline::classType const): Deleted. * animation/CompositeOperation.h: * animation/CompositeOperationOrAuto.h: * animation/ComputedEffectTiming.h: * animation/DeclarativeAnimation.cpp: (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::invalidateDOMEvents): * animation/DeclarativeAnimation.h: We keep m_wasPending and m_previousPhase at the top to save some padding at the end. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: * animation/EffectTiming.h: * animation/FillMode.h: * animation/IterationCompositeOperation.h: * animation/KeyframeEffect.cpp: (WebCore::computeMissingKeyframeOffsets): (WebCore::KeyframeEffect::create): (WebCore::KeyframeEffect::KeyframeEffect): * animation/KeyframeEffect.h: * animation/OptionalEffectTiming.h: * animation/PlaybackDirection.h: * animation/WebAnimation.h: * animation/WebAnimationUtilities.h: (WebCore::WebAnimationsMarkableDoubleTraits::isEmptyValue): (WebCore::WebAnimationsMarkableDoubleTraits::emptyValue): Canonical link: https://commits.webkit.org/207806@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239820 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-10 08:19:39 +00:00
bool isDocumentTimeline() const final { return true; }
[Web Animations] Correct implementation of pending tasks and promises https://bugs.webkit.org/show_bug.cgi?id=183161 Reviewed by Dean Jackson. LayoutTests/imported/w3c: Update test expectations with progressions (+32 WPT PASS). * web-platform-tests/web-animations/interfaces/Animatable/animate-no-browsing-context-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/finish-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/finished-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/onfinish-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/pause-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/pending-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/startTime-expected.txt: * web-platform-tests/web-animations/timing-model/animations/canceling-an-animation-expected.txt: * web-platform-tests/web-animations/timing-model/animations/pausing-an-animation-expected.txt: * web-platform-tests/web-animations/timing-model/animations/play-states-expected.txt: * web-platform-tests/web-animations/timing-model/animations/reversing-an-animation-expected.txt: * web-platform-tests/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * web-platform-tests/web-animations/timing-model/animations/set-the-target-effect-of-an-animation-expected.txt: * web-platform-tests/web-animations/timing-model/animations/set-the-timeline-of-an-animation-expected.txt: Source/WebCore: We had an incorrect implementation of the spec due to two misinterpretations. The first one is about pending tasks (play and pause) which the spec says should be performed by "scheduling a task". In WebCore, this means using postTask() on a ScriptExecutionContext, such as Document. One of the big practical changes is that calling play() on an animation correctly sets its startTime to null (unresolved) immediately after the call to play() returns before setting it to a resolved value when the task is performed asynchronously. As a result, the playState is now always accurate. The second one is about promises where new promises need to be created in certain situations called out by the spec. We used to call clear() on them, but this merely resets the fulfillment or rejection state of the promise, while the spec requires a different object to be returned for the promise. We now create our promises using makeUniqueRef<> when new promise objects are expected to be created. This patch also corrects a few smaller bugs and spec compliant issues, called out below, related to pending tasks and promises uncovered while looking at relevant WPT tests. * animation/DocumentTimeline.h: Expose the Document used to create this timeline such that it may be used by WebAnimation objects registered for this timeline when scheduling a task is required via postTask(). * animation/WebAnimation.cpp: (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::setBindingsStartTime): (WebCore::WebAnimation::setCurrentTime): (WebCore::WebAnimation::cancel): Ensure the finished promise has not already been fulfilled before rejecting it. While the spec does not specifically call this out, a promise may not be rejected after being fulfilled, and we would hit an ASSERT if we didn't also check that it was in the correct pending state before attemping to reject it. (WebCore::WebAnimation::resetPendingTasks): (WebCore::WebAnimation::finish): (WebCore::WebAnimation::updateFinishedState): (WebCore::WebAnimation::finishNotificationSteps): (WebCore::WebAnimation::play): We used to only check for a pending pause task before canceling that task, but the spec says to check for either a pending pause or play task (ie. pending()) and to cancel whichever is scheduled. (WebCore::WebAnimation::runPendingPlayTask): We were missing an assertion called out by the spec when running a pending task. (WebCore::WebAnimation::pause): (WebCore::WebAnimation::runPendingPauseTask): (WebCore::WebAnimation::updatePendingTasks): We now use postTask() on the animation's associated timeline's document to schedule pending tasks for which the criteria to run are met, ie. there is an associated timeline. * animation/WebAnimation.h: Canonical link: https://commits.webkit.org/198880@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229069 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-02-27 21:05:02 +00:00
Document* document() const { return m_document.get(); }
Remove WTF::Optional synonym for std::optional, using that class template directly instead https://bugs.webkit.org/show_bug.cgi?id=226433 Reviewed by Chris Dumez. Source/JavaScriptCore: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * inspector/scripts/codegen/generate_objc_protocol_types_implementation.py: (ObjCProtocolTypesImplementationGenerator._generate_init_method_for_payload): Use auto instead of Optional<>. Also use * instead of value() and nest the definition of the local inside an if statement in the case where it's an optional. * inspector/scripts/tests/expected/*: Regenerated these results. Source/WebCore: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebCore/PAL: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebDriver: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKit: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * Scripts/webkit/tests: Regenerated expected results, by running the command "python Scripts/webkit/messages_unittest.py -r". (How am I supposed to know to do that?) Source/WebKitLegacy/ios: * WebCoreSupport/WebChromeClientIOS.h: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKitLegacy/mac: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WebKitLegacy/win: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Source/WTF: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. * wtf/Optional.h: Remove WTF::Optional. Tools: * <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>. Canonical link: https://commits.webkit.org/238290@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-30 16:11:40 +00:00
std::optional<Seconds> currentTime() override;
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
[Web Animations] Implement the update animations and send events procedure https://bugs.webkit.org/show_bug.cgi?id=191013 <rdar://problem/45620495> Reviewed by Dean Jackson. LayoutTests/imported/mozilla: Progression in a couple of getAnimations() tests for CSS Animations. * css-animations/test_document-get-animations-expected.txt: LayoutTests/imported/w3c: Progressions in a couple of Web Animations Web Platform Tests. * web-platform-tests/web-animations/timing-model/animations/current-time-expected.txt: * web-platform-tests/web-animations/timing-model/animations/updating-the-finished-state-expected.txt: Source/WebCore: While we implemented the various parts of what the Web Animations specification refers to as the "update animations and send events" procedure, we did not implement it as one function and in the correct order, specifically updating animations and sending events in two separate tasks. We now have a single method on DocumentTimeline which runs as the DisplayRefreshMonitor fires to update each "relevant" animation with the current time, perform a microtask checkpoint and dispatch events. Implementing this procedure allowed us to make several enhancements: 1. We introduce the concept of a "relevant" animation, which is essentially an animation that is either pending or playing. All animations in a different state are no longer owned by the DocumentTimeline and can thus be destroyed if the developer doesn't hold references in JS. Maintaining such a list guarantees that we're only updating animations that would have changed state since the last time the "update animations and send events" procedure was run. Note that DeclarativeAnimation instances are also considered to be relevant if they have queued DOM events to dispatch as they could otherwise be destroyed before they can fully dispatch them. 2. We no longer conflate the timing model and effects. Until now the way we would update animations was to go through all elements for which we had a registered animation, invalidate their style and finally forcing a style update on the document. We had a separate data structure where we help animations without targets so we update these as well in a separate pass, in order to make sure that promises and events would fire for them as expected. We now let the "update animations and send events" procedure update the timing of all relevant animations and let individual animation effects invalidate their style as needed, the document style invalidation happening naturally without DocumentTimeline forcing it. 3. We use a single step to schedule the update of animations, which is to register for a display refresh monitor update provided a "relevant" animation is known since the previous update. Until now we first had an "timing model invalidation" task scheduled upon any change of an animation's timing model, which would then create a timer to the earliest moment any listed animation would require an update, finally registering a display refresh monitor update, which used at least GenericTaskQueue<Timer> and potentially two, whereas we use none right now. 4. We allow for a display refresh monitor update to be canceled should the number of "relevant" animations since the last update goes back to 0. To facilitate all of this, we have changed the m_animations ListHashSet to contain only the "relevant" animations, and no longer every animation created that has this DocumentTimeline set as their "timeline" property. To keep this list current, every single change that changes a given animation's timing ends up calling AnimationTimeline::animationTimingDidChange() passing the animation as the sole parameter and adding this animation to m_animations. We immediately schedule a display refresh monitor update if one wasn't already scheduled. Then, when running the "update animations and send events" procedure, we call a new WebAnimation::tick() method on each of those animations, which updates this animation's effect and relevance, using the newly computed relevance to identify whether this animation should be kept in the m_animations ListHashSet. This is only the first step towards a more efficient update and ownership model of animations by the document timeline since animations created as CSS Animations and CSS Transitions are committed through CSS have dedicated data structures that are not updated in this particular patch, but this will be addressed in a followup to keep this already significant patch smaller. Another issue that will be addressed later is the ability to not schedule display refresh monitor udpates when only accelerated animations are running. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::animationTimingDidChange): Called by animations when any aspect of their timing model changes. The provided animation is then added to the m_animations list unless its timeline is no longer this timeline. (WebCore::AnimationTimeline::removeAnimation): Remove the provided animation from m_animations and remove any animation registered on the element-specific animation lists if this animation has an effect with a target. (WebCore::AnimationTimeline::animationWasAddedToElement): We no longer need to worry about the m_animationsWithoutTarget data structure since we removed it. (WebCore::removeCSSTransitionFromMap): Fix a bug where we would remove any CSSTransition in the provided map that had a matching transition-property instead of checking the CSSTransition registered for this transition-property was indeed the provided CSSTransition. The other code changes in this patch made this code now cause regressions in the Web Platform Tests. (WebCore::AnimationTimeline::animationWasRemovedFromElement): Stop updating m_animationsWithoutTarget since it no longer exists. (WebCore::AnimationTimeline::elementWasRemoved): (WebCore::AnimationTimeline::updateCSSAnimationsForElement): Fix a small error that caused a regression in the Web Platform Tests where we could attempt to call setBackingAnimation() on a nullptr instead of a valid CSSAnimation. (WebCore::AnimationTimeline::cancelOrRemoveDeclarativeAnimation): (WebCore::AnimationTimeline::addAnimation): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::hasElementAnimations const): Deleted. (WebCore::AnimationTimeline:: const): Deleted. (WebCore::AnimationTimeline::elementToAnimationsMap): Deleted. (WebCore::AnimationTimeline::elementToCSSAnimationsMap): Deleted. (WebCore::AnimationTimeline::elementToCSSTransitionsMap): Deleted. * animation/CSSTransition.cpp: (WebCore::CSSTransition::canBeListed const): Deleted. * animation/CSSTransition.h: * animation/DeclarativeAnimation.cpp: (WebCore::DeclarativeAnimation::tick): Call the superclass's method and queue any necessary DOM events reflecting the timing model changes. (WebCore::DeclarativeAnimation::needsTick const): Call the superclass's method and return true also if we have pending events since otherwise this animation could be removed from m_animations on its AnimationTimeline and potentially destroyed before the GenericEventQueue had a chance to dispatch all events. (WebCore::DeclarativeAnimation::startTime const): We removed the custom binding for this IDL property and renamed the method from bindingsStartTime to startTime. (WebCore::DeclarativeAnimation::setStartTime): We removed the custom binding for this IDL property and renamed the method from setBindingsStartTime to setStartTime. (WebCore::DeclarativeAnimation::bindingsStartTime const): Deleted. (WebCore::DeclarativeAnimation::setBindingsStartTime): Deleted. * animation/DeclarativeAnimation.h: * animation/DocumentAnimationScheduler.cpp: (WebCore::DocumentAnimationScheduler::unscheduleWebAnimationsResolution): Add a method to mark that we no longer need a display refresh monitor update for this document's animation timeline. This is called when m_animations becomes empty. * animation/DocumentAnimationScheduler.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::detachFromDocument): Stop clearing two task queues and a timer that no longer exist and instead only clear the task queue to clear the cached current time, which we queue any time we generate a new one (see DocumentTimeline::currentTime). (WebCore::DocumentTimeline::getAnimations const): Use isRelevant() instead of canBeListed(). (WebCore::DocumentTimeline::updateThrottlingState): (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::resumeAnimations): (WebCore::DocumentTimeline::numberOfActiveAnimationsForTesting const): (WebCore::DocumentTimeline::currentTime): Queue a task in the new m_currentTimeClearingTaskQueue task queue to clear the current time that we've generated and cached in the next run loop (provided all pending JS execution has also completed). (WebCore::DocumentTimeline::maybeClearCachedCurrentTime): (WebCore::DocumentTimeline::scheduleAnimationResolutionIfNeeded): Schedule a display refresh monitor update if we are not suspended and have "relevant" animations. (WebCore::DocumentTimeline::animationTimingDidChange): Call scheduleAnimationResolutionIfNeeded() after calling the superclass's implementation. (WebCore::DocumentTimeline::removeAnimation): Call unscheduleAnimationResolution() if the list of "relevant" animations is now empty. (WebCore::DocumentTimeline::unscheduleAnimationResolution): Unschedule a pending display refresh monitor update. (WebCore::DocumentTimeline::animationResolutionTimerFired): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): Implement the "update animations and send events" procedure as specified by the Web Animations spec. During this procedure, we call tick() on all animations listed in m_animations and create a list of animations to remove from that list if this animation is no longer relevant following the call to tick(). (WebCore::DocumentTimeline::enqueueAnimationPlaybackEvent): (WebCore::DocumentTimeline::timingModelDidChange): Deleted. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Deleted. (WebCore::DocumentTimeline::performInvalidationTask): Deleted. (WebCore::DocumentTimeline::updateAnimationSchedule): Deleted. (WebCore::DocumentTimeline::animationScheduleTimerFired): Deleted. (WebCore::DocumentTimeline::updateAnimations): Deleted. (WebCore::compareAnimationPlaybackEvents): Deleted. (WebCore::DocumentTimeline::performEventDispatchTask): Deleted. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: The majority of the changes to this class is that we call the new timingDidChange() method when any code that modifies the timing model is run. We also remove methods to set the pending play and pause tasks as well as the animation's start time and hold time since any time we're changing these instance variables, we later already have a call to update the timing model and we were doing more work than needed. As a result we no longer need an internal method to set the start time and can stop requiring a custom IDL binding for the "startTime" property. (WebCore::WebAnimation::effectTimingPropertiesDidChange): (WebCore::WebAnimation::setEffect): (WebCore::WebAnimation::setEffectInternal): (WebCore::WebAnimation::setTimeline): (WebCore::WebAnimation::setTimelineInternal): (WebCore::WebAnimation::startTime const): (WebCore::WebAnimation::setStartTime): (WebCore::WebAnimation::silentlySetCurrentTime): (WebCore::WebAnimation::setCurrentTime): (WebCore::WebAnimation::setPlaybackRate): (WebCore::WebAnimation::cancel): (WebCore::WebAnimation::resetPendingTasks): (WebCore::WebAnimation::finish): (WebCore::WebAnimation::timingDidChange): New method called any time a timing property changed where we run the "update the finished state" procedure and notify the animation's timeline that its timing changed so that it can be considered the next time the "update animations and send events" procedure runs. (WebCore::WebAnimation::invalidateEffect): (WebCore::WebAnimation::updateFinishedState): Update the animation's relevance after running the procedure as specified. (WebCore::WebAnimation::play): (WebCore::WebAnimation::runPendingPlayTask): (WebCore::WebAnimation::pause): (WebCore::WebAnimation::runPendingPauseTask): (WebCore::WebAnimation::needsTick const): (WebCore::WebAnimation::tick): New method called during the "update animations and send events" procedure where we run the "update the finished state" procedure and run the pending play and pause tasks. (WebCore::WebAnimation::resolve): (WebCore::WebAnimation::updateRelevance): (WebCore::WebAnimation::computeRelevance): (WebCore::WebAnimation::timingModelDidChange): Deleted. (WebCore::WebAnimation::setHoldTime): Deleted. (WebCore::WebAnimation::bindingsStartTime const): Deleted. (WebCore::WebAnimation::setBindingsStartTime): Deleted. (WebCore::WebAnimation::setTimeToRunPendingPlayTask): Deleted. (WebCore::WebAnimation::setTimeToRunPendingPauseTask): Deleted. (WebCore::WebAnimation::updatePendingTasks): Deleted. (WebCore::WebAnimation::timeToNextRequiredTick const): Deleted. (WebCore::WebAnimation::runPendingTasks): Deleted. (WebCore::WebAnimation::canBeListed const): Deleted. * animation/WebAnimation.h: (WebCore::WebAnimation::isRelevant const): (WebCore::WebAnimation::hasPendingPlayTask const): (WebCore::WebAnimation::isEffectInvalidationSuspended): * animation/WebAnimation.idl: * dom/Element.cpp: (WebCore::Element::getAnimations): Use isRelevant() instead of canBeListed(). LayoutTests: Several tests that broke when turning Web Animations CSS Integration on by default are now passing. In the case of one test, we had to ensure that the final animation frame had been committed before terminating the test or there would be a tiny image reference issue. * TestExpectations: * fast/layers/no-clipping-overflow-hidden-added-after-transform.html: Canonical link: https://commits.webkit.org/205875@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237587 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-30 09:30:03 +00:00
void animationTimingDidChange(WebAnimation&) override;
void removeAnimation(WebAnimation&) override;
[Web Animations] Coordinate "update animations and send events" procedure across multiple timelines https://bugs.webkit.org/show_bug.cgi?id=202109 <rdar://problem/59470821> Reviewed by Dean Jackson. LayoutTests/imported/w3c: Mark a new test as PASS which shows that we correctly perform a single microstask checkpoint when updating multiple timelines. * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: So far, although we did manage multiple animation timelines per document, we mostly operated under the assumption that there really was a single timeline. In this patch we make the "update animations and send events" procedure, which is central to the lifecycle of animations, work with multiple timelines such that a single microtask checkpoint is performed even with multiple timelines, whereas we would perform one per timeline before. To do this, we move much of the logic DocumentTimeline::updateAnimationsAndSendEvents() to DocumentTimelinesController where each step is run across each timeline, rather than running all steps for each timeline one after the other, respecting the single microtask checkpoint in the middle of the process. To minimize code churn at this stage, we still keep a fair bit of logic in DocumentTimeline and, while we remove updateAnimationsAndSendEvents(), internalUpdateAnimationsAndSendEvents() and updateCurrentTime(), we expose three methods that allow to run the pre-flight sequence in documentWillUpdateAnimationsAndSendEvents(), collect pending events in prepareForPendingAnimationEventsDispatch() and run the post-flight sequence in documentDidUpdateAnimationsAndSendEvents(). None of the logic changes, this is just moving code around. In the future, more patches will move code from DocumentTimeline up to DocumentTimelinesController such that events are enqueued there, and animation scheduling as well. But this already lets us pass a new test that used to flakily reject promises in the WPT test web-animations/timing-model/timelines/update-and-send-events.html. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::relevantAnimations const): (WebCore::AnimationTimeline::allAnimations const): * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::documentDidUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::prepareForPendingAnimationEventsDispatch): (WebCore::DocumentTimeline::updateCurrentTime): Deleted. (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): Deleted. (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): Deleted. * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: (WebCore::DocumentTimelinesController::DocumentTimelinesController): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): * animation/DocumentTimelinesController.h: * animation/WebAnimationTypes.h: * dom/Document.cpp: (WebCore::Document::ensureTimelinesController): LayoutTests: Remove the flaky expectation for the improved test. * TestExpectations: Canonical link: https://commits.webkit.org/223759@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260525 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 18:47:36 +00:00
void transitionDidComplete(RefPtr<CSSTransition>);
[Web Animations] Ensure renderers with accelerated animations have layers https://bugs.webkit.org/show_bug.cgi?id=189990 Reviewed by Simon Fraser. In r236501 we added code that would make a RenderBox and a RenderInline query the document timeline for whether a given element has accelerated animations running on it. Since the calls to requiresLayer() are in a hot path, we instead keep a list of elements with exclusively accelerated animations running. No new tests, this is already covered by webanimations/accelerated-animation-with-delay.html and webanimations/opacity-animation-yields-compositing-span.html which respectively check that we can apply an accelerated animation to a non-positioned block and an inline element. * animation/AnimationTimeline.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): (WebCore::DocumentTimeline::animationWasAddedToElement): (WebCore::DocumentTimeline::animationWasRemovedFromElement): (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): (WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Iterate over an element's animations to determine whether all of its animations are running accelerated, then update the HashSet containing elements running accelerated animations to remove or add this element. (WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Make a simple contains() call on the HashSet containing elements running accelerated animations. * animation/DocumentTimeline.h: * animation/KeyframeEffectReadOnly.cpp: (WebCore::KeyframeEffectReadOnly::updateAcceleratedAnimationState): (WebCore::KeyframeEffectReadOnly::applyPendingAcceleratedActions): * rendering/RenderBoxModelObject.h: Canonical link: https://commits.webkit.org/205099@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236670 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-01 17:44:39 +00:00
[Web Animations] Ensure elements overlapping with elements animating also get composited https://bugs.webkit.org/show_bug.cgi?id=184539 Reviewed by Jon Lee. Source/WebCore: A number of compositing tests failed because we didn't call into the Web Animations engine while various calls on RenderLayer and RenderLayerBacking were made. We bring the functionality over from CSSAnimationController to DocumentTimeline and KeyframeAnimation to KeyframeEffectReadOnly. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::animationsForElement const): Update this method's signature to be const since it should be callable by other const method. (WebCore::AnimationTimeline::animationsForElement): Deleted. * animation/AnimationTimeline.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::computeExtentOfAnimation const): Adapt this method from CSSAnimationController. (WebCore::DocumentTimeline::isRunningAnimationOnRenderer const): Adapt this method from CSSAnimationController. (WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const): Adapt this method from CSSAnimationController. * animation/DocumentTimeline.h: * animation/KeyframeEffectReadOnly.cpp: (WebCore::KeyframeEffectReadOnly::computeExtentOfTransformAnimation const): Bring this method over from KeyframeAnimation. (WebCore::containsRotation): Bring this method over from KeyframeAnimation. (WebCore::KeyframeEffectReadOnly::computeTransformedExtentViaTransformList const): Bring this method over from KeyframeAnimation. (WebCore::KeyframeEffectReadOnly::computeTransformedExtentViaMatrix const): Bring this method over from KeyframeAnimation. * animation/KeyframeEffectReadOnly.h: (WebCore::KeyframeEffectReadOnly::animatedProperties const): DocumentTimeline::computeExtentOfAnimation() needs to get a list of all animated properties to see if a transform is animated, so we now expose such a list. * rendering/RenderLayer.cpp: (WebCore::RenderLayer::currentTransform const): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. (WebCore::RenderLayer::calculateClipRects const): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. * rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::updateGeometry): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::isRunningTransformAnimation const): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. * rendering/RenderObject.h: (WebCore::RenderObject::documentTimeline const): LayoutTests: Opt more tests in the CSS Animations and CSS Transitions as Web Animations runtime flag since they now pass. * compositing/backing/backface-visibility-flip.html: * compositing/layer-creation/overlap-animation-clipping.html: * compositing/layer-creation/overlap-animation-container.html: * compositing/layer-creation/overlap-animation.html: * compositing/layer-creation/translate-animation-overlap.html: Canonical link: https://commits.webkit.org/200090@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230578 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-12 16:34:42 +00:00
// 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
// transform animation but we were unable to cheaply compute its effect on the extent.
bool computeExtentOfAnimation(RenderElement&, LayoutRect&) const;
[Web Animations] Allow getComputedStyle() to return animated values for accelerated animations https://bugs.webkit.org/show_bug.cgi?id=179975 <rdar://problem/35676811> Reviewed by Dean Jackson. Source/WebCore: In case we're running an accelerated animation, we are not blending RenderStyles as the animation progresses and thus we need to hook into computeRenderStyleForProperty() to query the DocumentTimeline for the animated style of running accelerated animations where we blend styles manually for the animation's current time. Test: http/wpt/wk-web-animations/interfaces/keyframe-effect-getComputedStyle.html * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::animatedStyleForRenderer): Iterate through all running accelerated animations for the element to which the provided renderer is attached and ask for their animated styles. * animation/DocumentTimeline.h: * animation/KeyframeEffect.cpp: (WebCore::KeyframeEffect::getAnimatedStyle): Manually blend all animated properties and populate the provided RenderStyle with their values, creating the RenderStyle if needed. * animation/KeyframeEffect.h: * css/CSSComputedStyleDeclaration.cpp: (WebCore::computeRenderStyleForProperty): Query the DocumentTimeline for accelerated animated properties in case such animations are running, otherwise let the CSS animation controller report the animated values. LayoutTests: Add a new test that checks that the computed style of accelerated animation returns the animated value. This test would fail for the accelerated case prior to this patch. * http/wpt/wk-web-animations/interfaces/keyframe-effect-getComputedStyle-expected.txt: Added. * http/wpt/wk-web-animations/interfaces/keyframe-effect-getComputedStyle.html: Added. Canonical link: https://commits.webkit.org/196001@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225133 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-24 13:30:36 +00:00
std::unique_ptr<RenderStyle> animatedStyleForRenderer(RenderElement& renderer);
[Web Animations] Ensure elements overlapping with elements animating also get composited https://bugs.webkit.org/show_bug.cgi?id=184539 Reviewed by Jon Lee. Source/WebCore: A number of compositing tests failed because we didn't call into the Web Animations engine while various calls on RenderLayer and RenderLayerBacking were made. We bring the functionality over from CSSAnimationController to DocumentTimeline and KeyframeAnimation to KeyframeEffectReadOnly. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::animationsForElement const): Update this method's signature to be const since it should be callable by other const method. (WebCore::AnimationTimeline::animationsForElement): Deleted. * animation/AnimationTimeline.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::computeExtentOfAnimation const): Adapt this method from CSSAnimationController. (WebCore::DocumentTimeline::isRunningAnimationOnRenderer const): Adapt this method from CSSAnimationController. (WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const): Adapt this method from CSSAnimationController. * animation/DocumentTimeline.h: * animation/KeyframeEffectReadOnly.cpp: (WebCore::KeyframeEffectReadOnly::computeExtentOfTransformAnimation const): Bring this method over from KeyframeAnimation. (WebCore::containsRotation): Bring this method over from KeyframeAnimation. (WebCore::KeyframeEffectReadOnly::computeTransformedExtentViaTransformList const): Bring this method over from KeyframeAnimation. (WebCore::KeyframeEffectReadOnly::computeTransformedExtentViaMatrix const): Bring this method over from KeyframeAnimation. * animation/KeyframeEffectReadOnly.h: (WebCore::KeyframeEffectReadOnly::animatedProperties const): DocumentTimeline::computeExtentOfAnimation() needs to get a list of all animated properties to see if a transform is animated, so we now expose such a list. * rendering/RenderLayer.cpp: (WebCore::RenderLayer::currentTransform const): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. (WebCore::RenderLayer::calculateClipRects const): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. * rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::updateGeometry): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::isRunningTransformAnimation const): Update this method to call into DocumentTimeline if the CSS Animations and CSS Transitions as Web Animations flag is on. * rendering/RenderObject.h: (WebCore::RenderObject::documentTimeline const): LayoutTests: Opt more tests in the CSS Animations and CSS Transitions as Web Animations runtime flag since they now pass. * compositing/backing/backface-visibility-flip.html: * compositing/layer-creation/overlap-animation-clipping.html: * compositing/layer-creation/overlap-animation-container.html: * compositing/layer-creation/overlap-animation.html: * compositing/layer-creation/translate-animation-overlap.html: Canonical link: https://commits.webkit.org/200090@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230578 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-12 16:34:42 +00:00
bool isRunningAnimationOnRenderer(RenderElement&, CSSPropertyID) const;
bool isRunningAcceleratedAnimationOnRenderer(RenderElement&, CSSPropertyID) const;
Source/WebCore: [Web Animations] Perform accelerated animations when possible https://bugs.webkit.org/show_bug.cgi?id=179973 <rdar://problem/34953922> Reviewed by Dean Jackson. When we're entering and leaving the active duration of an animation effect, we now check whether the animation can be accelerated, using the existing CSSPropertyAnimation::animationOfPropertyIsAccelerated() utility, and start and stop animations using the startAnimation() and animationFinished() functions on RenderBoxModelObject. This patch is only a first step towards full support for accelerated animations, there are two known issues at the moment. Because we're not blending the styles to perform the animation, getComputedStyle() will not return the animated value (webkit.org/b/179974). Additionally, if other animations happen to run later during the active state of an animation that can run accelerated, we will not fall back to software-only animation for this element and these animations will appear not to run (webkit.org/b/179975). These will be addressed in follow-up patches. Tests: webanimations/left-and-opacity-animation-yields-no-compositing.html webanimations/opacity-animation-no-longer-composited-upon-completion.html webanimations/opacity-animation-yields-compositing.html webanimations/width-and-opacity-separate-animation-yields-no-compositing.html * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::updateAnimations): Check in the map of pending accelerated animations to see if any animation requires toggling their active state after their styles have been invalidated. (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): New function to let animations indicate that they need to have their accelerated backing animation toggled after style invalidation has been completed. (WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated): This function is used in RenderLayerCompositor::requiresCompositingForAnimation() to identify whether an element requires hardware compositing due to running accelerated animations. We check all running animations for the provided element to see if they can all be running accelerated and return true in this situation only. * animation/DocumentTimeline.h: * animation/KeyframeEffect.cpp: (WebCore::KeyframeEffect::applyAtLocalTime): Identify if we're crossing into or out of the active state for an animation and check if it will be or has been running accelerated such that we can notify the DocumentTimeline, through the associated animation, that the accelerated backing animation will need to be toggled after style invalidation has been completed. (WebCore::KeyframeEffect::shouldRunAccelerated): Check that all properties for this animation effect can be accelerated according to CSSPropertyAnimation::animationOfPropertyIsAccelerated(). (WebCore::KeyframeEffect::startOrStopAccelerated): Start or stop the associated accelerated animation through the associated element's RenderBoxModelObject renderer. * animation/KeyframeEffect.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::acceleratedRunningStateDidChange): Called from AnimationEffect::applyAtLocalTime(), we forward to the DocumentTimeline the information that the animation will cross an active state boundary while allowing to be backed by hardware compositing. (WebCore::WebAnimation::startOrStopAccelerated): Forward to the associated KeyframeEffect that accelerated animation backing should be toggled. * animation/WebAnimation.h: * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::requiresCompositingForAnimation const): Check via the renderer's element's DocumentTimeline that all running animations for this particular element are accelerated to ensure that the element will be hardware-composited. LayoutTests: [Web Animations] Perform hardware-composited animations when possible https://bugs.webkit.org/show_bug.cgi?id=179973 <rdar://problem/34953922> Reviewed by Dean Jackson. Add a series of tests to check that we use hardware-compositing for animations when possible. Specifically, we check that: 1. Specifying both accelerated and non-accelerated properties for a single animation does *not* yield hardware compositing (left-and-opacity-animation-yields-no-compositing.html). 2. Specifying both accelerated and non-accelerated properties via multiple animations does *not* yield hardware compositing (width-and-opacity-separate-animation-yields-no-compositing.html). 3. Specifying only accelerated properties *does* yield hardware compositing (opacity-animation-yields-compositing.html). 4. Hardware-composited animations no longer enforce hardware compositing after their completion (opacity-animation-no-longer-composited-upon-completion.html). * webanimations/left-and-opacity-animation-yields-no-compositing-expected.txt: Added. * webanimations/left-and-opacity-animation-yields-no-compositing.html: Added. * webanimations/opacity-animation-no-longer-composited-upon-completion-expected.txt: Added. * webanimations/opacity-animation-no-longer-composited-upon-completion.html: Added. * webanimations/opacity-animation-yields-compositing-expected.txt: Added. * webanimations/opacity-animation-yields-compositing.html: Added. * webanimations/width-and-opacity-separate-animation-yields-no-compositing-expected.txt: Added. * webanimations/width-and-opacity-separate-animation-yields-no-compositing.html: Added. Canonical link: https://commits.webkit.org/195996@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225128 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-24 09:45:30 +00:00
void animationAcceleratedRunningStateDidChange(WebAnimation&);
Reduce the reliance on PseudoElement in the animation code https://bugs.webkit.org/show_bug.cgi?id=216931 LayoutTests/imported/w3c: Reviewed by Antti Koivisto. Mark a WPT test progression. * web-platform-tests/css/css-transitions/non-rendered-element-002-expected.txt: Source/WebCore: <rdar://problem/69511682> Reviewed by Antti Koivisto. We have so far relied on PseudoElement as a foundation for supporting animations of pseudo-elements. This is not a great choice since PseudoElement is currently limited to ::before and ::after pseudo-elements only. This patch refactors animation-related code to rely on PseudoElement as little as possible without making changes outside of the animation code, as a first step towards supporting animation of more pseudo-elements. This patch introduces a new struct Styleable which combines an Element& and PseudoId. We use this struct instead of Element objects wherever necessary in the animation code. On top of that, we add a PseudoId parameter to all the Element methods wrapping access to ElementAnimationRareData and use a HashMap<PseudoId, std::unique_ptr<ElementAnimationRareData>> to be able to separate animation data per pseudo-element. * Headers.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::removeAnimation): (WebCore::AnimationTimeline::animationWasAddedToStyleable): (WebCore::AnimationTimeline::animationWasRemovedFromStyleable): (WebCore::AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement): (WebCore::AnimationTimeline::removeCSSAnimationCreatedByMarkup): (WebCore::AnimationTimeline::elementWasRemoved): (WebCore::AnimationTimeline::willChangeRendererForStyleable): (WebCore::AnimationTimeline::cancelDeclarativeAnimationsForStyleable): (WebCore::shouldConsiderAnimation): (WebCore::AnimationTimeline::updateCSSAnimationsForStyleable): (WebCore::keyframeEffectForElementAndProperty): (WebCore::AnimationTimeline::updateCSSTransitionsForStyleableAndProperty): (WebCore::AnimationTimeline::updateCSSTransitionsForStyleable): (WebCore::AnimationTimeline::animationWasAddedToElement): Deleted. (WebCore::AnimationTimeline::animationWasRemovedFromElement): Deleted. (WebCore::AnimationTimeline::willChangeRendererForElement): Deleted. (WebCore::AnimationTimeline::cancelDeclarativeAnimationsForElement): Deleted. (WebCore::AnimationTimeline::updateCSSAnimationsForElement): Deleted. (WebCore::AnimationTimeline::updateCSSTransitionsForElementAndProperty): Deleted. (WebCore::AnimationTimeline::updateCSSTransitionsForElement): Deleted. * animation/AnimationTimeline.h: * animation/CSSAnimation.cpp: (WebCore::CSSAnimation::create): (WebCore::CSSAnimation::CSSAnimation): * animation/CSSAnimation.h: * animation/CSSTransition.cpp: (WebCore::CSSTransition::create): (WebCore::CSSTransition::CSSTransition): * animation/CSSTransition.h: * animation/DeclarativeAnimation.cpp: (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::owningElement const): (WebCore::DeclarativeAnimation::disassociateFromOwningElement): (WebCore::DeclarativeAnimation::initialize): (WebCore::DeclarativeAnimation::enqueueDOMEvent): * animation/DeclarativeAnimation.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::animationCanBeRemoved): (WebCore::DocumentTimeline::transitionDidComplete): (WebCore::DocumentTimeline::computeExtentOfAnimation const): (WebCore::DocumentTimeline::isRunningAnimationOnRenderer const): (WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const): (WebCore::DocumentTimeline::animatedStyleForRenderer): (WebCore::DocumentTimeline::runningAnimationsForRendererAreAllAccelerated const): (WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Deleted. * animation/DocumentTimeline.h: * animation/ElementAnimationRareData.cpp: (WebCore::ElementAnimationRareData::ElementAnimationRareData): * animation/ElementAnimationRareData.h: (WebCore::ElementAnimationRareData::pseudoId const): * animation/KeyframeEffect.cpp: (WebCore::elementOrPseudoElementForStyleable): (WebCore::invalidateElement): (WebCore::KeyframeEffect::animationTimelineDidChange): (WebCore::KeyframeEffect::updateEffectStackMembership): (WebCore::KeyframeEffect::targetStyleable const): (WebCore::KeyframeEffect::setTarget): (WebCore::KeyframeEffect::setPseudoElement): (WebCore::KeyframeEffect::didChangeTargetStyleable): (WebCore::KeyframeEffect::invalidate): (WebCore::KeyframeEffect::applyPendingAcceleratedActions): (WebCore::KeyframeEffect::didChangeTargetElementOrPseudoElement): Deleted. * animation/KeyframeEffect.h: * animation/KeyframeEffectStack.cpp: (WebCore::KeyframeEffectStack::addEffect): * animation/WebAnimation.cpp: (WebCore::WebAnimation::setEffectInternal): (WebCore::WebAnimation::setTimeline): (WebCore::WebAnimation::effectTargetDidChange): (WebCore::WebAnimation::persist): (WebCore::WebAnimation::commitStyles): * animation/WebAnimation.h: * animation/WebAnimationUtilities.cpp: (WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder): (WebCore::compareCSSTransitions): (WebCore::compareCSSAnimations): * dom/Element.cpp: (WebCore::Element::removedFromAncestor): (WebCore::Element::animationRareData const): (WebCore::Element::ensureAnimationRareData): (WebCore::Element::keyframeEffectStack const): (WebCore::Element::ensureKeyframeEffectStack): (WebCore::Element::hasKeyframeEffects const): (WebCore::Element::applyKeyframeEffects): (WebCore::Element::animations const): (WebCore::Element::hasCompletedTransitionsForProperty const): (WebCore::Element::hasRunningTransitionsForProperty const): (WebCore::Element::hasRunningTransitions const): (WebCore::Element::ensureAnimations): (WebCore::Element::animationsCreatedByMarkup): (WebCore::Element::setAnimationsCreatedByMarkup): (WebCore::Element::ensureCompletedTransitionsByProperty): (WebCore::Element::ensureRunningTransitionsByProperty): (WebCore::Element::lastStyleChangeEventStyle const): (WebCore::Element::setLastStyleChangeEventStyle): (WebCore::Element::getAnimations): * dom/Element.h: * dom/ElementRareData.cpp: * dom/ElementRareData.h: (WebCore::ElementRareData::useTypes const): (WebCore::ElementRareData::animationRareData const): (WebCore::ElementRareData::ensureAnimationRareData): (WebCore::ElementRareData::elementAnimationRareData): Deleted. * dom/PseudoElement.cpp: (WebCore::PseudoElement::clearHostElement): (WebCore::PseudoElement::isTargetedByKeyframeEffectRequiringPseudoElement): * rendering/RenderBoxModelObject.cpp: (WebCore::RenderBoxModelObject::hasRunningAcceleratedAnimations const): * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::requiresCompositingForAnimation const): (WebCore::RenderLayerCompositor::isRunningTransformAnimation const): * rendering/style/RenderStyleConstants.cpp: (WebCore::operator<<): * rendering/updating/RenderTreeUpdater.cpp: (WebCore::RenderTreeUpdater::tearDownRenderers): * style/StyleTreeResolver.cpp: (WebCore::Style::TreeResolver::resolveElement): (WebCore::Style::TreeResolver::resolvePseudoStyle): (WebCore::Style::TreeResolver::createAnimatedElementUpdate): * style/StyleTreeResolver.h: * style/Styleable.h: Added. (WebCore::Styleable::Styleable): (WebCore::Styleable::fromElement): (WebCore::Styleable::fromRenderer): (WebCore::Styleable::operator== const): (WebCore::Styleable::operator!= const): (WebCore::Styleable::keyframeEffectStack const): (WebCore::Styleable::ensureKeyframeEffectStack const): (WebCore::Styleable::hasKeyframeEffects const): (WebCore::Styleable::applyKeyframeEffects const): (WebCore::Styleable::animations const): (WebCore::Styleable::hasCompletedTransitionsForProperty const): (WebCore::Styleable::hasRunningTransitionsForProperty const): (WebCore::Styleable::hasRunningTransitions const): (WebCore::Styleable::ensureAnimations const): (WebCore::Styleable::ensureCompletedTransitionsByProperty const): (WebCore::Styleable::ensureRunningTransitionsByProperty const): (WebCore::Styleable::animationsCreatedByMarkup const): (WebCore::Styleable::setAnimationsCreatedByMarkup const): (WebCore::Styleable::lastStyleChangeEventStyle const): (WebCore::Styleable::setLastStyleChangeEventStyle const): LayoutTests: <rdar://problem/69511682> Reviewed by Antti Koivisto. Update a couple of tests which relied on an internals method to get a pseudo element and instead use the Web Animations API to determine whether a given animation targets a pseudo-element. This has the added benefit of having the same code run in a testing environment as in a regular browser. * fast/css-generated-content/pseudo-animation.html: * fast/css-generated-content/pseudo-transition.html: Canonical link: https://commits.webkit.org/229750@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267571 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-09-25 15:22:00 +00:00
bool runningAnimationsForRendererAreAllAccelerated(const RenderBoxModelObject&) const;
[Web Animations] Implement getAnimations() https://bugs.webkit.org/show_bug.cgi?id=179535 <rdar://problem/34932475> Reviewed by Simon Fraser. Source/WebCore: We now allow a list of animations for a document, with Document.getAnimations(), or for an element, with Animatable.getAnimations(), to be returned. In order to support this, we maintain a map on AnimationTimeline of all animations for a given element. This map is invalidated when an animation's timeline changes and when an animation's effect changes. Note that the Web Animations spec mandates that an AnimationEffect can only be a single animation's effect. Tests: http/wpt/wk-web-animations/interfaces/document-get-animations.html http/wpt/wk-web-animations/interfaces/element-get-animations.html http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html * CMakeLists.txt: Add Animatable.idl. * DerivedSources.make: Add Animatable.idl. * WebCore.xcodeproj/project.pbxproj: Add Animatable.idl. * animation/Animatable.idl: A new interface that Element implements and which currently only exposes getAnimations(), the animate() method will be added later. * animation/AnimationEffect.h: Add a new m_animation member to reference the animation using this effect. This relationship is required so we guarantee that an effect is associated with a single animation at most. (WebCore::AnimationEffect::animation const): (WebCore::AnimationEffect::setAnimation): * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::animationWasAddedToElement): New method to notify the timeline that an animation registered with this timeline has been associated with a new element through its effect. (WebCore::AnimationTimeline::animationWasRemovedFromElement): New method to notify the timeline that an animation registered with this timeline has been disassociated with an element through its effect. (WebCore::AnimationTimeline::animationsForElement): New method returning all animations registered with this timeline for a given element. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::animations const): All animations registered with this timeline. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::detachFromDocument): Clear the reference between this timeline and its document. (WebCore::DocumentTimeline::currentTime): Protect against a null Document reference. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Protect against a null Document reference. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): (WebCore::WebAnimation::setEffect): As an animation's effect changes, we need to ensure that the old effect no longer has an associated animation, and that the new effect is associated with this animation. Additionally, we update the element-to-animations map on the animation's timeline. (WebCore::WebAnimation::setTimeline): Update the element-to-animations map on the former and new timeline. * dom/Document.cpp: (WebCore::Document::prepareForDestruction): Clear the relationship between this document and its timeline. (WebCore::Document::getAnimations): Obtain all animations associated with this document's timeline. * dom/Document.h: * dom/Document.idl: * dom/Element.cpp: (WebCore::Element::getAnimations): Obtain all animations associated with this element. * dom/Element.h: * dom/Element.idl: * testing/Internals.cpp: * CMakeLists.txt: * DerivedSources.make: * WebCore.xcodeproj/project.pbxproj: * animation/Animatable.idl: * animation/AnimationEffect.h: (WebCore::AnimationEffect::animation const): (WebCore::AnimationEffect::setAnimation): * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::animationWasAddedToElement): (WebCore::AnimationTimeline::animationWasRemovedFromElement): (WebCore::AnimationTimeline::animationsForElement): * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::animations const): * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::detachFromDocument): (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): (WebCore::WebAnimation::setEffect): (WebCore::WebAnimation::setTimeline): * dom/Document.cpp: (WebCore::Document::prepareForDestruction): (WebCore::Document::getAnimations): * dom/Document.h: * dom/Document.idl: * dom/Element.cpp: (WebCore::Element::getAnimations): * dom/Element.h: * dom/Element.idl: * testing/Internals.cpp: LayoutTests: Update WPT expectations per new progressions and add three new tests that check the behavior of Document.getAnimations(), Element.getAnimations() and the unique relationship between an Animation and an AnimationEffect. * http/wpt/web-animations/interfaces/Animatable/animate-expected.txt: * http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt: * http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt: * http/wpt/wk-web-animations/interfaces/document-get-animations-expected.txt: Added. * http/wpt/wk-web-animations/interfaces/document-get-animations.html: Added. * http/wpt/wk-web-animations/interfaces/element-get-animations-expected.txt: Added. * http/wpt/wk-web-animations/interfaces/element-get-animations.html: Added. * http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship-expected.txt: Added. * http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html: Added. Canonical link: https://commits.webkit.org/195647@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-13 19:14:47 +00:00
void detachFromDocument();
[Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline https://bugs.webkit.org/show_bug.cgi?id=207364 <rdar://problem/59370413> Reviewed by Simon Fraser. LayoutTests/imported/w3c: There are some progressions but also some "regressions". The progressions are real, showing the delivery of all animation events at the correct time. However, the regressions are misleading. The fact that the "style change" tests would work was due to a design issue in the test which would only wait one frame to detect whether a CSS Transition was started after a change made through the Web Animations API. These would work because events were queued in the next frame, but delivered later due to the dedicated per-animation queue used, which meant the test was fooled into thinking the CSS Transition did not start, as expected. Changing those test to use more than one frame to test for the lack of a CSS Transition would have shown the FAIL results. However, in order to not regress our WPT score, the issue of "style change" events will be addressed in a follow-up patch. * web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt: * web-platform-tests/web-animations/interfaces/Animatable/animate-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt: * web-platform-tests/web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt: * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: Until now, AnimationPlaybackEvent events, which are new events introduced by the Web Animations spec, were enqueued in a shared queue on the DocumentTimeline and dispatched during the "update animations and send events" procedure. However, AnimationEvent and TransitionEvent events, dispatched by CSS Animations and CSS Transitions, were dispatched via a dedicated per-animation queue, which meant typically that those events were dispathed one runloop after the AnimationPlaybackEvent events. We now remove the dedicated per-animation queue and enqueue all events in the shared DocumentTimeline queue for dispatch during the "update animations and send events" procedure. To do this correctly, we need to do a couple of other things that ensure we don't regress tests. First, we update the DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() to account for whether there are pending animation events, guaranteeing that an animation update is scheduled should there be any. Second, when animation events are enqueued in DocumentTimeline::enqueueAnimationEvent() we schedule an animation update if needed, since we know we now have pending events that will need to be delivered in an upcoming update. We also maintain a flag between the start of the "update animations and send events" procedure and the moment when the pending animation events queue is cleared prior to dispatching events so that events enqueued in the meantime do not prematurely schedule animation resolution. The need for a new animation resolution will be checked at the end of the procedure. Finally, declarative animations used to have a special suclass of WebAnimation::needsTick() that would check whether they had any pending events, ensuring they would not be removed prematurely. We now reset a flag to false as WebAnimation::tick() is called (as part of the "update animations and send events" procedure) and set it to true in case an animation is enqueued. This flag is then used in needsTick() to guarantee the animation is not removed before the DocumentTimeline has had a chance to dispatch the enqueued event. Note also that, for clarity, the DocumentTimeline::unscheduleAnimationResolution() was renamed to DocumentTimeline::clearTickScheduleTimer() since it wouldn't actually cancel a previous animation resolution schedule. * animation/CSSTransition.h: Fix a newly found build error due to the missing wtf/MonotonicTime.h header. * animation/DeclarativeAnimation.cpp: Remove all code related to the dedicated per-animation queue and instead call the new WebAnimation::enqueueAnimationEvent() method to enqueue events on the DocumentTimeline. (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::tick): (WebCore::DeclarativeAnimation::enqueueDOMEvent): * animation/DeclarativeAnimation.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): Ensure the pending events queue is cleared when the timeline is detached from a document, ensuring that there no longer events that would cause a ref-cycle (DocumentTimeline -> AnimationPlaybackEvent -> WebAnimation -> DocumentTimeline). (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::removeAnimation): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::clearTickScheduleTimer): (WebCore::DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState const): (WebCore::DocumentTimeline::updateCurrentTime): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): (WebCore::DocumentTimeline::enqueueAnimationEvent): * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::enqueueAnimationPlaybackEvent): (WebCore::WebAnimation::enqueueAnimationEvent): (WebCore::WebAnimation::needsTick const): (WebCore::WebAnimation::tick): * animation/WebAnimation.h: LayoutTests: Fix a couple of tests that made some incorrect assumptions. * TestExpectations: imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is no longer flaky. * compositing/backing/animate-into-view.html: Because the "animationstart" event is now dispatched during the "update animations and send events" procedure, which happens during page rendering _before_ rAF callbacks are serviced, we must remove the rAF callback used prior to adding the "animationstart" event listener or else we would never get it and the test would time out. * webanimations/css-transition-in-flight-reversal-accelerated.html: We must wait for the initial transition to start and then two frames before reversing the transition, to be certain that the animation did start. Indeed, the "transitionstart" event will be fired right before the next rAF callback is called, as the animation starts in that very same frame, and so progress will be 0 and the transition wouldn't be reversable until the next frame when the animation has progress > 0. Canonical link: https://commits.webkit.org/220724@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@256619 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-14 17:52:07 +00:00
void enqueueAnimationEvent(AnimationEventBase&);
requestAnimationFrame should execute before the next frame https://bugs.webkit.org/show_bug.cgi?id=177484 Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2019-04-10 Reviewed by Simon Fraser. LayoutTests/imported/w3c: Add trace points for the page RenderingUpdate. * web-platform-tests/resize-observer/resources/resizeTestHelper.js: Change ResizeTestHelper.TIMEOUT to be 1 second instead of 100 ms which is too short for layout tests. Source/WebCore: This change fixes these issues with animation timing: 1. Calling the requestAnimationFrame callbacks would have happened when the DisplayLink fires. This may have happened even if the frame is missed and no display is committed. 2. Style changes and layout triggered by script could trigger painting at more than 60fps. CoreAnimation commits could happen at more than 60fps, although WindowServer will throttle those, and only some will be shown on the screen. This change introduces a new paint scheduling model where painting is driven by a "RenderingUpdateScheduler", which only triggers paints once per 16.7ms frame. Code that previously scheduled a compositing layer flush now schedules a "RenderingUpdate", and that update is driven by a DisplayRefreshMonitor callback. When the render happens, we service requestAnimationFrame callbacks, Web Animations, intersection observations and resize observations per the "Update the rendering" step of the HTML Event Loop specification: <https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>. In the future, more rendering steps will be added to this code. * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * accessibility/mac/AXObjectCacheMac.mm: (WebCore::AXObjectCache::platformHandleFocusedUIElementChanged): Fix layout tests by adding null check. * animation/DocumentAnimationScheduler.cpp: Removed. * animation/DocumentAnimationScheduler.h: Removed. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::updateThrottlingState): (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::resumeAnimations): (WebCore::DocumentTimeline::liveCurrentTime const): (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::cacheCurrentTime): (WebCore::DocumentTimeline::animationTimingDidChange): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::unscheduleAnimationResolution): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Simplify this function by handling the case of no-animations separately. (WebCore::DocumentTimeline::resolveAnimationsForElement): Simplify the loop and delete hasPendingAcceleratedAnimations because it is initialized to true and is not changed inside the loop. (WebCore::DocumentTimeline::scheduleAnimationResolutionIfNeeded): Deleted. (WebCore::DocumentTimeline::animationResolutionTimerFired): Deleted. * animation/DocumentTimeline.h: * dom/Document.cpp: (WebCore::Document::resolveStyle): There is no need to force update in resolveStyle(). notifyFlushRequired() will be called eventually which will scheduleRenderingUpdate(). (WebCore::Document::prepareForDestruction): (WebCore::Document::updateAnimationsAndSendEvents): (WebCore::Document::serviceRequestAnimationFrameCallbacks): (WebCore::Document::windowScreenDidChange): (WebCore::Document::scheduleRenderingUpdate): (WebCore::Document::updateIntersectionObservations): (WebCore::Document::addResizeObserver): (WebCore::Document::updateResizeObservations): (WebCore::Document::scheduleForcedIntersectionObservationUpdate): Deleted. (WebCore::Document::scheduleResizeObservations): Deleted. (WebCore::Document::animationScheduler): Deleted. No need to schedule web-animations, intersection observations and resize observations updates separately. All of them will be updated through the "Update the rendering" step, i.e. Page::updateRendering(). * dom/Document.h: (WebCore::Document::numberOfIntersectionObservers const): * dom/ScriptedAnimationController.cpp: (WebCore::ScriptedAnimationController::serviceRequestAnimationFrameCallbacks): (WebCore::ScriptedAnimationController::scheduleAnimation): (WebCore::ScriptedAnimationController::animationTimerFired): (WebCore::ScriptedAnimationController::serviceScriptedAnimations): Deleted. (WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire): Deleted. * dom/ScriptedAnimationController.h: * page/FrameView.cpp: (WebCore::FrameView::didLayout): (WebCore::FrameView::viewportContentsChanged): * page/FrameViewLayoutContext.cpp: (WebCore::FrameViewLayoutContext::layoutTimerFired): * page/IntersectionObserver.cpp: (WebCore::IntersectionObserver::observe): * page/Page.cpp: (WebCore::Page::Page): (WebCore::Page::layoutIfNeeded): (WebCore::Page::updateRendering): (WebCore::Page::renderingUpdateScheduler): (WebCore::Page::willDisplayPage): Deleted. (WebCore::Page::addDocumentNeedingIntersectionObservationUpdate): Deleted. (WebCore::Page::updateIntersectionObservations): Deleted. (WebCore::Page::scheduleForcedIntersectionObservationUpdate): Deleted. (WebCore::Page::hasResizeObservers const): Deleted. (WebCore::Page::gatherDocumentsNeedingResizeObservationCheck): Deleted. (WebCore::Page::checkResizeObservations): Deleted. (WebCore::Page::scheduleResizeObservations): Deleted. (WebCore::Page::notifyResizeObservers): Deleted. * page/Page.h: (WebCore::Page::setNeedsCheckResizeObservations): Deleted. (WebCore::Page::needsCheckResizeObservations const): Deleted. The IntersectionObserver and the ResizeObserver do not need to schedule their own timers. The RenderingUpdateScheduler will schedule the "Update the rendering" step in which these obverses will be served. * page/PageOverlayController.cpp: (WebCore::PageOverlayController::didChangeViewExposedRect): (WebCore::PageOverlayController::notifyFlushRequired): Force committing the layers to be 60 fps at maximum. * page/RenderingUpdateScheduler.cpp: Added. (WebCore::RenderingUpdateScheduler::RenderingUpdateScheduler): (WebCore::RenderingUpdateScheduler::scheduleRenderingUpdate): (WebCore::RenderingUpdateScheduler::isScheduled const): (WebCore::RenderingUpdateScheduler::startTimer): (WebCore::RenderingUpdateScheduler::clearScheduled): (WebCore::RenderingUpdateScheduler::createDisplayRefreshMonitor const): (WebCore::RenderingUpdateScheduler::windowScreenDidChange): (WebCore::RenderingUpdateScheduler::displayRefreshFired): (WebCore::RenderingUpdateScheduler::scheduleCompositingLayerFlush): * page/RenderingUpdateScheduler.h: Added. (WebCore::RenderingUpdateScheduler::create): * page/ResizeObserver.cpp: (WebCore::ResizeObserver::observe): (WebCore::ResizeObserver::scheduleObservations): Deleted. * page/ResizeObserver.h: (WebCore::ResizeObserver::hasActiveObservations const): * page/ios/ContentChangeObserver.h: * page/mac/ServicesOverlayController.mm: (WebCore::ServicesOverlayController::Highlight::notifyFlushRequired): * page/scrolling/ScrollingStateTree.cpp: * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::scheduleLayerFlushNow): (WebCore::RenderLayerCompositor::layerTreeAsText): Source/WebKit: Replace the calls to Page::layoutIfNeeded() and willDisplayPage() by a single call to Page::updateRendering(). This new function implements "Update the rendering" step of the HTML Event Loop specification <https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>. * WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp: (WebKit::DrawingAreaCoordinatedGraphics::scheduleCompositingLayerFlush): (WebKit::DrawingAreaCoordinatedGraphics::updateBackingStoreState): (WebKit::DrawingAreaCoordinatedGraphics::display): * WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp: (WebKit::LayerTreeHost::layerFlushTimerFired): * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm: (WebKit::RemoteLayerTreeDrawingArea::flushLayers): -- Call Page::updateRendering() to make sure that "Update the rendering" happens immediately before updating the page. -- Move the call to RemoteLayerBackingStoreCollection::willFlushLayers() to be exactly before flushing the layers. This fixes the assertion ASSERT(m_inLayerFlush) which was firing when running a layout test. RemoteLayerTreeDrawingArea::flushLayers() now can call itself through TestRunner::notifyDone(). flushLayers() was calling willFlushLayers() twice before calling didFlushLayers(). * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::layoutIfNeeded): (WebKit::WebPage::updateRendering): (WebKit::WebPage::willDisplayPage): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _viewWillDrawInternal]): (-[WebView _flushCompositingChanges]): Call Page::updateRendering() which implements "Update the rendering" step of the HTML Event Loop specification. Source/WebKitLegacy/win: * WebView.cpp: (WebView::updateBackingStore): (WebView::flushPendingGraphicsLayerChangesSoon): (WebView::flushPendingGraphicsLayerChanges): Call Page::updateRendering() which implements "Update the rendering" step of the HTML Event Loop specification. Source/WTF: Add trace points for the page RenderingUpdate. * wtf/SystemTracing.h: Tools: Add trace points for the page RenderingUpdate. * Tracing/SystemTracePoints.plist: LayoutTests: * TestExpectations: There is a slight difference between the actual DRT and the expected DRT due to animation timing change. But these two tests are not animating correctly if they are opened in Safari with web animation turned on. * accessibility/mac/selection-notification-focus-change-expected.txt: * accessibility/mac/selection-notification-focus-change.html: Remove the debug statements form notificationCallback() since the number of times this function is called back and the order of notifications are not defined. This test has been flaky and some trials were made to make it more reliable. With this change it became flaky again. * animations/animation-multiple-callbacks-timestamp.html: Fix variable names used by an error message. * animations/no-style-recalc-during-accelerated-animation-expected.txt: * animations/no-style-recalc-during-accelerated-animation.html: One extra styleReclc was incurred due to the document styleRecalcTimer. I think this timer is not needed anymore. I will look at removing it in a separate patch. * animations/resources/animation-test-helpers.js: (waitForAnimationToStart): The expectation that animation will start at the beginning of the next event loop is not true anymore. The animation will start at the time the requestAnimationFrame fires. * compositing/video/video-clip-change-src.html: This test loads a video data and pushes it to the encoder. Originally it used to wait 150 ms after receiving the second canplaythrough. I had to change this timing to 250 ms. * css3/filters/composited-during-animation.html: Ditto. setTimeout({...}, 0) versus requestAnimationFrame. * media/media-controls-accessibility.html: Updating the accessibility button happens asynchronously, see [WebAccessibilityObjectWrapper accessibilityPerformPressAction]. Due to changing the page update timing, this test became flaky. Originally it used to setTimeout({...}, 10) to ensure the stringValue of the mutate button was changed after it was pressed. The fix is to loop using rAF till the stringValue changes. * platform/mac-wk2/accessibility/mac/selection-notification-focus-change-expected.txt: Removed. The number of time notificationCallback() is called and the order of notifications are not defined. And this is why we have two expected files: one for WK1 and the other for WK2. Since the test is now simplified, we can get rid of this duplication. We will test the minimum reliable thing we can test. Canonical link: https://commits.webkit.org/211093@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-11 05:44:13 +00:00
[Web Animations] Coordinate "update animations and send events" procedure across multiple timelines https://bugs.webkit.org/show_bug.cgi?id=202109 <rdar://problem/59470821> Reviewed by Dean Jackson. LayoutTests/imported/w3c: Mark a new test as PASS which shows that we correctly perform a single microstask checkpoint when updating multiple timelines. * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: So far, although we did manage multiple animation timelines per document, we mostly operated under the assumption that there really was a single timeline. In this patch we make the "update animations and send events" procedure, which is central to the lifecycle of animations, work with multiple timelines such that a single microtask checkpoint is performed even with multiple timelines, whereas we would perform one per timeline before. To do this, we move much of the logic DocumentTimeline::updateAnimationsAndSendEvents() to DocumentTimelinesController where each step is run across each timeline, rather than running all steps for each timeline one after the other, respecting the single microtask checkpoint in the middle of the process. To minimize code churn at this stage, we still keep a fair bit of logic in DocumentTimeline and, while we remove updateAnimationsAndSendEvents(), internalUpdateAnimationsAndSendEvents() and updateCurrentTime(), we expose three methods that allow to run the pre-flight sequence in documentWillUpdateAnimationsAndSendEvents(), collect pending events in prepareForPendingAnimationEventsDispatch() and run the post-flight sequence in documentDidUpdateAnimationsAndSendEvents(). None of the logic changes, this is just moving code around. In the future, more patches will move code from DocumentTimeline up to DocumentTimelinesController such that events are enqueued there, and animation scheduling as well. But this already lets us pass a new test that used to flakily reject promises in the WPT test web-animations/timing-model/timelines/update-and-send-events.html. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::relevantAnimations const): (WebCore::AnimationTimeline::allAnimations const): * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::documentDidUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::prepareForPendingAnimationEventsDispatch): (WebCore::DocumentTimeline::updateCurrentTime): Deleted. (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): Deleted. (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): Deleted. * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: (WebCore::DocumentTimelinesController::DocumentTimelinesController): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): * animation/DocumentTimelinesController.h: * animation/WebAnimationTypes.h: * dom/Document.cpp: (WebCore::Document::ensureTimelinesController): LayoutTests: Remove the flaky expectation for the improved test. * TestExpectations: Canonical link: https://commits.webkit.org/223759@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260525 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 18:47:36 +00:00
enum class ShouldUpdateAnimationsAndSendEvents : uint8_t { Yes, No };
[Web Animations] imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is a flaky failure https://bugs.webkit.org/show_bug.cgi?id=211232 <rdar://problem/62650227> Reviewed by Dean Jackson. The flakiness came from this porting of the test: animA.finished.then(() => { animB.cancel() }); animB.finished.then(() => { animA.cancel() }); Sometimes, animA and animB would finish in different frames even though they were designed to finish at the same time. If this happened, animA.finished would resolve and trigger animB.cancel, which then rejected animB.finished. This happened because animB was attached to a DocumentTimeline created by script which isn't the main DocumenTimeline accessed via document.timeline. Some curious code would handle syncing of the various timelines such that they would use a shared timebase. This was in DocumentTimeline::currentTime(): auto& mainDocumentTimeline = m_document->timeline(); if (&mainDocumentTimeline != this) { if (auto mainDocumentTimelineCurrentTime = mainDocumentTimeline.currentTime()) return *mainDocumentTimelineCurrentTime - m_originTime; return WTF::nullopt; } We now move the currentTime caching at the DocumentTimelinesController level which ensures all DocumentTimeline objects attached to a given Document use the exact same currentTime(). This prompted some overdue refactoring where also all the related animation suspension code is moved from DocumentTimeline up to DocumentTimelinesController. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::resumeAnimations): (WebCore::DocumentTimeline::animationsAreSuspended const): (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::animationsAreSuspended): Deleted. (WebCore::DocumentTimeline::liveCurrentTime const): Deleted. (WebCore::DocumentTimeline::cacheCurrentTime): Deleted. (WebCore::DocumentTimeline::maybeClearCachedCurrentTime): Deleted. * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: (WebCore::DocumentTimelinesController::detachFromDocument): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): (WebCore::DocumentTimelinesController::suspendAnimations): (WebCore::DocumentTimelinesController::resumeAnimations): (WebCore::DocumentTimelinesController::animationsAreSuspended const): (WebCore::DocumentTimelinesController::liveCurrentTime const): (WebCore::DocumentTimelinesController::currentTime): (WebCore::DocumentTimelinesController::cacheCurrentTime): (WebCore::DocumentTimelinesController::maybeClearCachedCurrentTime): * animation/DocumentTimelinesController.h: * dom/Document.cpp: (WebCore::Document::didBecomeCurrentDocumentInFrame): (WebCore::Document::resume): * dom/Document.h: * page/Frame.cpp: (WebCore::Frame::clearTimers): (WebCore::Frame::resumeActiveDOMObjectsAndAnimations): * page/Page.cpp: (WebCore::Page::setIsVisibleInternal): (WebCore::Page::hiddenPageCSSAnimationSuspensionStateChanged): * testing/Internals.cpp: (WebCore::Internals::animationsAreSuspended const): (WebCore::Internals::suspendAnimations const): (WebCore::Internals::resumeAnimations const): Canonical link: https://commits.webkit.org/224501@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261336 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-07 21:44:13 +00:00
ShouldUpdateAnimationsAndSendEvents documentWillUpdateAnimationsAndSendEvents();
[Web Animations] Coordinate "update animations and send events" procedure across multiple timelines https://bugs.webkit.org/show_bug.cgi?id=202109 <rdar://problem/59470821> Reviewed by Dean Jackson. LayoutTests/imported/w3c: Mark a new test as PASS which shows that we correctly perform a single microstask checkpoint when updating multiple timelines. * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: So far, although we did manage multiple animation timelines per document, we mostly operated under the assumption that there really was a single timeline. In this patch we make the "update animations and send events" procedure, which is central to the lifecycle of animations, work with multiple timelines such that a single microtask checkpoint is performed even with multiple timelines, whereas we would perform one per timeline before. To do this, we move much of the logic DocumentTimeline::updateAnimationsAndSendEvents() to DocumentTimelinesController where each step is run across each timeline, rather than running all steps for each timeline one after the other, respecting the single microtask checkpoint in the middle of the process. To minimize code churn at this stage, we still keep a fair bit of logic in DocumentTimeline and, while we remove updateAnimationsAndSendEvents(), internalUpdateAnimationsAndSendEvents() and updateCurrentTime(), we expose three methods that allow to run the pre-flight sequence in documentWillUpdateAnimationsAndSendEvents(), collect pending events in prepareForPendingAnimationEventsDispatch() and run the post-flight sequence in documentDidUpdateAnimationsAndSendEvents(). None of the logic changes, this is just moving code around. In the future, more patches will move code from DocumentTimeline up to DocumentTimelinesController such that events are enqueued there, and animation scheduling as well. But this already lets us pass a new test that used to flakily reject promises in the WPT test web-animations/timing-model/timelines/update-and-send-events.html. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::relevantAnimations const): (WebCore::AnimationTimeline::allAnimations const): * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::documentDidUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::prepareForPendingAnimationEventsDispatch): (WebCore::DocumentTimeline::updateCurrentTime): Deleted. (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): Deleted. (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): Deleted. * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: (WebCore::DocumentTimelinesController::DocumentTimelinesController): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): * animation/DocumentTimelinesController.h: * animation/WebAnimationTypes.h: * dom/Document.cpp: (WebCore::Document::ensureTimelinesController): LayoutTests: Remove the flaky expectation for the improved test. * TestExpectations: Canonical link: https://commits.webkit.org/223759@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260525 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 18:47:36 +00:00
void removeReplacedAnimations();
AnimationEvents prepareForPendingAnimationEventsDispatch();
void documentDidUpdateAnimationsAndSendEvents();
[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): Canonical link: https://commits.webkit.org/202231@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233140 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-06-25 09:54:34 +00:00
WEBCORE_EXPORT Seconds animationInterval() const;
[Web Animations] imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is a flaky failure https://bugs.webkit.org/show_bug.cgi?id=211232 <rdar://problem/62650227> Reviewed by Dean Jackson. The flakiness came from this porting of the test: animA.finished.then(() => { animB.cancel() }); animB.finished.then(() => { animA.cancel() }); Sometimes, animA and animB would finish in different frames even though they were designed to finish at the same time. If this happened, animA.finished would resolve and trigger animB.cancel, which then rejected animB.finished. This happened because animB was attached to a DocumentTimeline created by script which isn't the main DocumenTimeline accessed via document.timeline. Some curious code would handle syncing of the various timelines such that they would use a shared timebase. This was in DocumentTimeline::currentTime(): auto& mainDocumentTimeline = m_document->timeline(); if (&mainDocumentTimeline != this) { if (auto mainDocumentTimelineCurrentTime = mainDocumentTimeline.currentTime()) return *mainDocumentTimelineCurrentTime - m_originTime; return WTF::nullopt; } We now move the currentTime caching at the DocumentTimelinesController level which ensures all DocumentTimeline objects attached to a given Document use the exact same currentTime(). This prompted some overdue refactoring where also all the related animation suspension code is moved from DocumentTimeline up to DocumentTimelinesController. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::resumeAnimations): (WebCore::DocumentTimeline::animationsAreSuspended const): (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::animationsAreSuspended): Deleted. (WebCore::DocumentTimeline::liveCurrentTime const): Deleted. (WebCore::DocumentTimeline::cacheCurrentTime): Deleted. (WebCore::DocumentTimeline::maybeClearCachedCurrentTime): Deleted. * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: (WebCore::DocumentTimelinesController::detachFromDocument): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): (WebCore::DocumentTimelinesController::suspendAnimations): (WebCore::DocumentTimelinesController::resumeAnimations): (WebCore::DocumentTimelinesController::animationsAreSuspended const): (WebCore::DocumentTimelinesController::liveCurrentTime const): (WebCore::DocumentTimelinesController::currentTime): (WebCore::DocumentTimelinesController::cacheCurrentTime): (WebCore::DocumentTimelinesController::maybeClearCachedCurrentTime): * animation/DocumentTimelinesController.h: * dom/Document.cpp: (WebCore::Document::didBecomeCurrentDocumentInFrame): (WebCore::Document::resume): * dom/Document.h: * page/Frame.cpp: (WebCore::Frame::clearTimers): (WebCore::Frame::resumeActiveDOMObjectsAndAnimations): * page/Page.cpp: (WebCore::Page::setIsVisibleInternal): (WebCore::Page::hiddenPageCSSAnimationSuspensionStateChanged): * testing/Internals.cpp: (WebCore::Internals::animationsAreSuspended const): (WebCore::Internals::suspendAnimations const): (WebCore::Internals::resumeAnimations const): Canonical link: https://commits.webkit.org/224501@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261336 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-07 21:44:13 +00:00
void suspendAnimations();
void resumeAnimations();
bool animationsAreSuspended() const;
[Web Animations] Suspend animations when required https://bugs.webkit.org/show_bug.cgi?id=184541 Reviewed by Jon Lee. Source/WebCore: Animations managed by CSSAnimationController get suspended under a number of scenarios, we now add the possibility to suspend animations on a DocumentTimeline as well such that Web Animations and CSS Animations and CSS Transitions implemented as Web Animations get suspended under the same conditions as well. We also update the implementation for Internals::numberOfActiveAnimations() such that tests checking that animations get suspended pass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::suspendAnimations): When asked to be suspended, the DocumentTimeline cancels pending invalidation tasks and updates all of the animations it manages, including those running on the compositor. (WebCore::DocumentTimeline::resumeAnimations): When asked to be resumed, the DocumentTimeline resumes animations it manages and rewinds its invalidation timer. (WebCore::DocumentTimeline::animationsAreSuspended): (WebCore::DocumentTimeline::numberOfActiveAnimationsForTesting const): Called by Internals::numberOfActiveAnimations(), this returns the number of animations managed by this timeline that are not suspended. (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::timingModelDidChange): Ensure the invalidation timer is not rewound if the timeline is suspended. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::setTimeline): When moving to a new timeline, ensure we match the new timeline's animation state. (WebCore::WebAnimation::setSuspended): Toggle the accelerated running state of any backing hardware animations when the suspension state of an animation changes. * animation/WebAnimation.h: (WebCore::WebAnimation::isSuspended const): * dom/Document.cpp: (WebCore::Document::didBecomeCurrentDocumentInFrame): (WebCore::Document::resume): * dom/Document.h: * history/CachedFrame.cpp: (WebCore::CachedFrameBase::restore): * page/Frame.cpp: (WebCore::Frame::clearTimers): * page/Page.cpp: (WebCore::Page::setIsVisibleInternal): (WebCore::Page::hiddenPageCSSAnimationSuspensionStateChanged): * testing/Internals.cpp: (WebCore::Internals::numberOfActiveAnimations const): (WebCore::Internals::animationsAreSuspended const): (WebCore::Internals::suspendAnimations const): (WebCore::Internals::resumeAnimations const): LayoutTests: Mark more tests as passing when the CSS Animations and CSS Transitions as Web Animations flag is on. * animations/animation-controller-drt-api.html: * animations/animation-followed-by-transition.html: * fast/animation/css-animation-resuming-when-visible-with-style-change.html: * fast/animation/css-animation-resuming-when-visible.html: Canonical link: https://commits.webkit.org/200093@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230581 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-12 17:37:55 +00:00
WEBCORE_EXPORT unsigned numberOfActiveAnimationsForTesting() const;
WEBCORE_EXPORT Vector<std::pair<String, double>> acceleratedAnimationsForElement(Element&) const;
[Web Animations] DocumentTimeline::updateAnimations() is called endlessly https://bugs.webkit.org/show_bug.cgi?id=189784 <rdar://problem/41705679> Reviewed by Dean Jackson. Source/WebCore: Test: webanimations/accelerated-animation-interruption-display-none.html We have code that keeps queueing pending accelerated actions for an animation that does not have a renderer until it has one so that we can deal with situations where animations are ready to commited before its composited renderer is available. This code ended up running continuously when an element with an accelerated animation had its renderer removed without the animation being removed itself, such as setting "display: none" on an element with an acceelerated CSS Animation targeting it. We fix this by queueing up a "Stop" accelerated action when updating the accelerated state if there is no renderer for the current animation target. Then, we no longer re-queue pending accelerated actions if the last queued operation is "Stop". This ensures that we no longer queue actions endlessly when there is no longer a visible animation. To test this, we add a new internals.numberOfAnimationTimelineInvalidations() method that indicates the number of times the current document's animation timeline was invalidated. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::updateAnimations): (WebCore::DocumentTimeline::numberOfAnimationTimelineInvalidationsForTesting const): * animation/DocumentTimeline.h: * animation/KeyframeEffectReadOnly.cpp: (WebCore::KeyframeEffectReadOnly::updateAcceleratedAnimationState): If the animation target does not have a renderer and it's still marked as running, enqueue a "Stop" accelerated action. (WebCore::KeyframeEffectReadOnly::addPendingAcceleratedAction): If we enqueue a "Stop" accelerated action, remove any other queued action so that we only process the "Stop" action, which would have superseded all previously queued actions anyway. (WebCore::KeyframeEffectReadOnly::applyPendingAcceleratedActions): Only re-queue pending accelerated actions when a composited renderer is not yet available if we don't have a "Stop" action queued. * testing/Internals.cpp: (WebCore::Internals::numberOfAnimationTimelineInvalidations const): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Add a new test that checks that setting "display: none" on an element with an accelerated CSS animation on it will no longer update the animation timeline. * webanimations/accelerated-animation-interruption-display-none-expected.txt: Added. * webanimations/accelerated-animation-interruption-display-none.html: Added. * platform/win/TestExpectations: Canonical link: https://commits.webkit.org/204777@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236308 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-21 11:28:40 +00:00
WEBCORE_EXPORT unsigned numberOfAnimationTimelineInvalidationsForTesting() const;
[Web Animations] Provide basic timeline and animation interfaces https://bugs.webkit.org/show_bug.cgi?id=178526 Patch by Antoine Quint <graouts@apple.com> on 2017-10-20 Reviewed by Dean Jackson. .: Remove the WEB_ANIMATIONS compile-time flag. * Source/cmake/OptionsWPE.cmake: * Source/cmake/OptionsWin.cmake: * Source/cmake/WebKitFeatures.cmake: * Source/cmake/tools/vsprops/FeatureDefines.props: * Source/cmake/tools/vsprops/FeatureDefinesCairo.props: Source/JavaScriptCore: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebCore: We're getting Web Animations work started by implementing a very minimal codebase which provides a DocumentTimeline class which has an instance created for each Document. The parent class, AnimationTimeline, allows for animations to be added and removed, and animations can be created using the Animation class, with an optional timeline as parameter. Tests: webanimations/animation-creation-basic.html webanimations/document-timeline.html * CMakeLists.txt: * Configurations/FeatureDefines.xcconfig: * DerivedSources.make: * PlatformWin.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: Added. (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::~AnimationTimeline): (WebCore::AnimationTimeline::addAnimation): (WebCore::AnimationTimeline::removeAnimation): * animation/AnimationTimeline.h: Added. (WebCore::AnimationTimeline::isDocumentTimeline const): (WebCore::AnimationTimeline::classType const): * animation/AnimationTimeline.idl: Added. * animation/DocumentTimeline.cpp: Added. (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: Added. * animation/DocumentTimeline.idl: Added. * animation/WebAnimation.cpp: Added. (WebCore::WebAnimation::create): (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::~WebAnimation): * animation/WebAnimation.h: Added. * animation/WebAnimation.idl: Added. * bindings/js/JSAnimationTimelineCustom.cpp: Added. (WebCore::toJSNewlyCreated): (WebCore::toJS): * bindings/js/WebCoreBuiltinNames.h: * dom/Document.cpp: (WebCore::Document::timeline): * dom/Document.h: * dom/Document.idl: * page/RuntimeEnabledFeatures.h: (WebCore::RuntimeEnabledFeatures::webAnimationsEnabled const): Source/WebCore/PAL: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebKit: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebProcess/InjectedBundle/InjectedBundle.cpp: (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): (WebKit::InjectedBundle::setWebAnimationsEnabled): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updatePreferences): Source/WebKitLegacy/mac: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Source/WebKitLegacy/win: Remove the WEB_ANIMATIONS compile-time flag. * WebView.cpp: (WebView::notifyPreferencesChanged): Source/WTF: Remove the WEB_ANIMATIONS compile-time flag. * wtf/FeatureDefines.h: Tools: Remove the WEB_ANIMATIONS compile-time flag. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: Basic test coverage to check that we are exposing a DocumentTimeline instance on the Document and that we can construct Animations, optionally associated with a timeline. * platform/mac-elcapitan/TestExpectations: * webanimations/animation-creation-basic-expected.txt: Added. * webanimations/animation-creation-basic.html: Added. * webanimations/document-timeline-expected.txt: Added. * webanimations/document-timeline.html: Added. Canonical link: https://commits.webkit.org/194785@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 18:41:23 +00:00
private:
DocumentTimeline(Document&, Seconds);
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
[Web Animations] Add a supporting object for Document to manage timelines https://bugs.webkit.org/show_bug.cgi?id=210817 Reviewed by Dean Jackson. Add a new DocumentTimelinesController object owned by Document to manage DocumentTimelines created for it. This simple piece of refactoring is the first step towards a coordinated "update animations and send events" procedure where all timelines are updated at once with a single microtask checkpoint instead of each timeline running one. No change in behavior, so no new tests. * Headers.cmake: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::~DocumentTimeline): (WebCore::DocumentTimeline::controller const): (WebCore::DocumentTimeline::detachFromDocument): * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: Added. (WebCore::DocumentTimelinesController::DocumentTimelinesController): (WebCore::DocumentTimelinesController::~DocumentTimelinesController): (WebCore::DocumentTimelinesController::addTimeline): (WebCore::DocumentTimelinesController::removeTimeline): (WebCore::DocumentTimelinesController::detachFromDocument): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): * animation/DocumentTimelinesController.h: Added. * dom/Document.cpp: (WebCore::Document::commonTeardown): (WebCore::Document::ensureTimelinesController): (WebCore::Document::updateAnimationsAndSendEvents): Deleted. (WebCore::Document::addTimeline): Deleted. (WebCore::Document::removeTimeline): Deleted. * dom/Document.h: (WebCore::Document::timelinesController const): * page/Page.cpp: (WebCore::Page::updateRendering): Canonical link: https://commits.webkit.org/223739@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260504 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 07:16:51 +00:00
DocumentTimelinesController* controller() const;
void applyPendingAcceleratedAnimations();
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
void scheduleInvalidationTaskIfNeeded();
void scheduleAnimationResolution();
[Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline https://bugs.webkit.org/show_bug.cgi?id=207364 <rdar://problem/59370413> Reviewed by Simon Fraser. LayoutTests/imported/w3c: There are some progressions but also some "regressions". The progressions are real, showing the delivery of all animation events at the correct time. However, the regressions are misleading. The fact that the "style change" tests would work was due to a design issue in the test which would only wait one frame to detect whether a CSS Transition was started after a change made through the Web Animations API. These would work because events were queued in the next frame, but delivered later due to the dedicated per-animation queue used, which meant the test was fooled into thinking the CSS Transition did not start, as expected. Changing those test to use more than one frame to test for the lack of a CSS Transition would have shown the FAIL results. However, in order to not regress our WPT score, the issue of "style change" events will be addressed in a follow-up patch. * web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt: * web-platform-tests/web-animations/interfaces/Animatable/animate-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt: * web-platform-tests/web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt: * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: Until now, AnimationPlaybackEvent events, which are new events introduced by the Web Animations spec, were enqueued in a shared queue on the DocumentTimeline and dispatched during the "update animations and send events" procedure. However, AnimationEvent and TransitionEvent events, dispatched by CSS Animations and CSS Transitions, were dispatched via a dedicated per-animation queue, which meant typically that those events were dispathed one runloop after the AnimationPlaybackEvent events. We now remove the dedicated per-animation queue and enqueue all events in the shared DocumentTimeline queue for dispatch during the "update animations and send events" procedure. To do this correctly, we need to do a couple of other things that ensure we don't regress tests. First, we update the DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() to account for whether there are pending animation events, guaranteeing that an animation update is scheduled should there be any. Second, when animation events are enqueued in DocumentTimeline::enqueueAnimationEvent() we schedule an animation update if needed, since we know we now have pending events that will need to be delivered in an upcoming update. We also maintain a flag between the start of the "update animations and send events" procedure and the moment when the pending animation events queue is cleared prior to dispatching events so that events enqueued in the meantime do not prematurely schedule animation resolution. The need for a new animation resolution will be checked at the end of the procedure. Finally, declarative animations used to have a special suclass of WebAnimation::needsTick() that would check whether they had any pending events, ensuring they would not be removed prematurely. We now reset a flag to false as WebAnimation::tick() is called (as part of the "update animations and send events" procedure) and set it to true in case an animation is enqueued. This flag is then used in needsTick() to guarantee the animation is not removed before the DocumentTimeline has had a chance to dispatch the enqueued event. Note also that, for clarity, the DocumentTimeline::unscheduleAnimationResolution() was renamed to DocumentTimeline::clearTickScheduleTimer() since it wouldn't actually cancel a previous animation resolution schedule. * animation/CSSTransition.h: Fix a newly found build error due to the missing wtf/MonotonicTime.h header. * animation/DeclarativeAnimation.cpp: Remove all code related to the dedicated per-animation queue and instead call the new WebAnimation::enqueueAnimationEvent() method to enqueue events on the DocumentTimeline. (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::tick): (WebCore::DeclarativeAnimation::enqueueDOMEvent): * animation/DeclarativeAnimation.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): Ensure the pending events queue is cleared when the timeline is detached from a document, ensuring that there no longer events that would cause a ref-cycle (DocumentTimeline -> AnimationPlaybackEvent -> WebAnimation -> DocumentTimeline). (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::removeAnimation): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::clearTickScheduleTimer): (WebCore::DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState const): (WebCore::DocumentTimeline::updateCurrentTime): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): (WebCore::DocumentTimeline::enqueueAnimationEvent): * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::enqueueAnimationPlaybackEvent): (WebCore::WebAnimation::enqueueAnimationEvent): (WebCore::WebAnimation::needsTick const): (WebCore::WebAnimation::tick): * animation/WebAnimation.h: LayoutTests: Fix a couple of tests that made some incorrect assumptions. * TestExpectations: imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is no longer flaky. * compositing/backing/animate-into-view.html: Because the "animationstart" event is now dispatched during the "update animations and send events" procedure, which happens during page rendering _before_ rAF callbacks are serviced, we must remove the rAF callback used prior to adding the "animationstart" event listener or else we would never get it and the test would time out. * webanimations/css-transition-in-flight-reversal-accelerated.html: We must wait for the initial transition to start and then two frames before reversing the transition, to be certain that the animation did start. Indeed, the "transitionstart" event will be fired right before the next rAF callback is called, as the animation starts in that very same frame, and so progress will be 0 and the transition wouldn't be reversable until the next frame when the animation has progress > 0. Canonical link: https://commits.webkit.org/220724@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@256619 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-14 17:52:07 +00:00
void clearTickScheduleTimer();
requestAnimationFrame should execute before the next frame https://bugs.webkit.org/show_bug.cgi?id=177484 Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2019-04-10 Reviewed by Simon Fraser. LayoutTests/imported/w3c: Add trace points for the page RenderingUpdate. * web-platform-tests/resize-observer/resources/resizeTestHelper.js: Change ResizeTestHelper.TIMEOUT to be 1 second instead of 100 ms which is too short for layout tests. Source/WebCore: This change fixes these issues with animation timing: 1. Calling the requestAnimationFrame callbacks would have happened when the DisplayLink fires. This may have happened even if the frame is missed and no display is committed. 2. Style changes and layout triggered by script could trigger painting at more than 60fps. CoreAnimation commits could happen at more than 60fps, although WindowServer will throttle those, and only some will be shown on the screen. This change introduces a new paint scheduling model where painting is driven by a "RenderingUpdateScheduler", which only triggers paints once per 16.7ms frame. Code that previously scheduled a compositing layer flush now schedules a "RenderingUpdate", and that update is driven by a DisplayRefreshMonitor callback. When the render happens, we service requestAnimationFrame callbacks, Web Animations, intersection observations and resize observations per the "Update the rendering" step of the HTML Event Loop specification: <https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>. In the future, more rendering steps will be added to this code. * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * accessibility/mac/AXObjectCacheMac.mm: (WebCore::AXObjectCache::platformHandleFocusedUIElementChanged): Fix layout tests by adding null check. * animation/DocumentAnimationScheduler.cpp: Removed. * animation/DocumentAnimationScheduler.h: Removed. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::updateThrottlingState): (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::resumeAnimations): (WebCore::DocumentTimeline::liveCurrentTime const): (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::cacheCurrentTime): (WebCore::DocumentTimeline::animationTimingDidChange): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::unscheduleAnimationResolution): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Simplify this function by handling the case of no-animations separately. (WebCore::DocumentTimeline::resolveAnimationsForElement): Simplify the loop and delete hasPendingAcceleratedAnimations because it is initialized to true and is not changed inside the loop. (WebCore::DocumentTimeline::scheduleAnimationResolutionIfNeeded): Deleted. (WebCore::DocumentTimeline::animationResolutionTimerFired): Deleted. * animation/DocumentTimeline.h: * dom/Document.cpp: (WebCore::Document::resolveStyle): There is no need to force update in resolveStyle(). notifyFlushRequired() will be called eventually which will scheduleRenderingUpdate(). (WebCore::Document::prepareForDestruction): (WebCore::Document::updateAnimationsAndSendEvents): (WebCore::Document::serviceRequestAnimationFrameCallbacks): (WebCore::Document::windowScreenDidChange): (WebCore::Document::scheduleRenderingUpdate): (WebCore::Document::updateIntersectionObservations): (WebCore::Document::addResizeObserver): (WebCore::Document::updateResizeObservations): (WebCore::Document::scheduleForcedIntersectionObservationUpdate): Deleted. (WebCore::Document::scheduleResizeObservations): Deleted. (WebCore::Document::animationScheduler): Deleted. No need to schedule web-animations, intersection observations and resize observations updates separately. All of them will be updated through the "Update the rendering" step, i.e. Page::updateRendering(). * dom/Document.h: (WebCore::Document::numberOfIntersectionObservers const): * dom/ScriptedAnimationController.cpp: (WebCore::ScriptedAnimationController::serviceRequestAnimationFrameCallbacks): (WebCore::ScriptedAnimationController::scheduleAnimation): (WebCore::ScriptedAnimationController::animationTimerFired): (WebCore::ScriptedAnimationController::serviceScriptedAnimations): Deleted. (WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire): Deleted. * dom/ScriptedAnimationController.h: * page/FrameView.cpp: (WebCore::FrameView::didLayout): (WebCore::FrameView::viewportContentsChanged): * page/FrameViewLayoutContext.cpp: (WebCore::FrameViewLayoutContext::layoutTimerFired): * page/IntersectionObserver.cpp: (WebCore::IntersectionObserver::observe): * page/Page.cpp: (WebCore::Page::Page): (WebCore::Page::layoutIfNeeded): (WebCore::Page::updateRendering): (WebCore::Page::renderingUpdateScheduler): (WebCore::Page::willDisplayPage): Deleted. (WebCore::Page::addDocumentNeedingIntersectionObservationUpdate): Deleted. (WebCore::Page::updateIntersectionObservations): Deleted. (WebCore::Page::scheduleForcedIntersectionObservationUpdate): Deleted. (WebCore::Page::hasResizeObservers const): Deleted. (WebCore::Page::gatherDocumentsNeedingResizeObservationCheck): Deleted. (WebCore::Page::checkResizeObservations): Deleted. (WebCore::Page::scheduleResizeObservations): Deleted. (WebCore::Page::notifyResizeObservers): Deleted. * page/Page.h: (WebCore::Page::setNeedsCheckResizeObservations): Deleted. (WebCore::Page::needsCheckResizeObservations const): Deleted. The IntersectionObserver and the ResizeObserver do not need to schedule their own timers. The RenderingUpdateScheduler will schedule the "Update the rendering" step in which these obverses will be served. * page/PageOverlayController.cpp: (WebCore::PageOverlayController::didChangeViewExposedRect): (WebCore::PageOverlayController::notifyFlushRequired): Force committing the layers to be 60 fps at maximum. * page/RenderingUpdateScheduler.cpp: Added. (WebCore::RenderingUpdateScheduler::RenderingUpdateScheduler): (WebCore::RenderingUpdateScheduler::scheduleRenderingUpdate): (WebCore::RenderingUpdateScheduler::isScheduled const): (WebCore::RenderingUpdateScheduler::startTimer): (WebCore::RenderingUpdateScheduler::clearScheduled): (WebCore::RenderingUpdateScheduler::createDisplayRefreshMonitor const): (WebCore::RenderingUpdateScheduler::windowScreenDidChange): (WebCore::RenderingUpdateScheduler::displayRefreshFired): (WebCore::RenderingUpdateScheduler::scheduleCompositingLayerFlush): * page/RenderingUpdateScheduler.h: Added. (WebCore::RenderingUpdateScheduler::create): * page/ResizeObserver.cpp: (WebCore::ResizeObserver::observe): (WebCore::ResizeObserver::scheduleObservations): Deleted. * page/ResizeObserver.h: (WebCore::ResizeObserver::hasActiveObservations const): * page/ios/ContentChangeObserver.h: * page/mac/ServicesOverlayController.mm: (WebCore::ServicesOverlayController::Highlight::notifyFlushRequired): * page/scrolling/ScrollingStateTree.cpp: * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::scheduleLayerFlushNow): (WebCore::RenderLayerCompositor::layerTreeAsText): Source/WebKit: Replace the calls to Page::layoutIfNeeded() and willDisplayPage() by a single call to Page::updateRendering(). This new function implements "Update the rendering" step of the HTML Event Loop specification <https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>. * WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp: (WebKit::DrawingAreaCoordinatedGraphics::scheduleCompositingLayerFlush): (WebKit::DrawingAreaCoordinatedGraphics::updateBackingStoreState): (WebKit::DrawingAreaCoordinatedGraphics::display): * WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp: (WebKit::LayerTreeHost::layerFlushTimerFired): * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm: (WebKit::RemoteLayerTreeDrawingArea::flushLayers): -- Call Page::updateRendering() to make sure that "Update the rendering" happens immediately before updating the page. -- Move the call to RemoteLayerBackingStoreCollection::willFlushLayers() to be exactly before flushing the layers. This fixes the assertion ASSERT(m_inLayerFlush) which was firing when running a layout test. RemoteLayerTreeDrawingArea::flushLayers() now can call itself through TestRunner::notifyDone(). flushLayers() was calling willFlushLayers() twice before calling didFlushLayers(). * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::layoutIfNeeded): (WebKit::WebPage::updateRendering): (WebKit::WebPage::willDisplayPage): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _viewWillDrawInternal]): (-[WebView _flushCompositingChanges]): Call Page::updateRendering() which implements "Update the rendering" step of the HTML Event Loop specification. Source/WebKitLegacy/win: * WebView.cpp: (WebView::updateBackingStore): (WebView::flushPendingGraphicsLayerChangesSoon): (WebView::flushPendingGraphicsLayerChanges): Call Page::updateRendering() which implements "Update the rendering" step of the HTML Event Loop specification. Source/WTF: Add trace points for the page RenderingUpdate. * wtf/SystemTracing.h: Tools: Add trace points for the page RenderingUpdate. * Tracing/SystemTracePoints.plist: LayoutTests: * TestExpectations: There is a slight difference between the actual DRT and the expected DRT due to animation timing change. But these two tests are not animating correctly if they are opened in Safari with web animation turned on. * accessibility/mac/selection-notification-focus-change-expected.txt: * accessibility/mac/selection-notification-focus-change.html: Remove the debug statements form notificationCallback() since the number of times this function is called back and the order of notifications are not defined. This test has been flaky and some trials were made to make it more reliable. With this change it became flaky again. * animations/animation-multiple-callbacks-timestamp.html: Fix variable names used by an error message. * animations/no-style-recalc-during-accelerated-animation-expected.txt: * animations/no-style-recalc-during-accelerated-animation.html: One extra styleReclc was incurred due to the document styleRecalcTimer. I think this timer is not needed anymore. I will look at removing it in a separate patch. * animations/resources/animation-test-helpers.js: (waitForAnimationToStart): The expectation that animation will start at the beginning of the next event loop is not true anymore. The animation will start at the time the requestAnimationFrame fires. * compositing/video/video-clip-change-src.html: This test loads a video data and pushes it to the encoder. Originally it used to wait 150 ms after receiving the second canplaythrough. I had to change this timing to 250 ms. * css3/filters/composited-during-animation.html: Ditto. setTimeout({...}, 0) versus requestAnimationFrame. * media/media-controls-accessibility.html: Updating the accessibility button happens asynchronously, see [WebAccessibilityObjectWrapper accessibilityPerformPressAction]. Due to changing the page update timing, this test became flaky. Originally it used to setTimeout({...}, 10) to ensure the stringValue of the mutate button was changed after it was pressed. The fix is to loop using rAF till the stringValue changes. * platform/mac-wk2/accessibility/mac/selection-notification-focus-change-expected.txt: Removed. The number of time notificationCallback() is called and the order of notifications are not defined. And this is why we have two expected files: one for WK1 and the other for WK2. Since the test is now simplified, we can get rid of this duplication. We will test the minimum reliable thing we can test. Canonical link: https://commits.webkit.org/211093@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-11 05:44:13 +00:00
void internalUpdateAnimationsAndSendEvents();
[Web Animations] Don't schedule animation frames or update style while an accelerated animation is running https://bugs.webkit.org/show_bug.cgi?id=191542 <rdar://problem/45356027> Reviewed by Simon Fraser. Source/WebCore: Test: animations/no-style-recalc-during-accelerated-animation.html In order to be more power-efficient, we stop scheduling calls to updateAnimationsAndSendEvents() when running only accelerated animations. To do that, we prevent scheduling further animation resolution if we're in the process of updating animations, and when we are done, call the new DocumentTimeline::scheduleNextTick() method that will check whether we have only accelerated animations running, and in that case check which of those animations needs an update the soonest and starts a timer scheduled for that time when we'll schedule animation resolution. By default, animations compute the time until their natural completion but in the case of CSS Animations, we want to make sure we also update animations in-flight to dispatch "animationiteration" events. * animation/AnimationEffect.h: Make the simpleIterationProgress() public so it can be called by WebAnimation::timeToNextTick(). * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): Create the m_tickScheduleTimer and set it up to call scheduleAnimationResolutionIfNeeded(). (WebCore::DocumentTimeline::suspendAnimations): If we don't already have a cached current time, cache the current time. (WebCore::DocumentTimeline::resumeAnimations): Reset the cached current time to ensure we'll get a fresh one when updating animations next. (WebCore::DocumentTimeline::liveCurrentTime const): Factor the code to compute the current time out of currentTime() so that we can cache the current time in suspendAnimations() without also automatically clearing the current time. (WebCore::DocumentTimeline::currentTime): Use liveCurrentTime() and cacheCurrentTime() since much of the code from this function has been factored out into those. Additionally, we were failing to clear the current time if called inside an animation frame, which we now do correctly by virtue of using cacheCurrentTime(). This fixes some flakiness. (WebCore::DocumentTimeline::cacheCurrentTime): Factor the code to cache the current time out of currentTime(). (WebCore::DocumentTimeline::maybeClearCachedCurrentTime): No need to clear the current time if we get suspended. (WebCore::DocumentTimeline::scheduleAnimationResolutionIfNeeded): Prevent scheduling an animation update if we're in the middle of one already, scheduleNextTick() will be called after animations are updated to see if we should schedule an animation update instead. (WebCore::DocumentTimeline::unscheduleAnimationResolution): Cancel the m_tickScheduleTimer if we need to unschedule animation resolution. (WebCore::DocumentTimeline::animationResolutionTimerFired): Factor the call to applyPendingAcceleratedAnimations() out of updateAnimationsAndSendEvents() and call scheduleNextTick(). (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): Set the new m_isUpdatingAnimations member variable to true while this function is running. (WebCore::DocumentTimeline::scheduleNextTick): Schedule an animation update immediately if we have any relevant animation that is not accelerated. Otherwise, iterate through all animations to figure out the earliest moment at which we need to update animations. (WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Use the new WebAnimation::isRunningAccelerated() function. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::isRunningAccelerated const): Since we end up checking if an animation is running with an accelerated effect, we introduce a new function to get that information directly through the WebAnimation object without bothering about its effect. (WebCore::WebAnimation::resolve): We should only call updateFinishedState() here since timingDidChange() would also notify the timeline about a potential change in relevance, which is not necessary and which would schedule an animation frame even for animations that are accelerated. (WebCore::WebAnimation::timeToNextTick const): Compute the time until our animation completion or, in the case of CSS animations, the next iteration. * animation/WebAnimation.h: LayoutTests: Add a test that checks that we make only minimal style updates and still dispatch events while an accelerated animation is running. * animations/no-style-recalc-during-accelerated-animation-expected.txt: Added. * animations/no-style-recalc-during-accelerated-animation.html: Added. * fast/layers/no-clipping-overflow-hidden-added-after-transform-expected.html: * fast/layers/no-clipping-overflow-hidden-added-after-transform.html: Change the colors to avoid a tiny ImageOnlyFailure. * platform/win/TestExpectations: Mark some regressions tracked by webkit.org/b/191584. Canonical link: https://commits.webkit.org/206337@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238128 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-13 10:22:56 +00:00
void scheduleNextTick();
bool animationCanBeRemoved(WebAnimation&);
bool shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() const;
[Web Animations] Schedule animations registered on the document timeline https://bugs.webkit.org/show_bug.cgi?id=179236 <rdar://problem/35332669> Reviewed by Dean Jackson. Source/WebCore: We now schedule animations contained in the document timeline using a three-step approach. 1. Each time an object that is part of the timing model changes one of its timing properties, we call animationTimingModelDidChange() on the document timeline. This schedules performInvalidationTask() to be called when the current run loop completes, such that we invalidate the timing model just once per run loop. 2. Once performInvalidationTask() is called, the timing model is invalidated in updateAnimationSchedule(). We iterate over the registered animations on the timineline and identify the shortest interval between the current time and the next moment one of the animations requires a tick to update its value. If we find a value below 15ms, we schedule animations to be resolved with scheduleAnimationResolution() right away. If the value is above 15ms, and not inifinity, we schedule a one-shot timer for that interval to call scheduleAnimationResolution(). 3. Once scheduleAnimationResolution() is called, we call scheduleAnimation() on the shared DisplayRefreshMonitorManager to be notified when the next display refresh occurs to actually resolve animations with resolveAnimations(). Note that, in this patch, resolveAnimations() does nothing, we will add support for interpolating values in a future patch. Another important thing to note is that every time the document timeline's current time is requested, we cache it for the duration of the run loop such that the timing model always uses the same value during a given run loop. Finally, to support tests where we check the state of the timing model by manually advancing time, we expose a new pause() method on AnimationTimeline for tests to call to avoid the timeline to self-advance. * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::addAnimation): Mark that the timing model changed as a result of adding an animation. (WebCore::AnimationTimeline::removeAnimation): Mark that the timing model changed as a result of removing an animation. (WebCore::AnimationTimeline::bindingsCurrentTime): Update the method signature to no longer be const and call into currentTime() instead of reading directly from the m_currentTime member variable since a subclass, like DocumentTimeline, may have a custom currentTime() implementation. (WebCore::AnimationTimeline::setCurrentTime): Mark that the timing model changed as a result of the timeline current time changing. (WebCore::AnimationTimeline::bindingsCurrentTime const): Deleted. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::currentTime): Change both methods signatures to no longer be const so that DocumentTimeline's implementation of currentTime() may cache the current time in a member variable, enqueuing a callback when the run loop completes for this member variable to be reset, and updating some states. (WebCore::AnimationTimeline::pause): To be implemented by subclasses. (WebCore::AnimationTimeline::animationTimingModelDidChange): Add a new virtual method to indicate that the timing model needs invalidating. (WebCore::AnimationTimeline::animations const): Add an accessor to allow animations to be accessed by a subclass. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): Update the constructor signature to receive a Document and a PlatformDisplayID since we need a reference to the Document to get at the nowTime() and a PlatformDisplayID to create the DisplayRefreshMonitor. (WebCore::DocumentTimeline::~DocumentTimeline): Close the task queue when the timeline gets destroyed. (WebCore::DocumentTimeline::currentTime): If we don't have a current cahed current time, compute one and schedule the invalidation task if needed so that we may reset the cached value as the run loop completes. (WebCore::DocumentTimeline::pause): Allows the timeline not to self-advance, for testing purposes only. (WebCore::DocumentTimeline::animationTimingModelDidChange): If we haven't already done so, mark that we need to update our animation schedule in the invalidation task and schedule that task if not scheduled yet. (WebCore::DocumentTimeline::scheduleInvalidationTaskIfNeeded): Schedule the invalidation task to run as the run loop completes if we haven't already done so. (WebCore::DocumentTimeline::performInvalidationTask): Update the animation schedule if needed and reset the cached current time value. (WebCore::DocumentTimeline::updateAnimationSchedule): Iterate over registed animations and find the shortest interval until one of them needs to update their animation. If the shortest interval is below 15ms, schedule the animation resolution right away. If the shortest inverval is finite and above 15ms, then schedule a one-shot timer for that interval to perform the animation resolution then. (WebCore::DocumentTimeline::animationScheduleTimerFired): The one-shot timer to perform the animation resolution has fired, we call scheduleAnimationResolution(). (WebCore::DocumentTimeline::scheduleAnimationResolution): We call scheduleAnimation() on the shared DisplayRefreshMonitorManager so that we may resolve animations on the next display refresh, or start a timer if the DisplayRefreshMonitorManager is not available. (WebCore::DocumentTimeline::displayRefreshFired): The display is about to refresh, we call resolveAnimations(). (WebCore::DocumentTimeline::animationResolutionTimerFired): The fallback animation resolution timer has fired, we call resolveAnimations(). (WebCore::DocumentTimeline::resolveAnimations): Currently do nothing, this is where we'll iterate over registered animations to update them with the current time. (WebCore::DocumentTimeline::windowScreenDidChange): Notify the shared DisplayRefreshMonitorManager that the PlatformDisplayID changed. (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Provide a DisplayRefreshMonitor as part of the DisplayRefreshMonitorClient protocol. * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::create): Remove extra white space. (WebCore::WebAnimation::setStartTime): Mark that the timing model changed as a result of changing this animation's start time. (WebCore::WebAnimation::timeToNextRequiredTick const): Compute the interval until the next time we need to resolve this animation. If the provided current time is before this animation's start time, compute the delay until the start time. If the current time is after the animation's start time but before the animation's end time, indicate that we want to resolve the animation again right away and return 0ms. In any other case, return an infinite interval to indicate that we don't need to be refreshed after the provided time. * animation/WebAnimation.h: * dom/Document.cpp: (WebCore::Document::windowScreenDidChange): Notify the document timeline that the PlatformDisplayID changed. (WebCore::Document::timeline): Provide the Document and the PlatformDisplayID to the DocumentTimeline. * testing/Internals.cpp: (WebCore::Internals::pauseTimeline): * testing/Internals.h: * testing/Internals.idl: LayoutTests: Adopt the new internals.pauseTimeline() method to ensure that the existing tests do not have a self-advancing timeline since we're interested in checking the timing model state based on manually setting the timeline current time. Also update some WPT expectations with some progressions. * TestExpectations: Mark two tests as flaky due to the sample time being logged in the failure. * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt: * http/wpt/web-animations/timing-model/animations/current-time-expected.txt: * http/wpt/web-animations/timing-model/animations/set-the-animation-start-time-expected.txt: * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html: * http/wpt/wk-web-animations/timing-model/animation-current-time.html: * http/wpt/wk-web-animations/timing-model/animation-effect-timing.html: * http/wpt/wk-web-animations/timing-model/animation-effect.html: * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html: * http/wpt/wk-web-animations/timing-model/animation-interface-start-time-property.html: * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: * http/wpt/wk-web-animations/timing-model/document-timeline.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html: * http/wpt/wk-web-animations/timing-model/keyframe-effect.html: * http/wpt/wk-web-animations/timing-model/timeline-current-time.html: Canonical link: https://commits.webkit.org/195397@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224472 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-05 22:34:10 +00:00
[Web Animations] Audit Web Animations classes for memory reduction https://bugs.webkit.org/show_bug.cgi?id=193195 Reviewed by Simon Fraser and Yusuke Suzuki. The classes, enums and structs added to support Web Animations were not as memory-efficient as they could be. We now order members in a way that reduces padding, use Markable<T, Traits> instead of Optional<T> where applicable, declare enums as uint8_t and removed unnecessary members. As a result, classes and structs have shrunk as follows: WebAnimation: 256 > 216 DeclarativeAnimation: 392 > 344 CSSAnimation: 416 > 368 CSSTransition: 440 > 392 AnimationEffect: 88 > 72 KeyframeEffect: 208 > 184 AnimationPlaybackEvent: 104 > 88 EffectTiming: 72 > 64 ComputedEffectTiming: 136 > 112 AnimationTimeline: 264 > 248 DocumentTimeline: 496 > 464 OptionalEffectTiming: 112 > 80 BaseKeyframe: 32 > 24 ParsedKeyframe: 80 > 72 BaseComputedKeyframe: 40 > 32 * animation/AnimationEffect.h: Order members in decreasing size, except for m_fill and m_direction, which we put at the top to save 8 bytes (2 bytes of padding instead of 4 before m_animation and saving 6 bytes of padding at the end). * animation/AnimationPlaybackEvent.cpp: (WebCore::AnimationPlaybackEvent::AnimationPlaybackEvent): * animation/AnimationPlaybackEvent.h: * animation/AnimationPlaybackEventInit.h: * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::updateCSSTransitionsForElement): * animation/AnimationTimeline.h: We remove the m_classType member and instead make isDocumentTimeline() virtual. (WebCore::AnimationTimeline::isDocumentTimeline const): (): Deleted. (WebCore::AnimationTimeline::classType const): Deleted. * animation/CompositeOperation.h: * animation/CompositeOperationOrAuto.h: * animation/ComputedEffectTiming.h: * animation/DeclarativeAnimation.cpp: (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::invalidateDOMEvents): * animation/DeclarativeAnimation.h: We keep m_wasPending and m_previousPhase at the top to save some padding at the end. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: * animation/EffectTiming.h: * animation/FillMode.h: * animation/IterationCompositeOperation.h: * animation/KeyframeEffect.cpp: (WebCore::computeMissingKeyframeOffsets): (WebCore::KeyframeEffect::create): (WebCore::KeyframeEffect::KeyframeEffect): * animation/KeyframeEffect.h: * animation/OptionalEffectTiming.h: * animation/PlaybackDirection.h: * animation/WebAnimation.h: * animation/WebAnimationUtilities.h: (WebCore::WebAnimationsMarkableDoubleTraits::isEmptyValue): (WebCore::WebAnimationsMarkableDoubleTraits::emptyValue): Canonical link: https://commits.webkit.org/207806@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239820 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-10 08:19:39 +00:00
Timer m_tickScheduleTimer;
HashSet<RefPtr<WebAnimation>> m_acceleratedAnimationsPendingRunningStateChange;
[Web Animations] Coordinate "update animations and send events" procedure across multiple timelines https://bugs.webkit.org/show_bug.cgi?id=202109 <rdar://problem/59470821> Reviewed by Dean Jackson. LayoutTests/imported/w3c: Mark a new test as PASS which shows that we correctly perform a single microstask checkpoint when updating multiple timelines. * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: So far, although we did manage multiple animation timelines per document, we mostly operated under the assumption that there really was a single timeline. In this patch we make the "update animations and send events" procedure, which is central to the lifecycle of animations, work with multiple timelines such that a single microtask checkpoint is performed even with multiple timelines, whereas we would perform one per timeline before. To do this, we move much of the logic DocumentTimeline::updateAnimationsAndSendEvents() to DocumentTimelinesController where each step is run across each timeline, rather than running all steps for each timeline one after the other, respecting the single microtask checkpoint in the middle of the process. To minimize code churn at this stage, we still keep a fair bit of logic in DocumentTimeline and, while we remove updateAnimationsAndSendEvents(), internalUpdateAnimationsAndSendEvents() and updateCurrentTime(), we expose three methods that allow to run the pre-flight sequence in documentWillUpdateAnimationsAndSendEvents(), collect pending events in prepareForPendingAnimationEventsDispatch() and run the post-flight sequence in documentDidUpdateAnimationsAndSendEvents(). None of the logic changes, this is just moving code around. In the future, more patches will move code from DocumentTimeline up to DocumentTimelinesController such that events are enqueued there, and animation scheduling as well. But this already lets us pass a new test that used to flakily reject promises in the WPT test web-animations/timing-model/timelines/update-and-send-events.html. * animation/AnimationTimeline.h: (WebCore::AnimationTimeline::relevantAnimations const): (WebCore::AnimationTimeline::allAnimations const): * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::documentDidUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::prepareForPendingAnimationEventsDispatch): (WebCore::DocumentTimeline::updateCurrentTime): Deleted. (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): Deleted. (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): Deleted. * animation/DocumentTimeline.h: * animation/DocumentTimelinesController.cpp: (WebCore::DocumentTimelinesController::DocumentTimelinesController): (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents): * animation/DocumentTimelinesController.h: * animation/WebAnimationTypes.h: * dom/Document.cpp: (WebCore::Document::ensureTimelinesController): LayoutTests: Remove the flaky expectation for the improved test. * TestExpectations: Canonical link: https://commits.webkit.org/223759@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260525 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-04-22 18:47:36 +00:00
AnimationEvents m_pendingAnimationEvents;
WeakPtr<Document> m_document;
Seconds m_originTime;
[Web Animations] Audit Web Animations classes for memory reduction https://bugs.webkit.org/show_bug.cgi?id=193195 Reviewed by Simon Fraser and Yusuke Suzuki. The classes, enums and structs added to support Web Animations were not as memory-efficient as they could be. We now order members in a way that reduces padding, use Markable<T, Traits> instead of Optional<T> where applicable, declare enums as uint8_t and removed unnecessary members. As a result, classes and structs have shrunk as follows: WebAnimation: 256 > 216 DeclarativeAnimation: 392 > 344 CSSAnimation: 416 > 368 CSSTransition: 440 > 392 AnimationEffect: 88 > 72 KeyframeEffect: 208 > 184 AnimationPlaybackEvent: 104 > 88 EffectTiming: 72 > 64 ComputedEffectTiming: 136 > 112 AnimationTimeline: 264 > 248 DocumentTimeline: 496 > 464 OptionalEffectTiming: 112 > 80 BaseKeyframe: 32 > 24 ParsedKeyframe: 80 > 72 BaseComputedKeyframe: 40 > 32 * animation/AnimationEffect.h: Order members in decreasing size, except for m_fill and m_direction, which we put at the top to save 8 bytes (2 bytes of padding instead of 4 before m_animation and saving 6 bytes of padding at the end). * animation/AnimationPlaybackEvent.cpp: (WebCore::AnimationPlaybackEvent::AnimationPlaybackEvent): * animation/AnimationPlaybackEvent.h: * animation/AnimationPlaybackEventInit.h: * animation/AnimationTimeline.cpp: (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::updateCSSTransitionsForElement): * animation/AnimationTimeline.h: We remove the m_classType member and instead make isDocumentTimeline() virtual. (WebCore::AnimationTimeline::isDocumentTimeline const): (): Deleted. (WebCore::AnimationTimeline::classType const): Deleted. * animation/CompositeOperation.h: * animation/CompositeOperationOrAuto.h: * animation/ComputedEffectTiming.h: * animation/DeclarativeAnimation.cpp: (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::invalidateDOMEvents): * animation/DeclarativeAnimation.h: We keep m_wasPending and m_previousPhase at the top to save some padding at the end. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: * animation/EffectTiming.h: * animation/FillMode.h: * animation/IterationCompositeOperation.h: * animation/KeyframeEffect.cpp: (WebCore::computeMissingKeyframeOffsets): (WebCore::KeyframeEffect::create): (WebCore::KeyframeEffect::KeyframeEffect): * animation/KeyframeEffect.h: * animation/OptionalEffectTiming.h: * animation/PlaybackDirection.h: * animation/WebAnimation.h: * animation/WebAnimationUtilities.h: (WebCore::WebAnimationsMarkableDoubleTraits::isEmptyValue): (WebCore::WebAnimationsMarkableDoubleTraits::emptyValue): Canonical link: https://commits.webkit.org/207806@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239820 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-10 08:19:39 +00:00
unsigned m_numberOfAnimationTimelineInvalidationsForTesting { 0 };
requestAnimationFrame should execute before the next frame https://bugs.webkit.org/show_bug.cgi?id=177484 Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2019-04-10 Reviewed by Simon Fraser. LayoutTests/imported/w3c: Add trace points for the page RenderingUpdate. * web-platform-tests/resize-observer/resources/resizeTestHelper.js: Change ResizeTestHelper.TIMEOUT to be 1 second instead of 100 ms which is too short for layout tests. Source/WebCore: This change fixes these issues with animation timing: 1. Calling the requestAnimationFrame callbacks would have happened when the DisplayLink fires. This may have happened even if the frame is missed and no display is committed. 2. Style changes and layout triggered by script could trigger painting at more than 60fps. CoreAnimation commits could happen at more than 60fps, although WindowServer will throttle those, and only some will be shown on the screen. This change introduces a new paint scheduling model where painting is driven by a "RenderingUpdateScheduler", which only triggers paints once per 16.7ms frame. Code that previously scheduled a compositing layer flush now schedules a "RenderingUpdate", and that update is driven by a DisplayRefreshMonitor callback. When the render happens, we service requestAnimationFrame callbacks, Web Animations, intersection observations and resize observations per the "Update the rendering" step of the HTML Event Loop specification: <https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>. In the future, more rendering steps will be added to this code. * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * accessibility/mac/AXObjectCacheMac.mm: (WebCore::AXObjectCache::platformHandleFocusedUIElementChanged): Fix layout tests by adding null check. * animation/DocumentAnimationScheduler.cpp: Removed. * animation/DocumentAnimationScheduler.h: Removed. * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::DocumentTimeline): (WebCore::DocumentTimeline::updateThrottlingState): (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::resumeAnimations): (WebCore::DocumentTimeline::liveCurrentTime const): (WebCore::DocumentTimeline::currentTime): (WebCore::DocumentTimeline::cacheCurrentTime): (WebCore::DocumentTimeline::animationTimingDidChange): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::unscheduleAnimationResolution): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Simplify this function by handling the case of no-animations separately. (WebCore::DocumentTimeline::resolveAnimationsForElement): Simplify the loop and delete hasPendingAcceleratedAnimations because it is initialized to true and is not changed inside the loop. (WebCore::DocumentTimeline::scheduleAnimationResolutionIfNeeded): Deleted. (WebCore::DocumentTimeline::animationResolutionTimerFired): Deleted. * animation/DocumentTimeline.h: * dom/Document.cpp: (WebCore::Document::resolveStyle): There is no need to force update in resolveStyle(). notifyFlushRequired() will be called eventually which will scheduleRenderingUpdate(). (WebCore::Document::prepareForDestruction): (WebCore::Document::updateAnimationsAndSendEvents): (WebCore::Document::serviceRequestAnimationFrameCallbacks): (WebCore::Document::windowScreenDidChange): (WebCore::Document::scheduleRenderingUpdate): (WebCore::Document::updateIntersectionObservations): (WebCore::Document::addResizeObserver): (WebCore::Document::updateResizeObservations): (WebCore::Document::scheduleForcedIntersectionObservationUpdate): Deleted. (WebCore::Document::scheduleResizeObservations): Deleted. (WebCore::Document::animationScheduler): Deleted. No need to schedule web-animations, intersection observations and resize observations updates separately. All of them will be updated through the "Update the rendering" step, i.e. Page::updateRendering(). * dom/Document.h: (WebCore::Document::numberOfIntersectionObservers const): * dom/ScriptedAnimationController.cpp: (WebCore::ScriptedAnimationController::serviceRequestAnimationFrameCallbacks): (WebCore::ScriptedAnimationController::scheduleAnimation): (WebCore::ScriptedAnimationController::animationTimerFired): (WebCore::ScriptedAnimationController::serviceScriptedAnimations): Deleted. (WebCore::ScriptedAnimationController::documentAnimationSchedulerDidFire): Deleted. * dom/ScriptedAnimationController.h: * page/FrameView.cpp: (WebCore::FrameView::didLayout): (WebCore::FrameView::viewportContentsChanged): * page/FrameViewLayoutContext.cpp: (WebCore::FrameViewLayoutContext::layoutTimerFired): * page/IntersectionObserver.cpp: (WebCore::IntersectionObserver::observe): * page/Page.cpp: (WebCore::Page::Page): (WebCore::Page::layoutIfNeeded): (WebCore::Page::updateRendering): (WebCore::Page::renderingUpdateScheduler): (WebCore::Page::willDisplayPage): Deleted. (WebCore::Page::addDocumentNeedingIntersectionObservationUpdate): Deleted. (WebCore::Page::updateIntersectionObservations): Deleted. (WebCore::Page::scheduleForcedIntersectionObservationUpdate): Deleted. (WebCore::Page::hasResizeObservers const): Deleted. (WebCore::Page::gatherDocumentsNeedingResizeObservationCheck): Deleted. (WebCore::Page::checkResizeObservations): Deleted. (WebCore::Page::scheduleResizeObservations): Deleted. (WebCore::Page::notifyResizeObservers): Deleted. * page/Page.h: (WebCore::Page::setNeedsCheckResizeObservations): Deleted. (WebCore::Page::needsCheckResizeObservations const): Deleted. The IntersectionObserver and the ResizeObserver do not need to schedule their own timers. The RenderingUpdateScheduler will schedule the "Update the rendering" step in which these obverses will be served. * page/PageOverlayController.cpp: (WebCore::PageOverlayController::didChangeViewExposedRect): (WebCore::PageOverlayController::notifyFlushRequired): Force committing the layers to be 60 fps at maximum. * page/RenderingUpdateScheduler.cpp: Added. (WebCore::RenderingUpdateScheduler::RenderingUpdateScheduler): (WebCore::RenderingUpdateScheduler::scheduleRenderingUpdate): (WebCore::RenderingUpdateScheduler::isScheduled const): (WebCore::RenderingUpdateScheduler::startTimer): (WebCore::RenderingUpdateScheduler::clearScheduled): (WebCore::RenderingUpdateScheduler::createDisplayRefreshMonitor const): (WebCore::RenderingUpdateScheduler::windowScreenDidChange): (WebCore::RenderingUpdateScheduler::displayRefreshFired): (WebCore::RenderingUpdateScheduler::scheduleCompositingLayerFlush): * page/RenderingUpdateScheduler.h: Added. (WebCore::RenderingUpdateScheduler::create): * page/ResizeObserver.cpp: (WebCore::ResizeObserver::observe): (WebCore::ResizeObserver::scheduleObservations): Deleted. * page/ResizeObserver.h: (WebCore::ResizeObserver::hasActiveObservations const): * page/ios/ContentChangeObserver.h: * page/mac/ServicesOverlayController.mm: (WebCore::ServicesOverlayController::Highlight::notifyFlushRequired): * page/scrolling/ScrollingStateTree.cpp: * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::scheduleLayerFlushNow): (WebCore::RenderLayerCompositor::layerTreeAsText): Source/WebKit: Replace the calls to Page::layoutIfNeeded() and willDisplayPage() by a single call to Page::updateRendering(). This new function implements "Update the rendering" step of the HTML Event Loop specification <https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering>. * WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp: (WebKit::DrawingAreaCoordinatedGraphics::scheduleCompositingLayerFlush): (WebKit::DrawingAreaCoordinatedGraphics::updateBackingStoreState): (WebKit::DrawingAreaCoordinatedGraphics::display): * WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp: (WebKit::LayerTreeHost::layerFlushTimerFired): * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm: (WebKit::RemoteLayerTreeDrawingArea::flushLayers): -- Call Page::updateRendering() to make sure that "Update the rendering" happens immediately before updating the page. -- Move the call to RemoteLayerBackingStoreCollection::willFlushLayers() to be exactly before flushing the layers. This fixes the assertion ASSERT(m_inLayerFlush) which was firing when running a layout test. RemoteLayerTreeDrawingArea::flushLayers() now can call itself through TestRunner::notifyDone(). flushLayers() was calling willFlushLayers() twice before calling didFlushLayers(). * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::layoutIfNeeded): (WebKit::WebPage::updateRendering): (WebKit::WebPage::willDisplayPage): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _viewWillDrawInternal]): (-[WebView _flushCompositingChanges]): Call Page::updateRendering() which implements "Update the rendering" step of the HTML Event Loop specification. Source/WebKitLegacy/win: * WebView.cpp: (WebView::updateBackingStore): (WebView::flushPendingGraphicsLayerChangesSoon): (WebView::flushPendingGraphicsLayerChanges): Call Page::updateRendering() which implements "Update the rendering" step of the HTML Event Loop specification. Source/WTF: Add trace points for the page RenderingUpdate. * wtf/SystemTracing.h: Tools: Add trace points for the page RenderingUpdate. * Tracing/SystemTracePoints.plist: LayoutTests: * TestExpectations: There is a slight difference between the actual DRT and the expected DRT due to animation timing change. But these two tests are not animating correctly if they are opened in Safari with web animation turned on. * accessibility/mac/selection-notification-focus-change-expected.txt: * accessibility/mac/selection-notification-focus-change.html: Remove the debug statements form notificationCallback() since the number of times this function is called back and the order of notifications are not defined. This test has been flaky and some trials were made to make it more reliable. With this change it became flaky again. * animations/animation-multiple-callbacks-timestamp.html: Fix variable names used by an error message. * animations/no-style-recalc-during-accelerated-animation-expected.txt: * animations/no-style-recalc-during-accelerated-animation.html: One extra styleReclc was incurred due to the document styleRecalcTimer. I think this timer is not needed anymore. I will look at removing it in a separate patch. * animations/resources/animation-test-helpers.js: (waitForAnimationToStart): The expectation that animation will start at the beginning of the next event loop is not true anymore. The animation will start at the time the requestAnimationFrame fires. * compositing/video/video-clip-change-src.html: This test loads a video data and pushes it to the encoder. Originally it used to wait 150 ms after receiving the second canplaythrough. I had to change this timing to 250 ms. * css3/filters/composited-during-animation.html: Ditto. setTimeout({...}, 0) versus requestAnimationFrame. * media/media-controls-accessibility.html: Updating the accessibility button happens asynchronously, see [WebAccessibilityObjectWrapper accessibilityPerformPressAction]. Due to changing the page update timing, this test became flaky. Originally it used to setTimeout({...}, 10) to ensure the stringValue of the mutate button was changed after it was pressed. The fix is to loop using rAF till the stringValue changes. * platform/mac-wk2/accessibility/mac/selection-notification-focus-change-expected.txt: Removed. The number of time notificationCallback() is called and the order of notifications are not defined. And this is why we have two expected files: one for WK1 and the other for WK2. Since the test is now simplified, we can get rid of this duplication. We will test the minimum reliable thing we can test. Canonical link: https://commits.webkit.org/211093@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-11 05:44:13 +00:00
bool m_animationResolutionScheduled { false };
[Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline https://bugs.webkit.org/show_bug.cgi?id=207364 <rdar://problem/59370413> Reviewed by Simon Fraser. LayoutTests/imported/w3c: There are some progressions but also some "regressions". The progressions are real, showing the delivery of all animation events at the correct time. However, the regressions are misleading. The fact that the "style change" tests would work was due to a design issue in the test which would only wait one frame to detect whether a CSS Transition was started after a change made through the Web Animations API. These would work because events were queued in the next frame, but delivered later due to the dedicated per-animation queue used, which meant the test was fooled into thinking the CSS Transition did not start, as expected. Changing those test to use more than one frame to test for the lack of a CSS Transition would have shown the FAIL results. However, in order to not regress our WPT score, the issue of "style change" events will be addressed in a follow-up patch. * web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt: * web-platform-tests/web-animations/interfaces/Animatable/animate-expected.txt: * web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt: * web-platform-tests/web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt: * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: Source/WebCore: Until now, AnimationPlaybackEvent events, which are new events introduced by the Web Animations spec, were enqueued in a shared queue on the DocumentTimeline and dispatched during the "update animations and send events" procedure. However, AnimationEvent and TransitionEvent events, dispatched by CSS Animations and CSS Transitions, were dispatched via a dedicated per-animation queue, which meant typically that those events were dispathed one runloop after the AnimationPlaybackEvent events. We now remove the dedicated per-animation queue and enqueue all events in the shared DocumentTimeline queue for dispatch during the "update animations and send events" procedure. To do this correctly, we need to do a couple of other things that ensure we don't regress tests. First, we update the DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() to account for whether there are pending animation events, guaranteeing that an animation update is scheduled should there be any. Second, when animation events are enqueued in DocumentTimeline::enqueueAnimationEvent() we schedule an animation update if needed, since we know we now have pending events that will need to be delivered in an upcoming update. We also maintain a flag between the start of the "update animations and send events" procedure and the moment when the pending animation events queue is cleared prior to dispatching events so that events enqueued in the meantime do not prematurely schedule animation resolution. The need for a new animation resolution will be checked at the end of the procedure. Finally, declarative animations used to have a special suclass of WebAnimation::needsTick() that would check whether they had any pending events, ensuring they would not be removed prematurely. We now reset a flag to false as WebAnimation::tick() is called (as part of the "update animations and send events" procedure) and set it to true in case an animation is enqueued. This flag is then used in needsTick() to guarantee the animation is not removed before the DocumentTimeline has had a chance to dispatch the enqueued event. Note also that, for clarity, the DocumentTimeline::unscheduleAnimationResolution() was renamed to DocumentTimeline::clearTickScheduleTimer() since it wouldn't actually cancel a previous animation resolution schedule. * animation/CSSTransition.h: Fix a newly found build error due to the missing wtf/MonotonicTime.h header. * animation/DeclarativeAnimation.cpp: Remove all code related to the dedicated per-animation queue and instead call the new WebAnimation::enqueueAnimationEvent() method to enqueue events on the DocumentTimeline. (WebCore::DeclarativeAnimation::DeclarativeAnimation): (WebCore::DeclarativeAnimation::tick): (WebCore::DeclarativeAnimation::enqueueDOMEvent): * animation/DeclarativeAnimation.h: * animation/DocumentTimeline.cpp: (WebCore::DocumentTimeline::detachFromDocument): Ensure the pending events queue is cleared when the timeline is detached from a document, ensuring that there no longer events that would cause a ref-cycle (DocumentTimeline -> AnimationPlaybackEvent -> WebAnimation -> DocumentTimeline). (WebCore::DocumentTimeline::suspendAnimations): (WebCore::DocumentTimeline::removeAnimation): (WebCore::DocumentTimeline::scheduleAnimationResolution): (WebCore::DocumentTimeline::clearTickScheduleTimer): (WebCore::DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState const): (WebCore::DocumentTimeline::updateCurrentTime): (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): (WebCore::DocumentTimeline::scheduleNextTick): (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): (WebCore::DocumentTimeline::enqueueAnimationEvent): * animation/DocumentTimeline.h: * animation/WebAnimation.cpp: (WebCore::WebAnimation::enqueueAnimationPlaybackEvent): (WebCore::WebAnimation::enqueueAnimationEvent): (WebCore::WebAnimation::needsTick const): (WebCore::WebAnimation::tick): * animation/WebAnimation.h: LayoutTests: Fix a couple of tests that made some incorrect assumptions. * TestExpectations: imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is no longer flaky. * compositing/backing/animate-into-view.html: Because the "animationstart" event is now dispatched during the "update animations and send events" procedure, which happens during page rendering _before_ rAF callbacks are serviced, we must remove the rAF callback used prior to adding the "animationstart" event listener or else we would never get it and the test would time out. * webanimations/css-transition-in-flight-reversal-accelerated.html: We must wait for the initial transition to start and then two frames before reversing the transition, to be certain that the animation did start. Indeed, the "transitionstart" event will be fired right before the next rAF callback is called, as the animation starts in that very same frame, and so progress will be 0 and the transition wouldn't be reversable until the next frame when the animation has progress > 0. Canonical link: https://commits.webkit.org/220724@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@256619 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-02-14 17:52:07 +00:00
bool m_shouldScheduleAnimationResolutionForNewPendingEvents { true };
[Web Animations] Provide basic timeline and animation interfaces https://bugs.webkit.org/show_bug.cgi?id=178526 Patch by Antoine Quint <graouts@apple.com> on 2017-10-20 Reviewed by Dean Jackson. .: Remove the WEB_ANIMATIONS compile-time flag. * Source/cmake/OptionsWPE.cmake: * Source/cmake/OptionsWin.cmake: * Source/cmake/WebKitFeatures.cmake: * Source/cmake/tools/vsprops/FeatureDefines.props: * Source/cmake/tools/vsprops/FeatureDefinesCairo.props: Source/JavaScriptCore: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebCore: We're getting Web Animations work started by implementing a very minimal codebase which provides a DocumentTimeline class which has an instance created for each Document. The parent class, AnimationTimeline, allows for animations to be added and removed, and animations can be created using the Animation class, with an optional timeline as parameter. Tests: webanimations/animation-creation-basic.html webanimations/document-timeline.html * CMakeLists.txt: * Configurations/FeatureDefines.xcconfig: * DerivedSources.make: * PlatformWin.cmake: * WebCore.xcodeproj/project.pbxproj: * animation/AnimationTimeline.cpp: Added. (WebCore::AnimationTimeline::AnimationTimeline): (WebCore::AnimationTimeline::~AnimationTimeline): (WebCore::AnimationTimeline::addAnimation): (WebCore::AnimationTimeline::removeAnimation): * animation/AnimationTimeline.h: Added. (WebCore::AnimationTimeline::isDocumentTimeline const): (WebCore::AnimationTimeline::classType const): * animation/AnimationTimeline.idl: Added. * animation/DocumentTimeline.cpp: Added. (WebCore::DocumentTimeline::create): (WebCore::DocumentTimeline::DocumentTimeline): * animation/DocumentTimeline.h: Added. * animation/DocumentTimeline.idl: Added. * animation/WebAnimation.cpp: Added. (WebCore::WebAnimation::create): (WebCore::WebAnimation::WebAnimation): (WebCore::WebAnimation::~WebAnimation): * animation/WebAnimation.h: Added. * animation/WebAnimation.idl: Added. * bindings/js/JSAnimationTimelineCustom.cpp: Added. (WebCore::toJSNewlyCreated): (WebCore::toJS): * bindings/js/WebCoreBuiltinNames.h: * dom/Document.cpp: (WebCore::Document::timeline): * dom/Document.h: * dom/Document.idl: * page/RuntimeEnabledFeatures.h: (WebCore::RuntimeEnabledFeatures::webAnimationsEnabled const): Source/WebCore/PAL: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: Source/WebKit: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebProcess/InjectedBundle/InjectedBundle.cpp: (WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner): (WebKit::InjectedBundle::setWebAnimationsEnabled): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updatePreferences): Source/WebKitLegacy/mac: Remove the WEB_ANIMATIONS compile-time flag. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Source/WebKitLegacy/win: Remove the WEB_ANIMATIONS compile-time flag. * WebView.cpp: (WebView::notifyPreferencesChanged): Source/WTF: Remove the WEB_ANIMATIONS compile-time flag. * wtf/FeatureDefines.h: Tools: Remove the WEB_ANIMATIONS compile-time flag. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: Basic test coverage to check that we are exposing a DocumentTimeline instance on the Document and that we can construct Animations, optionally associated with a timeline. * platform/mac-elcapitan/TestExpectations: * webanimations/animation-creation-basic-expected.txt: Added. * webanimations/animation-creation-basic.html: Added. * webanimations/document-timeline-expected.txt: Added. * webanimations/document-timeline.html: Added. Canonical link: https://commits.webkit.org/194785@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-20 18:41:23 +00:00
};
} // namespace WebCore
SPECIALIZE_TYPE_TRAITS_ANIMATION_TIMELINE(DocumentTimeline, isDocumentTimeline())