Bug 1420928 - Reuse computed values for animation properties repeatedly if the computed values' length is less than animation-name length. r=boris
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 05 Jan 2018 06:24:09 +0900
changeset 449656 2004d0192d0c10e3edf5b4bc82dc2e2a26673788
parent 449655 fa35bc2879ad5e01bf3103d779bb160d067eb9b6
child 449657 2cf3e262e0d4ba41de112d199c6f2ca055cdec65
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersboris
bugs1420928
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 1420928 - Reuse computed values for animation properties repeatedly if the computed values' length is less than animation-name length. r=boris MozReview-Commit-ID: DSmUlE9m0UI
layout/style/nsAnimationManager.cpp
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -585,43 +585,47 @@ UpdateOldAnimationPropertiesWithNew(
 
 // Returns a new animation set up with given StyleAnimation.
 // Or returns an existing animation matching StyleAnimation's name updated
 // with the new StyleAnimation.
 template<class BuilderType>
 static already_AddRefed<CSSAnimation>
 BuildAnimation(nsPresContext* aPresContext,
                const NonOwningAnimationTarget& aTarget,
-               const StyleAnimation& aSrc,
+               const nsStyleDisplay& aStyleDisplay,
+               uint32_t animIdx,
                BuilderType& aBuilder,
                nsAnimationManager::CSSAnimationCollection* aCollection)
 {
   MOZ_ASSERT(aPresContext);
 
+  nsAtom* animationName = aStyleDisplay.GetAnimationName(animIdx);
   nsTArray<Keyframe> keyframes;
   if (!aBuilder.BuildKeyframes(aPresContext,
-                               aSrc.GetName(),
-                               aSrc.GetTimingFunction(),
+                               animationName,
+                               aStyleDisplay.GetAnimationTimingFunction(animIdx),
                                keyframes)) {
     return nullptr;
   }
 
-  TimingParams timing = TimingParamsFromCSSParams(aSrc.GetDuration(),
-                                                  aSrc.GetDelay(),
-                                                  aSrc.GetIterationCount(),
-                                                  aSrc.GetDirection(),
-                                                  aSrc.GetFillMode());
+  TimingParams timing =
+    TimingParamsFromCSSParams(aStyleDisplay.GetAnimationDuration(animIdx),
+                              aStyleDisplay.GetAnimationDelay(animIdx),
+                              aStyleDisplay.GetAnimationIterationCount(animIdx),
+                              aStyleDisplay.GetAnimationDirection(animIdx),
+                              aStyleDisplay.GetAnimationFillMode(animIdx));
 
   bool isStylePaused =
-    aSrc.GetPlayState() == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
+    aStyleDisplay.GetAnimationPlayState(animIdx) ==
+      NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
 
   // Find the matching animation with animation name in the old list
   // of animations and remove the matched animation from the list.
   RefPtr<CSSAnimation> oldAnim =
-    PopExistingAnimation(aSrc.GetName(), aCollection);
+    PopExistingAnimation(animationName, aCollection);
 
   if (oldAnim) {
     // Copy over the start times and (if still paused) pause starts
     // for each animation (matching on name only) that was also in the
     // old list of animations.
     // This means that we honor dynamic changes, which isn't what the
     // spec says to do, but WebKit seems to honor at least some of
     // them.  See
@@ -641,18 +645,17 @@ BuildAnimation(nsPresContext* aPresConte
   KeyframeEffectParams effectOptions;
   RefPtr<KeyframeEffectReadOnly> effect =
     new KeyframeEffectReadOnly(aPresContext->Document(), target, timing,
                                effectOptions);
 
   aBuilder.SetKeyframes(*effect, Move(keyframes));
 
   RefPtr<CSSAnimation> animation =
-    new CSSAnimation(aPresContext->Document()->GetScopeObject(),
-                     aSrc.GetName());
+    new CSSAnimation(aPresContext->Document()->GetScopeObject(), animationName);
   animation->SetOwningElement(
     OwningElementRef(*aTarget.mElement, aTarget.mPseudoType));
 
   animation->SetTimelineNoUpdate(aTarget.mElement->OwnerDoc()->Timeline());
   animation->SetEffectNoUpdate(effect);
 
   if (isStylePaused) {
     animation->PauseFromStyle();
@@ -1010,38 +1013,36 @@ GeckoCSSAnimationBuilder::FillInMissingK
     }
   }
 }
 
 template<class BuilderType>
 static nsAnimationManager::OwningCSSAnimationPtrArray
 BuildAnimations(nsPresContext* aPresContext,
                 const NonOwningAnimationTarget& aTarget,
-                const nsStyleAutoArray<StyleAnimation>& aStyleAnimations,
-                uint32_t aStyleAnimationNameCount,
+                const nsStyleDisplay& aStyleDisplay,
                 BuilderType& aBuilder,
                 nsAnimationManager::CSSAnimationCollection* aCollection)
 {
   nsAnimationManager::OwningCSSAnimationPtrArray result;
 
-  for (size_t animIdx = aStyleAnimationNameCount; animIdx-- != 0;) {
-    const StyleAnimation& src = aStyleAnimations[animIdx];
-
+  for (size_t animIdx = aStyleDisplay.mAnimationNameCount; animIdx-- != 0;) {
     // CSS Animations whose animation-name does not match a @keyframes rule do
     // not generate animation events. This includes when the animation-name is
     // "none" which is represented by an empty name in the StyleAnimation.
     // Since such animations neither affect style nor dispatch events, we do
     // not generate a corresponding CSSAnimation for them.
-    if (src.GetName() == nsGkAtoms::_empty) {
+    if (aStyleDisplay.GetAnimationName(animIdx) == nsGkAtoms::_empty) {
       continue;
     }
 
     RefPtr<CSSAnimation> dest = BuildAnimation(aPresContext,
                                                aTarget,
-                                               src,
+                                               aStyleDisplay,
+                                               animIdx,
                                                aBuilder,
                                                aCollection);
     if (!dest) {
       continue;
     }
 
     dest->SetAnimationIndex(static_cast<uint64_t>(animIdx));
     result.AppendElement(dest);
@@ -1127,18 +1128,17 @@ nsAnimationManager::DoUpdateAnimations(
 
   nsAutoAnimationMutationBatch mb(aTarget.mElement->OwnerDoc());
 
   // Build the updated animations list, extracting matching animations from
   // the existing collection as we go.
   OwningCSSAnimationPtrArray newAnimations;
   newAnimations = BuildAnimations(mPresContext,
                                   aTarget,
-                                  aStyleDisplay.mAnimations,
-                                  aStyleDisplay.mAnimationNameCount,
+                                  aStyleDisplay,
                                   aBuilder,
                                   collection);
 
   if (newAnimations.IsEmpty()) {
     if (collection) {
       collection->Destroy();
     }
     return;