Bug 1430924 - Queue a bunch of animation events at once. r=boris
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Wed, 17 Jan 2018 08:13:01 +0900
changeset 399612 55a05cde7eb705a4bcbf32c783fa2d92fc9afd8c
parent 399611 43280c5e33c524633ad9864bf867275d858ead67
child 399613 0d52b29a58e7d3d9212bde50433499d1c66c41f9
push id33271
push usertoros@mozilla.com
push dateWed, 17 Jan 2018 21:46:52 +0000
treeherdermozilla-central@3fb310e17608 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersboris
bugs1430924
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1430924 - Queue a bunch of animation events at once. r=boris MozReview-Commit-ID: BjRjohOFA7V
layout/style/AnimationCommon.h
layout/style/nsAnimationManager.cpp
layout/style/nsTransitionManager.cpp
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -71,22 +71,22 @@ public:
       return;
     }
 
     nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
     collection->Destroy();
   }
 
   /**
-   * Add a pending event.
+   * Add pending events.
    */
-  void QueueEvent(AnimationEventType&& aEventInfo)
+  void QueueEvents(nsTArray<AnimationEventType>&& aEvents)
   {
-    mEventDispatcher.QueueEvent(
-      mozilla::Forward<AnimationEventType>(aEventInfo));
+    mEventDispatcher.QueueEvents(
+      mozilla::Forward<nsTArray<AnimationEventType>>(aEvents));
   }
 
   void SortEvents()      { mEventDispatcher.SortEvents(); }
   void ClearEventQueue() { mEventDispatcher.ClearEventQueue(); }
 
 protected:
   virtual ~CommonAnimationManager()
   {
@@ -180,19 +180,19 @@ private:
 };
 
 template <class EventInfo>
 class DelayedEventDispatcher
 {
 public:
   DelayedEventDispatcher() : mIsSorted(true) { }
 
-  void QueueEvent(EventInfo&& aEventInfo)
+  void QueueEvents(nsTArray<EventInfo>&& aEvents)
   {
-    mPendingEvents.AppendElement(Forward<EventInfo>(aEventInfo));
+    mPendingEvents.AppendElements(Forward<nsTArray<EventInfo>>(aEvents));
     mIsSorted = false;
   }
 
   // This is exposed as a separate method so that when we are dispatching
   // *both* transition events and animation events we can sort both lists
   // once using the current state of the document before beginning any
   // dispatch.
   void SortEvents()
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -197,18 +197,16 @@ CSSAnimation::QueueEvents(StickyTimeDura
   if (!mOwningElement.IsSet()) {
     return;
   }
 
   nsPresContext* presContext = mOwningElement.GetPresContext();
   if (!presContext) {
     return;
   }
-  // Get the nsAnimationManager so we can queue events on it
-  nsAnimationManager* manager = presContext->AnimationManager();
 
   const StickyTimeDuration zeroDuration;
   uint64_t currentIteration = 0;
   ComputedTiming::AnimationPhase currentPhase;
   StickyTimeDuration intervalStartTime;
   StickyTimeDuration intervalEndTime;
   StickyTimeDuration iterationStartTime;
 
@@ -303,23 +301,31 @@ CSSAnimation::QueueEvents(StickyTimeDura
                                                    intervalEndTime,
                                                    endTimeStamp });
       }
       break;
   }
   mPreviousPhase = currentPhase;
   mPreviousIteration = currentIteration;
 
+  if (events.IsEmpty()) {
+    return;
+  }
+
+  AutoTArray<AnimationEventInfo, 2> animationEvents;
   for (const AnimationEventParams& event : events){
-    manager->QueueEvent(
-               AnimationEventInfo(mOwningElement.Target(),
-                                  event.mMessage, mAnimationName,
-                                  event.mElapsedTime, event.mTimeStamp,
-                                  this));
+    animationEvents.AppendElement(
+      AnimationEventInfo(mOwningElement.Target(),
+                         event.mMessage,
+                         mAnimationName,
+                         event.mElapsedTime,
+                         event.mTimeStamp,
+                         this));
   }
+  presContext->AnimationManager()->QueueEvents(Move(animationEvents));
 }
 
 void
 CSSAnimation::UpdateTiming(SeekFlag aSeekFlag, SyncNotifyFlag aSyncNotifyFlag)
 {
   if (mNeedsNewAnimationIndexWhenRun &&
       PlayState() != AnimationPlayState::Idle) {
     mAnimationIndex = sNextAnimationIndex++;
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -336,25 +336,31 @@ CSSTransition::QueueEvents(StickyTimeDur
         events.AppendElement(TransitionEventParams{ eTransitionEnd,
                                                     intervalStartTime,
                                                     endTimeStamp });
       }
       break;
   }
   mPreviousTransitionPhase = currentPhase;
 
-  nsTransitionManager* manager = presContext->TransitionManager();
+  if (events.IsEmpty()) {
+    return;
+  }
+
+  AutoTArray<TransitionEventInfo, 3> transitionEvents;
   for (const TransitionEventParams& evt : events) {
-    manager->QueueEvent(TransitionEventInfo(mOwningElement.Target(),
-                                            evt.mMessage,
-                                            TransitionProperty(),
-                                            evt.mElapsedTime,
-                                            evt.mTimeStamp,
-                                            this));
+    transitionEvents.AppendElement(
+      TransitionEventInfo(mOwningElement.Target(),
+                          evt.mMessage,
+                          TransitionProperty(),
+                          evt.mElapsedTime,
+                          evt.mTimeStamp,
+                          this));
   }
+  presContext->TransitionManager()->QueueEvents(Move(transitionEvents));
 }
 
 void
 CSSTransition::Tick()
 {
   Animation::Tick();
   QueueEvents();
 }