Bug 1333846 - Part 1: Move ContainsAnimatedScale() codes into dom/animation/. r=birtles a=gchang
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Thu, 09 Feb 2017 11:28:47 +0900
changeset 378360 e77ccea909001c46cb84cd7fd0e5809343e8bc83
parent 378359 44133d6f9edc3a1f85d5327b17aee98dfaecbdec
child 378361 a6a8ca19a0112bd6e4ab098e48ffc64a6c5a7229
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles, gchang
bugs1333846
milestone53.0a2
Bug 1333846 - Part 1: Move ContainsAnimatedScale() codes into dom/animation/. r=birtles a=gchang MozReview-Commit-ID: 6bWeTfCmjtd
dom/animation/AnimationUtils.cpp
dom/animation/AnimationUtils.h
dom/animation/KeyframeEffectReadOnly.cpp
dom/animation/KeyframeEffectReadOnly.h
layout/painting/ActiveLayerTracker.cpp
--- a/dom/animation/AnimationUtils.cpp
+++ b/dom/animation/AnimationUtils.cpp
@@ -8,16 +8,18 @@
 
 #include "nsDebug.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsGlobalWindow.h"
 #include "nsString.h"
 #include "xpcpublic.h" // For xpc::NativeGlobal
+#include "mozilla/EffectSet.h"
+#include "mozilla/dom/KeyframeEffectReadOnly.h"
 #include "mozilla/Preferences.h"
 
 namespace mozilla {
 
 /* static */ void
 AnimationUtils::LogAsyncAnimationFailure(nsCString& aMessage,
                                          const nsIContent* aContent)
 {
@@ -78,9 +80,22 @@ AnimationUtils::IsCoreAPIEnabled()
 }
 
 /* static */ bool
 AnimationUtils::IsCoreAPIEnabledForCaller(dom::CallerType aCallerType)
 {
   return IsCoreAPIEnabled() || aCallerType == dom::CallerType::System;
 }
 
+/* static */ bool
+AnimationUtils::EffectSetContainsAnimatedScale(EffectSet& aEffects,
+                                               const nsIFrame* aFrame)
+{
+  for (const dom::KeyframeEffectReadOnly* effect : aEffects) {
+    if (effect->ContainsAnimatedScale(aFrame)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 } // namespace mozilla
--- a/dom/animation/AnimationUtils.h
+++ b/dom/animation/AnimationUtils.h
@@ -9,21 +9,23 @@
 
 #include "mozilla/TimeStamp.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Nullable.h"
 #include "nsStringFwd.h"
 
 class nsIContent;
 class nsIDocument;
+class nsIFrame;
 struct JSContext;
 
 namespace mozilla {
 
 class ComputedTimingFunction;
+class EffectSet;
 
 class AnimationUtils
 {
 public:
   static dom::Nullable<double>
   TimeDurationToDouble(const dom::Nullable<TimeDuration>& aTime)
   {
     dom::Nullable<double> result;
@@ -68,13 +70,20 @@ public:
    */
   static bool IsCoreAPIEnabled();
 
   /**
    * Returns true if the preference to enable the core Web Animations API is
    * true or the caller is chrome.
    */
   static bool IsCoreAPIEnabledForCaller(dom::CallerType aCallerType);
+
+  /**
+   * Returns true if the given EffectSet contains a current effect that animates
+   * scale. |aFrame| is used for calculation of scale values.
+   */
+  static bool EffectSetContainsAnimatedScale(EffectSet& aEffects,
+                                             const nsIFrame* aFrame);
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -1692,10 +1692,37 @@ KeyframeEffectReadOnly::NeedsBaseStyle(n
     }
   }
   MOZ_ASSERT_UNREACHABLE(
     "Expected a property that can be run on the compositor");
 
   return false;
 }
 
+bool
+KeyframeEffectReadOnly::ContainsAnimatedScale(const nsIFrame* aFrame) const
+{
+  if (!IsCurrent()) {
+    return false;
+  }
+
+  for (const AnimationProperty& prop : mProperties) {
+    if (prop.mProperty != eCSSProperty_transform) {
+      continue;
+    }
+
+    for (const AnimationPropertySegment& segment : prop.mSegments) {
+      gfxSize from = segment.mFromValue.GetScaleValue(aFrame);
+      if (from != gfxSize(1.0f, 1.0f)) {
+        return true;
+      }
+      gfxSize to = segment.mToValue.GetScaleValue(aFrame);
+      if (to != gfxSize(1.0f, 1.0f)) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -347,16 +347,20 @@ public:
   // See nsChangeHint_Hints_CanIgnoreIfNotVisible in nsChangeHint.h
   // in detail which change hint can be ignored.
   bool CanIgnoreIfNotVisible() const;
 
   // Returns true if the effect is run on the compositor for |aProperty| and
   // needs a base style to composite with.
   bool NeedsBaseStyle(nsCSSPropertyID aProperty) const;
 
+  // Returns true if the effect is current state and has scale animation.
+  // |aFrame| is used for calculation of scale values.
+  bool ContainsAnimatedScale(const nsIFrame* aFrame) const;
+
 protected:
   KeyframeEffectReadOnly(nsIDocument* aDocument,
                          const Maybe<OwningAnimationTarget>& aTarget,
                          AnimationEffectTimingReadOnly* aTiming,
                          const KeyframeEffectParams& aOptions);
 
   ~KeyframeEffectReadOnly() override = default;
 
--- a/layout/painting/ActiveLayerTracker.cpp
+++ b/layout/painting/ActiveLayerTracker.cpp
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ActiveLayerTracker.h"
 
+#include "mozilla/AnimationUtils.h"
 #include "mozilla/ArrayUtils.h"
-#include "mozilla/dom/KeyframeEffectReadOnly.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/PodOperations.h"
 #include "gfx2DGlue.h"
 #include "nsExpirationTracker.h"
 #include "nsContainerFrame.h"
 #include "nsIContent.h"
 #include "nsRefreshDriver.h"
@@ -468,59 +468,30 @@ ActiveLayerTracker::IsOffsetOrMarginStyl
   // We should also check for running CSS animations of these properties once
   // bug 1009693 is fixed. Until that happens, layerization isn't useful for
   // animations of these properties because we'll invalidate the layer contents
   // on every change anyway.
   // See bug 1151346 for a patch that adds a check for CSS animations.
   return false;
 }
 
-// A helper function for IsScaleSubjectToAnimation which returns true if the
-// given EffectSet contains a current effect that animates scale.
-static bool
-ContainsAnimatedScale(EffectSet& aEffects, nsIFrame* aFrame)
-{
-  for (dom::KeyframeEffectReadOnly* effect : aEffects) {
-    if (!effect->IsCurrent()) {
-      continue;
-    }
-
-    for (const AnimationProperty& prop : effect->Properties()) {
-      if (prop.mProperty != eCSSProperty_transform) {
-        continue;
-      }
-      for (AnimationPropertySegment segment : prop.mSegments) {
-        gfxSize from = segment.mFromValue.GetScaleValue(aFrame);
-        if (from != gfxSize(1.0f, 1.0f)) {
-          return true;
-        }
-        gfxSize to = segment.mToValue.GetScaleValue(aFrame);
-        if (to != gfxSize(1.0f, 1.0f)) {
-          return true;
-        }
-      }
-    }
-  }
-
-  return false;
-}
-
 /* static */ bool
 ActiveLayerTracker::IsScaleSubjectToAnimation(nsIFrame* aFrame)
 {
   // Check whether JavaScript is animating this frame's scale.
   LayerActivity* layerActivity = GetLayerActivity(aFrame);
   if (layerActivity && layerActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE] >= 2) {
     return true;
   }
 
   // Check if any animations, transitions, etc. associated with this frame may
   // animate its scale.
   EffectSet* effects = EffectSet::GetEffectSet(aFrame);
-  if (effects && ContainsAnimatedScale(*effects, aFrame)) {
+  if (effects &&
+      AnimationUtils::EffectSetContainsAnimatedScale(*effects, aFrame)) {
     return true;
   }
 
   return false;
 }
 
 /* static */ void
 ActiveLayerTracker::NotifyContentChange(nsIFrame* aFrame)