Bug 1341987 - Part 3: Update the last refresh time for transform only when we send transform animations to the compositor. r=birtles
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Mon, 27 Feb 2017 11:34:46 +0900
changeset 344995 81cfa489cb872e065067eefcad1a60487bb7d5a3
parent 344994 b2d04e22fa338410f1eb3922e58458922f647562
child 344996 64b46c83b0cd3e2878f491b4a3de9a7db85a7fca
push id31424
push usercbook@mozilla.com
push dateMon, 27 Feb 2017 13:07:01 +0000
treeherdermozilla-central@43f52c13c08d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles
bugs1341987
milestone54.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 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() ||