Changeset 256619 in webkit
- Timestamp:
- Feb 14, 2020 9:52:07 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r256618 r256619 1 2020-02-14 Antoine Quint <graouts@webkit.org> 2 3 [Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline 4 https://bugs.webkit.org/show_bug.cgi?id=207364 5 <rdar://problem/59370413> 6 7 Reviewed by Simon Fraser. 8 9 Fix a couple of tests that made some incorrect assumptions. 10 11 * TestExpectations: imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is no longer flaky. 12 * compositing/backing/animate-into-view.html: Because the "animationstart" event is now dispatched during the "update animations and send events" procedure, which happens 13 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 14 get it and the test would time out. 15 * 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, 16 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 17 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. 18 1 19 2020-02-14 Jacob Uphoff <jacob_uphoff@apple.com> 2 20 -
trunk/LayoutTests/TestExpectations
r256501 r256619 2657 2657 webkit.org/b/202107 imported/w3c/web-platform-tests/web-animations/interfaces/Animation/style-change-events.html [ Pass Failure ] 2658 2658 webkit.org/b/202108 imported/w3c/web-platform-tests/web-animations/interfaces/DocumentTimeline/style-change-events.html [ Pass Failure ] 2659 webkit.org/b/202109 imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html [ Pass Failure ]2660 2659 2661 2660 webkit.org/b/157068 [ Debug ] imported/w3c/web-platform-tests/fetch/nosniff/importscripts.html [ Pass Crash ] -
trunk/LayoutTests/compositing/backing/animate-into-view.html
r239268 r256619 61 61 62 62 window.addEventListener('load', () => { 63 requestAnimationFrame(() => { 64 let animator = document.getElementById('target'); 65 animator.addEventListener('animationstart', () => { 66 requestAnimationFrame(() => { 67 dumpLayers(); 68 if (window.testRunner) 69 testRunner.notifyDone(); 70 }); 63 let animator = document.getElementById('target'); 64 animator.addEventListener('animationstart', () => { 65 requestAnimationFrame(() => { 66 dumpLayers(); 67 if (window.testRunner) 68 testRunner.notifyDone(); 71 69 }); 72 animator.classList.add('animating');73 70 }); 71 animator.classList.add('animating'); 74 72 }, false); 75 73 </script> -
trunk/LayoutTests/imported/w3c/ChangeLog
r256445 r256619 1 2020-02-14 Antoine Quint <graouts@webkit.org> 2 3 [Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline 4 https://bugs.webkit.org/show_bug.cgi?id=207364 5 <rdar://problem/59370413> 6 7 Reviewed by Simon Fraser. 8 9 There are some progressions but also some "regressions". The progressions are real, showing the delivery of all animation events at the correct 10 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 11 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 12 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 13 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 14 would have shown the FAIL results. 15 16 However, in order to not regress our WPT score, the issue of "style change" events will be addressed in a follow-up patch. 17 18 * web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt: 19 * web-platform-tests/web-animations/interfaces/Animatable/animate-expected.txt: 20 * web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt: 21 * web-platform-tests/web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt: 22 * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt: 23 1 24 2020-02-12 Rossana Monteriso <rmonteriso@igalia.com> 2 25 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt
r251591 r256619 4 4 PASS The start time of a transition can be set 5 5 PASS The start time can be set to seek a transition 6 FAIL Seeking a transition using start time dispatches transition events promise_test: Unhandled rejection with value: object "Error: Timed out waiting for Promise to resolve: transitionstart" 6 PASS Seeking a transition using start time dispatches transition events 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animatable/animate-expected.txt
r255821 r256619 133 133 PASS Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document 134 134 PASS Element.animate() calls play on the Animation 135 PASS Element.animate() does NOT trigger a style change event 135 FAIL Element.animate() does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 136 136 PASS animate() with pseudoElement parameter creates an Animation object 137 137 PASS animate() with pseudoElement parameter without content creates an Animation object -
trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animation/style-change-events-expected.txt
r252969 r256619 21 21 FAIL Animation.updatePlaybackRate produces expected style change events assert_false: A transition should NOT have been triggered expected false got true 22 22 FAIL Animation.reverse produces expected style change events assert_false: A transition should NOT have been triggered expected false got true 23 PASS Animation.persist produces expected style change events 23 FAIL Animation.persist produces expected style change events assert_false: A transition should NOT have been triggered expected false got true 24 24 FAIL Animation.commitStyles produces expected style change events assert_true: A transition should have been triggered expected true got false 25 25 FAIL Animation.Animation constructor produces expected style change events assert_false: A transition should NOT have been triggered expected false got true -
trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt
r255821 r256619 1 1 2 2 FAIL All property keys are recognized assert_in_array: Test property 'pseudoElement' should be one of the properties on KeyframeEffect value "pseudoElement" not in array ["getTiming", "getComputedTiming", "updateTiming", "target", "iterationComposite", "composite", "getKeyframes", "setKeyframes", "KeyframeEffect constructor", "KeyframeEffect copy constructor"] 3 PASS KeyframeEffect.getTiming does NOT trigger a style change event 4 PASS KeyframeEffect.getComputedTiming does NOT trigger a style change event 5 PASS KeyframeEffect.updateTiming does NOT trigger a style change event 6 PASS KeyframeEffect.target does NOT trigger a style change event 7 PASS KeyframeEffect.iterationComposite does NOT trigger a style change event 8 PASS KeyframeEffect.composite does NOT trigger a style change event 9 PASS KeyframeEffect.getKeyframes does NOT trigger a style change event 10 PASS KeyframeEffect.setKeyframes does NOT trigger a style change event 11 PASS KeyframeEffect.KeyframeEffect constructor does NOT trigger a style change event 12 PASS KeyframeEffect.KeyframeEffect copy constructor does NOT trigger a style change event 3 FAIL KeyframeEffect.getTiming does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 4 FAIL KeyframeEffect.getComputedTiming does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 5 FAIL KeyframeEffect.updateTiming does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 6 FAIL KeyframeEffect.target does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 7 FAIL KeyframeEffect.iterationComposite does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 8 FAIL KeyframeEffect.composite does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 9 FAIL KeyframeEffect.getKeyframes does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 10 FAIL KeyframeEffect.setKeyframes does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 11 FAIL KeyframeEffect.KeyframeEffect constructor does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 12 FAIL KeyframeEffect.KeyframeEffect copy constructor does NOT trigger a style change event assert_false: A transition should NOT have been triggered expected false got true 13 13 -
trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-expected.txt
r250263 r256619 3 3 PASS Fires finish event before requestAnimationFrame 4 4 FAIL Sorts finish events by composite order assert_array_equals: finish events for various animation type should be sorted by composite order property 0, expected "CSSTransition:finish" but got "ScriptAnimation:finish" 5 FAIL Sorts cancel events by composite order assert_array_equals: cancel events should be sorted by composite order lengths differ, expected 5 got 36 FAIL Queues a cancel event in transitionstart event callback assert_approx_equals: A rAF callback should happen in the same frame expected 112 +/- 0.001 but got 96 7 FAIL Sorts events for the same transition assert_array_equals: Playback and CSS events for the same transition should be sorted by schedule event time and composite order lengths differ, expected 2 got 1 5 FAIL Sorts cancel events by composite order assert_array_equals: cancel events should be sorted by composite order property 0, expected "CSSTransition:cancel" but got "ScriptAnimation:cancel" 6 PASS Queues a cancel event in transitionstart event callback 7 PASS Sorts events for the same transition 8 8 PASS Playback events with the same timeline retain the order in which they arequeued 9 9 FAIL All timelines are updated before running microtasks promise_test: Unhandled rejection with value: object "AbortError: The operation was aborted." -
trunk/LayoutTests/webanimations/css-transition-in-flight-reversal-accelerated.html
r252527 r256619 47 47 assert_true(initialTransition instanceof CSSTransition, "There is one animation applied to the target after starting the initial transition."); 48 48 49 // Wait for the initial transition to start and then another frame before reversing the transition. 49 // Wait for the initial transition to start and then two frames before reversing the transition, to be certain that the animation did start. 50 // Indeed, the "transitionstart" event will be fired right before the next rAF callback is called, as the animation starts in that very same 51 // frame, and so progress will be 0 and the transition wouldn't be reversable until the next frame when the animation has progress > 0. 50 52 target.addEventListener("transitionstart", event => { 51 53 requestAnimationFrame(() => { 52 target.classList.remove("in-flight"); 53 const animations = target.getAnimations(); 54 assert_equals(animations.length, 1, "There is one animation applied to the target after reversing the initial transition."); 54 requestAnimationFrame(() => { 55 target.classList.remove("in-flight"); 56 const animations = target.getAnimations(); 57 assert_equals(animations.length, 1, "There is one animation applied to the target after reversing the initial transition."); 55 58 56 reversedTransition = animations[0];57 assert_true(reversedTransition instanceof CSSTransition, "There is one animation applied to the target after reversing the initial transition.");58 assert_not_equals(initialTransition, reversedTransition, "The animation applied to the target after reversing the initial transition is different than the original transition.");59 reversedTransition = animations[0]; 60 assert_true(reversedTransition instanceof CSSTransition, "There is one animation applied to the target after reversing the initial transition."); 61 assert_not_equals(initialTransition, reversedTransition, "The animation applied to the target after reversing the initial transition is different than the original transition."); 59 62 60 target.remove(); 61 test.done(); 63 target.remove(); 64 test.done(); 65 }); 62 66 }); 63 67 }); -
trunk/Source/WebCore/ChangeLog
r256610 r256619 1 2020-02-14 Antoine Quint <graouts@webkit.org> 2 3 [Web Animations] Ensure CSS Transition and CSS Animation events are queued, sorted and dispatched by their timeline 4 https://bugs.webkit.org/show_bug.cgi?id=207364 5 <rdar://problem/59370413> 6 7 Reviewed by Simon Fraser. 8 9 Until now, AnimationPlaybackEvent events, which are new events introduced by the Web Animations spec, were enqueued in a shared queue on the DocumentTimeline 10 and dispatched during the "update animations and send events" procedure. However, AnimationEvent and TransitionEvent events, dispatched by CSS Animations 11 and CSS Transitions, were dispatched via a dedicated per-animation queue, which meant typically that those events were dispathed one runloop after the 12 AnimationPlaybackEvent events. 13 14 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 15 events" procedure. To do this correctly, we need to do a couple of other things that ensure we don't regress tests. 16 17 First, we update the DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() to account for whether there are pending animation events, 18 guaranteeing that an animation update is scheduled should there be any. 19 20 Second, when animation events are enqueued in DocumentTimeline::enqueueAnimationEvent() we schedule an animation update if needed, since we know we now 21 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" 22 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 23 prematurely schedule animation resolution. The need for a new animation resolution will be checked at the end of the procedure. 24 25 Finally, declarative animations used to have a special suclass of WebAnimation::needsTick() that would check whether they had any pending events, ensuring 26 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" 27 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 28 the DocumentTimeline has had a chance to dispatch the enqueued event. 29 30 Note also that, for clarity, the DocumentTimeline::unscheduleAnimationResolution() was renamed to DocumentTimeline::clearTickScheduleTimer() since it wouldn't 31 actually cancel a previous animation resolution schedule. 32 33 * animation/CSSTransition.h: Fix a newly found build error due to the missing wtf/MonotonicTime.h header. 34 * animation/DeclarativeAnimation.cpp: Remove all code related to the dedicated per-animation queue and instead call the new WebAnimation::enqueueAnimationEvent() 35 method to enqueue events on the DocumentTimeline. 36 (WebCore::DeclarativeAnimation::DeclarativeAnimation): 37 (WebCore::DeclarativeAnimation::tick): 38 (WebCore::DeclarativeAnimation::enqueueDOMEvent): 39 * animation/DeclarativeAnimation.h: 40 * animation/DocumentTimeline.cpp: 41 (WebCore::DocumentTimeline::detachFromDocument): Ensure the pending events queue is cleared when the timeline is detached from a document, ensuring that there no 42 longer events that would cause a ref-cycle (DocumentTimeline -> AnimationPlaybackEvent -> WebAnimation -> DocumentTimeline). 43 (WebCore::DocumentTimeline::suspendAnimations): 44 (WebCore::DocumentTimeline::removeAnimation): 45 (WebCore::DocumentTimeline::scheduleAnimationResolution): 46 (WebCore::DocumentTimeline::clearTickScheduleTimer): 47 (WebCore::DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState const): 48 (WebCore::DocumentTimeline::updateCurrentTime): 49 (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): 50 (WebCore::DocumentTimeline::internalUpdateAnimationsAndSendEvents): 51 (WebCore::DocumentTimeline::scheduleNextTick): 52 (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange): 53 (WebCore::DocumentTimeline::enqueueAnimationEvent): 54 * animation/DocumentTimeline.h: 55 * animation/WebAnimation.cpp: 56 (WebCore::WebAnimation::enqueueAnimationPlaybackEvent): 57 (WebCore::WebAnimation::enqueueAnimationEvent): 58 (WebCore::WebAnimation::needsTick const): 59 (WebCore::WebAnimation::tick): 60 * animation/WebAnimation.h: 61 62 2020-02-14 Antoine Quint <graouts@webkit.org> 63 64 [Web Animations] Make all animation event types inherit from the same base class 65 https://bugs.webkit.org/show_bug.cgi?id=207629 66 67 Reviewed by Simon Fraser. 68 69 Currently we dispatch events CSS Transitions and CSS Animations events using a dedicated event queue on DeclarativeAnimation, while the events 70 added by the Web Animations specification (of type AnimationPlaybackEvent) are dispatched using a shared queue on the DocumentTimeline that is 71 processed during the "update animations and send events procedure". The Web Animations specification dictates that all events should be dispatched 72 during that procedure, which includes sorting of such events based on their timeline time and associated animation relative composite order. 73 74 In this patch, we prepare the work towards spec compliance for animation events dispatch by making all event types (AnimationPlaybackEvent, 75 TransitionEvent and AnimationEvent) inherit from a single AnimationEventBase interface. This will allow DocumentTimeline to enqueue, sort and 76 dispatch all such events with a single queue in a future patch. 77 78 Due to CSSAnimationController, we must make the "timeline time" and "animation" parameters optional. When we drop support for CSSAnimationController 79 we'll be able to enforce stronger requirements for these. 80 81 No new test since this should not introduce any behavior change. 82 83 * Sources.txt: 84 * WebCore.xcodeproj/project.pbxproj: 85 * animation/AnimationEventBase.cpp: Added. 86 (WebCore::AnimationEventBase::AnimationEventBase): 87 * animation/AnimationEventBase.h: Added. 88 (WebCore::AnimationEventBase::create): 89 (WebCore::AnimationEventBase::isAnimationPlaybackEvent const): 90 (WebCore::AnimationEventBase::isAnimationEvent const): 91 (WebCore::AnimationEventBase::isTransitionEvent const): 92 (WebCore::AnimationEventBase::timelineTime const): 93 (WebCore::AnimationEventBase::animation const): 94 * animation/AnimationPlaybackEvent.cpp: 95 (WebCore::AnimationPlaybackEvent::AnimationPlaybackEvent): 96 (WebCore::AnimationPlaybackEvent::bindingsTimelineTime const): 97 * animation/AnimationPlaybackEvent.h: 98 * animation/CSSAnimation.cpp: 99 (WebCore::CSSAnimation::createEvent): 100 * animation/CSSAnimation.h: 101 * animation/CSSTransition.cpp: 102 (WebCore::CSSTransition::createEvent): 103 * animation/CSSTransition.h: 104 * animation/DeclarativeAnimation.cpp: 105 (WebCore::DeclarativeAnimation::enqueueDOMEvent): 106 * animation/DeclarativeAnimation.h: 107 * animation/WebAnimation.cpp: 108 (WebCore::WebAnimation::enqueueAnimationPlaybackEvent): 109 * dom/AnimationEvent.cpp: 110 (WebCore::AnimationEvent::AnimationEvent): 111 * dom/AnimationEvent.h: 112 * dom/TransitionEvent.cpp: 113 (WebCore::TransitionEvent::TransitionEvent): 114 * dom/TransitionEvent.h: 115 * page/animation/CSSAnimationController.cpp: 116 (WebCore::CSSAnimationControllerPrivate::fireEventsAndUpdateStyle): 117 1 118 2020-02-14 Antoine Quint <graouts@webkit.org> 2 119 -
trunk/Source/WebCore/animation/CSSTransition.h
r256610 r256619 28 28 #include "CSSPropertyNames.h" 29 29 #include "DeclarativeAnimation.h" 30 #include <wtf/MonotonicTime.h> 30 31 #include <wtf/Ref.h> 31 32 -
trunk/Source/WebCore/animation/DeclarativeAnimation.cpp
r256610 r256619 43 43 DeclarativeAnimation::DeclarativeAnimation(Element& owningElement, const Animation& backingAnimation) 44 44 : WebAnimation(owningElement.document()) 45 , m_eventQueue(MainThreadGenericEventQueue::create(owningElement))46 45 , m_owningElement(&owningElement) 47 46 , m_backingAnimation(const_cast<Animation&>(backingAnimation)) … … 64 63 // From this point on, this animation is like any other animation and should not appear in the 65 64 // maps containing running CSS Transitions and CSS Animations for a given element. 66 if (wasRelevant && playState() == WebAnimation::PlayState::Idle) {65 if (wasRelevant && playState() == WebAnimation::PlayState::Idle) 67 66 disassociateFromOwningElement(); 68 m_eventQueue->close();69 }70 67 } 71 68 … … 89 86 animationTimeline->removeDeclarativeAnimationFromListsForOwningElement(*this, *m_owningElement); 90 87 m_owningElement = nullptr; 91 }92 93 bool DeclarativeAnimation::needsTick() const94 {95 return WebAnimation::needsTick() || m_eventQueue->hasPendingEvents();96 }97 98 void DeclarativeAnimation::remove()99 {100 m_eventQueue->close();101 WebAnimation::remove();102 88 } 103 89 … … 352 338 const auto& pseudoId = PseudoElement::pseudoElementNameForEvents(m_owningElement->pseudoId()); 353 339 auto timelineTime = timeline() ? timeline()->currentTime() : WTF::nullopt; 354 m_eventQueue->enqueueEvent(createEvent(eventType, time, pseudoId, timelineTime)); 340 auto event = createEvent(eventType, time, pseudoId, timelineTime); 341 event->setTarget(m_owningElement); 342 enqueueAnimationEvent(WTFMove(event)); 355 343 } 356 344 -
trunk/Source/WebCore/animation/DeclarativeAnimation.h
r256610 r256619 28 28 #include "AnimationEffect.h" 29 29 #include "AnimationEffectPhase.h" 30 #include "GenericEventQueue.h"31 30 #include "WebAnimation.h" 32 31 #include <wtf/Ref.h> … … 66 65 void cancel() final; 67 66 68 bool needsTick() const override;69 67 void tick() override; 70 68 … … 86 84 AnimationEffectPhase phaseWithoutEffect() const; 87 85 void enqueueDOMEvent(const AtomString&, Seconds); 88 void remove() final;89 86 90 87 bool m_wasPending { false }; 91 88 AnimationEffectPhase m_previousPhase { AnimationEffectPhase::Idle }; 92 93 UniqueRef<MainThreadGenericEventQueue> m_eventQueue;94 89 95 90 Element* m_owningElement; -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r256512 r256619 27 27 #include "DocumentTimeline.h" 28 28 29 #include "Animation PlaybackEvent.h"29 #include "AnimationEventBase.h" 30 30 #include "CSSAnimation.h" 31 31 #include "CSSTransition.h" … … 89 89 m_document->removeTimeline(*this); 90 90 91 m_pendingAnimationEvents.clear(); 91 92 m_currentTimeClearingTaskQueue.close(); 92 93 m_elementsWithRunningAcceleratedAnimations.clear(); … … 96 97 animationsToRemove.first()->remove(); 97 98 98 unscheduleAnimationResolution();99 clearTickScheduleTimer(); 99 100 m_document = nullptr; 100 101 } … … 235 236 applyPendingAcceleratedAnimations(); 236 237 237 unscheduleAnimationResolution();238 clearTickScheduleTimer(); 238 239 } 239 240 … … 328 329 AnimationTimeline::removeAnimation(animation); 329 330 331 if (m_animations.isEmpty()) 332 clearTickScheduleTimer(); 333 } 334 335 void DocumentTimeline::scheduleAnimationResolution() 336 { 337 if (m_isSuspended || m_animationResolutionScheduled || !m_document || !m_document->page()) 338 return; 339 340 // We need some relevant animations or pending events to proceed. 330 341 if (!shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState()) 331 unscheduleAnimationResolution();332 }333 334 void DocumentTimeline::scheduleAnimationResolution()335 {336 if (m_isSuspended || m_animationResolutionScheduled || !shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState())337 342 return; 338 343 339 if (!m_document || !m_document->page())340 return;341 342 344 m_document->page()->renderingUpdateScheduler().scheduleTimedRenderingUpdate(); 343 345 m_animationResolutionScheduled = true; 344 346 } 345 347 346 void DocumentTimeline:: unscheduleAnimationResolution()348 void DocumentTimeline::clearTickScheduleTimer() 347 349 { 348 350 m_tickScheduleTimer.stop(); 349 m_animationResolutionScheduled = false;350 351 } 351 352 352 353 bool DocumentTimeline::shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() const 353 354 { 354 return !m_animations.isEmpty() || !m_ acceleratedAnimationsPendingRunningStateChange.isEmpty();355 return !m_animations.isEmpty() || !m_pendingAnimationEvents.isEmpty() || !m_acceleratedAnimationsPendingRunningStateChange.isEmpty(); 355 356 } 356 357 … … 360 361 // document.timeline.currentTime may be called from a rAF callback and 361 362 // it has to match the rAF timestamp. 362 if (!m_isSuspended )363 if (!m_isSuspended || !shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState()) 363 364 cacheCurrentTime(timestamp); 364 365 } … … 366 367 void DocumentTimeline::updateAnimationsAndSendEvents() 367 368 { 368 if (m_isSuspended || !shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState())369 return;370 369 371 370 // Updating animations and sending events may invalidate the timing of some animations, so we must set the m_animationResolutionScheduled … … 373 372 m_animationResolutionScheduled = false; 374 373 374 if (m_isSuspended) 375 return; 376 377 if (!shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState()) 378 return; 379 375 380 internalUpdateAnimationsAndSendEvents(); 376 381 applyPendingAcceleratedAnimations(); … … 383 388 { 384 389 m_numberOfAnimationTimelineInvalidationsForTesting++; 390 391 // enqueueAnimationEvent() calls scheduleAnimationResolution() to ensure that the "update animations and send events" 392 // procedure is run and enqueued events are dispatched in the next frame. However, events that are enqueued while 393 // this procedure is running should not schedule animation resolution until the event queue has been cleared. 394 m_shouldScheduleAnimationResolutionForNewPendingEvents = false; 385 395 386 396 // https://drafts.csswg.org/web-animations/#update-animations-and-send-events … … 422 432 // 5. Clear doc's pending animation event queue. 423 433 auto pendingAnimationEvents = WTFMove(m_pendingAnimationEvents); 434 m_shouldScheduleAnimationResolutionForNewPendingEvents = true; 424 435 425 436 // 6. Perform a stable sort of the animation events in events to dispatch as follows. 426 std::stable_sort(pendingAnimationEvents.begin(), pendingAnimationEvents.end(), [] (const Ref<Animation PlaybackEvent>& lhs, const Ref<AnimationPlaybackEvent>& rhs) {437 std::stable_sort(pendingAnimationEvents.begin(), pendingAnimationEvents.end(), [] (const Ref<AnimationEventBase>& lhs, const Ref<AnimationEventBase>& rhs) { 427 438 // 1. Sort the events by their scheduled event time such that events that were scheduled to occur earlier, sort before events scheduled to occur later 428 439 // and events whose scheduled event time is unresolved sort before events with a resolved scheduled event time. … … 438 449 439 450 // 7. Dispatch each of the events in events to dispatch at their corresponding target using the order established in the previous step. 440 for (auto& pending Event : pendingAnimationEvents)441 pending Event->target()->dispatchEvent(pendingEvent);451 for (auto& pendingAnimationEvent : pendingAnimationEvents) 452 pendingAnimationEvent->target()->dispatchEvent(pendingAnimationEvent); 442 453 443 454 // This will cancel any scheduled invalidation if we end up removing all animations. … … 548 559 void DocumentTimeline::scheduleNextTick() 549 560 { 561 // If we have pending animation events, we need to schedule an update right away. 562 if (!m_pendingAnimationEvents.isEmpty()) 563 scheduleAnimationResolution(); 564 550 565 // There is no tick to schedule if we don't have any relevant animations. 551 566 if (m_animations.isEmpty()) … … 666 681 scheduleAnimationResolution(); 667 682 else 668 unscheduleAnimationResolution();683 clearTickScheduleTimer(); 669 684 } 670 685 … … 709 724 } 710 725 711 void DocumentTimeline::enqueueAnimation PlaybackEvent(AnimationPlaybackEvent& event)726 void DocumentTimeline::enqueueAnimationEvent(AnimationEventBase& event) 712 727 { 713 728 m_pendingAnimationEvents.append(event); 729 if (m_shouldScheduleAnimationResolutionForNewPendingEvents) 730 scheduleAnimationResolution(); 714 731 } 715 732 -
trunk/Source/WebCore/animation/DocumentTimeline.h
r256512 r256619 36 36 namespace WebCore { 37 37 38 class Animation PlaybackEvent;38 class AnimationEventBase; 39 39 class RenderElement; 40 40 … … 71 71 void detachFromDocument(); 72 72 73 void enqueueAnimation PlaybackEvent(AnimationPlaybackEvent&);73 void enqueueAnimationEvent(AnimationEventBase&); 74 74 75 75 bool scheduledUpdate() const { return m_animationResolutionScheduled; } … … 93 93 void maybeClearCachedCurrentTime(); 94 94 void scheduleInvalidationTaskIfNeeded(); 95 void performInvalidationTask();96 95 void scheduleAnimationResolution(); 97 void unscheduleAnimationResolution();96 void clearTickScheduleTimer(); 98 97 void internalUpdateAnimationsAndSendEvents(); 99 void performEventDispatchTask();100 98 void updateListOfElementsWithRunningAcceleratedAnimationsForElement(Element&); 101 99 void transitionDidComplete(RefPtr<CSSTransition>); … … 109 107 HashSet<RefPtr<WebAnimation>> m_acceleratedAnimationsPendingRunningStateChange; 110 108 HashSet<Element*> m_elementsWithRunningAcceleratedAnimations; 111 Vector<Ref<Animation PlaybackEvent>> m_pendingAnimationEvents;109 Vector<Ref<AnimationEventBase>> m_pendingAnimationEvents; 112 110 RefPtr<Document> m_document; 113 111 Markable<Seconds, Seconds::MarkableTraits> m_cachedCurrentTime; … … 117 115 bool m_waitingOnVMIdle { false }; 118 116 bool m_animationResolutionScheduled { false }; 117 bool m_shouldScheduleAnimationResolutionForNewPendingEvents { true }; 119 118 }; 120 119 -
trunk/Source/WebCore/animation/WebAnimation.cpp
r256610 r256619 686 686 auto event = AnimationPlaybackEvent::create(type, currentTime, timelineTime, this); 687 687 event->setTarget(this); 688 688 enqueueAnimationEvent(WTFMove(event)); 689 } 690 691 void WebAnimation::enqueueAnimationEvent(Ref<AnimationEventBase>&& event) 692 { 689 693 if (is<DocumentTimeline>(m_timeline)) { 690 694 // If animation has a document for timing, then append event to its document for timing's pending animation event queue along … … 692 696 // to origin-relative time, let the scheduled event time be the result of applying that procedure to timeline time. Otherwise, the 693 697 // scheduled event time is an unresolved time value. 694 downcast<DocumentTimeline>(*m_timeline).enqueueAnimationPlaybackEvent(WTFMove(event)); 698 m_hasScheduledEventsDuringTick = true; 699 downcast<DocumentTimeline>(*m_timeline).enqueueAnimationEvent(WTFMove(event)); 695 700 } else { 696 701 // Otherwise, queue a task to dispatch event at animation. The task source for this task is the DOM manipulation task source. … … 1199 1204 bool WebAnimation::needsTick() const 1200 1205 { 1201 return pending() || playState() == PlayState::Running ;1206 return pending() || playState() == PlayState::Running || m_hasScheduledEventsDuringTick; 1202 1207 } 1203 1208 1204 1209 void WebAnimation::tick() 1205 1210 { 1211 m_hasScheduledEventsDuringTick = false; 1206 1212 updateFinishedState(DidSeek::No, SynchronouslyNotify::Yes); 1207 1213 m_shouldSkipUpdatingFinishedStateWhenResolving = true; -
trunk/Source/WebCore/animation/WebAnimation.h
r255663 r256619 43 43 44 44 class AnimationEffect; 45 class Animation PlaybackEvent;45 class AnimationEventBase; 46 46 class AnimationTimeline; 47 47 class Document; … … 117 117 virtual ExceptionOr<void> bindingsPause() { return pause(); } 118 118 119 virtualbool needsTick() const;119 bool needsTick() const; 120 120 virtual void tick(); 121 121 Seconds timeToNextTick() const; … … 136 136 bool isSuspended() const { return m_isSuspended; } 137 137 bool isReplaceable() const; 138 v irtual void remove();138 void remove(); 139 139 void enqueueAnimationPlaybackEvent(const AtomString&, Optional<Seconds>, Optional<Seconds>); 140 140 … … 155 155 protected: 156 156 explicit WebAnimation(Document&); 157 158 void enqueueAnimationEvent(Ref<AnimationEventBase>&&); 157 159 158 160 private: … … 202 204 bool m_isRelevant; 203 205 bool m_shouldSkipUpdatingFinishedStateWhenResolving; 206 bool m_hasScheduledEventsDuringTick { false }; 204 207 TimeToRunPendingTask m_timeToRunPendingPlayTask { TimeToRunPendingTask::NotScheduled }; 205 208 TimeToRunPendingTask m_timeToRunPendingPauseTask { TimeToRunPendingTask::NotScheduled };
Note: See TracChangeset
for help on using the changeset viewer.