Bug 1341987 - Part 3: Update the last refresh time for transform only when we send transform animations to the compositor. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Mon, 27 Feb 2017 11:34:46 +0900
changeset 489885 a818a00368df0cd8751700d2e9c0d6b059f9ba7e
parent 489884 a6ef92e3ae5d09ddd501e60e14afbf155df3ac60
child 489886 844d61344f2791f7d17ff1b08370ea53c611e57a
push id46933
push userhikezoe@mozilla.com
push dateMon, 27 Feb 2017 02:38:59 +0000
reviewersbirtles
bugs1341987
milestone54.0a1
Bug 1341987 - Part 3: Update the last refresh time for transform only when we send transform animations to the compositor. r?birtles We don't need to update the time during composing style, we just need to update when transform animations are sent to the compositor. The most recent refresh time of nsRefreshDriver should be the same in either side. If the time is skewed, that means we skip composing style, if it happened that's another bug. MozReview-Commit-ID: Dxtuocf1ml1
dom/animation/EffectCompositor.cpp
dom/animation/EffectCompositor.h
layout/painting/nsDisplayList.cpp
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -368,22 +368,21 @@ EffectCompositor::MaybeUpdateAnimationRu
 {
   // First update cascade results since that may cause some elements to
   // be marked as needing a restyle.
   MaybeUpdateCascadeResults(aElement, aPseudoType, aStyleContext);
 
   auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
   PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
 
-  if (!mPresContext || !elementsToRestyle.Contains(key)) {
+  if (!elementsToRestyle.Contains(key)) {
     return;
   }
 
-  ComposeAnimationRule(aElement, aPseudoType, aCascadeLevel,
-                       mPresContext->RefreshDriver()->MostRecentRefresh());
+  ComposeAnimationRule(aElement, aPseudoType, aCascadeLevel);
 
   elementsToRestyle.Remove(key);
 }
 
 nsIStyleRule*
 EffectCompositor::GetAnimationRule(dom::Element* aElement,
                                    CSSPseudoElementType aPseudoType,
                                    CascadeLevel aCascadeLevel,
@@ -488,18 +487,16 @@ EffectCompositor::GetServoAnimationRule(
   const nsCSSPropertyIDSet propertiesToSkip;
   for (KeyframeEffectReadOnly* effect : sortedEffectList) {
     effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
   }
 
   MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
 
-  effectSet->UpdateLastTransformSyncTime(
-    mPresContext->RefreshDriver()->MostRecentRefresh());
   return animRule.mServo;
 }
 
 void
 EffectCompositor::ClearElementsToRestyle()
 {
   MOZ_ASSERT(NS_IsMainThread());
   const auto iterEnd = mElementsToRestyle.end();
@@ -591,18 +588,17 @@ EffectCompositor::AddStyleUpdatesTo(Rest
 
     for (auto& pseudoElem : elementsToRestyle) {
       MaybeUpdateCascadeResults(pseudoElem.mElement,
                                 pseudoElem.mPseudoType,
                                 nullptr);
 
       ComposeAnimationRule(pseudoElem.mElement,
                            pseudoElem.mPseudoType,
-                           cascadeLevel,
-                           mPresContext->RefreshDriver()->MostRecentRefresh());
+                           cascadeLevel);
 
       dom::Element* elementToRestyle =
         GetElementToRestyle(pseudoElem.mElement, pseudoElem.mPseudoType);
       if (elementToRestyle) {
         nsRestyleHint rshint = cascadeLevel == CascadeLevel::Transitions ?
                                eRestyle_CSSTransitions :
                                eRestyle_CSSAnimations;
         aTracker.AddPendingRestyle(elementToRestyle, rshint, nsChangeHint(0));
@@ -724,18 +720,17 @@ EffectCompositor::GetAnimationElementAnd
   result.emplace(content->AsElement(), pseudoType);
 
   return result;
 }
 
 /* static */ void
 EffectCompositor::ComposeAnimationRule(dom::Element* aElement,
                                        CSSPseudoElementType aPseudoType,
-                                       CascadeLevel aCascadeLevel,
-                                       TimeStamp aRefreshTime)
+                                       CascadeLevel aCascadeLevel)
 {
   EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effects) {
     return;
   }
 
   // The caller is responsible for calling MaybeUpdateCascadeResults first.
   MOZ_ASSERT(!effects->CascadeNeedsUpdate(),
@@ -759,18 +754,16 @@ EffectCompositor::ComposeAnimationRule(d
     ? effects->PropertiesForAnimationsLevel().Invert()
     : effects->PropertiesForAnimationsLevel();
   for (KeyframeEffectReadOnly* effect : sortedEffectList) {
     effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
   }
 
   MOZ_ASSERT(effects == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
-
-  effects->UpdateLastTransformSyncTime(aRefreshTime);
 }
 
 /* static */ void
 EffectCompositor::GetOverriddenProperties(nsStyleContext* aStyleContext,
                                           EffectSet& aEffectSet,
                                           nsCSSPropertyIDSet&
                                             aPropertiesOverridden)
 {
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -235,18 +235,17 @@ public:
 
 private:
   ~EffectCompositor() = default;
 
   // Rebuilds the animation rule corresponding to |aCascadeLevel| on the
   // EffectSet associated with the specified (pseudo-)element.
   static void ComposeAnimationRule(dom::Element* aElement,
                                    CSSPseudoElementType aPseudoType,
-                                   CascadeLevel aCascadeLevel,
-                                   TimeStamp aRefreshTime);
+                                   CascadeLevel aCascadeLevel);
 
   static dom::Element* GetElementToRestyle(dom::Element* aElement,
                                            CSSPseudoElementType
                                              aPseudoType);
 
   // Get the properties in |aEffectSet| that we are able to animate on the
   // compositor but which are also specified at a higher level in the cascade
   // than the animations level in |aStyleContext|.
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -590,19 +590,20 @@ AddAnimationsForProperty(nsIFrame* aFram
                          nsTArray<RefPtr<dom::Animation>>& aAnimations,
                          Layer* aLayer, AnimationData& aData,
                          bool aPending)
 {
   MOZ_ASSERT(nsCSSProps::PropHasFlags(aProperty,
                                       CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR),
              "inconsistent property flags");
 
-  DebugOnly<EffectSet*> effects = EffectSet::GetEffectSet(aFrame);
+  EffectSet* effects = EffectSet::GetEffectSet(aFrame);
   MOZ_ASSERT(effects);
 
+  bool sentAnimations = false;
   // Add from first to last (since last overrides)
   for (size_t animIdx = 0; animIdx < aAnimations.Length(); animIdx++) {
     dom::Animation* anim = aAnimations[animIdx];
     if (!anim->IsRelevant()) {
       continue;
     }
 
     dom::KeyframeEffectReadOnly* keyframeEffect =
@@ -639,16 +640,22 @@ AddAnimationsForProperty(nsIFrame* aFram
     if (anim->PlayState() == AnimationPlayState::Pending &&
         (anim->GetTimeline() &&
          !anim->GetTimeline()->TracksWallclockTime())) {
       continue;
     }
 
     AddAnimationForProperty(aFrame, *property, anim, aLayer, aData, aPending);
     keyframeEffect->SetIsRunningOnCompositor(aProperty, true);
+    sentAnimations = true;
+  }
+
+  if (sentAnimations && aProperty == eCSSProperty_transform) {
+    TimeStamp now = aFrame->PresContext()->RefreshDriver()->MostRecentRefresh();
+    effects->UpdateLastTransformSyncTime(now);
   }
 }
 
 static bool
 GenerateAndPushTextMask(nsIFrame* aFrame, nsRenderingContext* aContext,
                         const nsRect& aFillRect, nsDisplayListBuilder* aBuilder)
 {
   if (aBuilder->IsForGenerateGlyphMask() ||