Bug 1230056 part 1 - Add EffectCompositor::HasAnimationsForCompositor; r=dholbert
authorBrian Birtles <birtles@gmail.com>
Wed, 09 Dec 2015 16:28:10 -0500
changeset 310151 2c97313b585702013d6a9fe8e8165401df8664aa
parent 310150 d11cceb2f732fa9c52a7743ee3b835e457ba35ab
child 310152 6ff143ef49ebce4663092109c9e6affd3ec1aa17
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1230056
milestone45.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 1230056 part 1 - Add EffectCompositor::HasAnimationsForCompositor; r=dholbert
dom/animation/EffectCompositor.cpp
dom/animation/EffectCompositor.h
dom/animation/EffectSet.h
layout/base/nsLayoutUtils.cpp
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -12,57 +12,96 @@
 #include "mozilla/EffectSet.h"
 #include "nsLayoutUtils.h"
 
 using mozilla::dom::Animation;
 using mozilla::dom::KeyframeEffectReadOnly;
 
 namespace mozilla {
 
-/* static */ nsTArray<RefPtr<dom::Animation>>
-EffectCompositor::GetAnimationsForCompositor(const nsIFrame* aFrame,
-                                             nsCSSProperty aProperty)
+// Helper function to factor out the common logic from
+// GetAnimationsForCompositor and HasAnimationsForCompositor.
+//
+// Takes an optional array to fill with eligible animations.
+//
+// Returns true if there are eligible animations, false otherwise.
+bool
+FindAnimationsForCompositor(const nsIFrame* aFrame,
+                            nsCSSProperty aProperty,
+                            nsTArray<RefPtr<dom::Animation>>* aMatches /*out*/)
 {
-  nsTArray<RefPtr<dom::Animation>> result;
+  MOZ_ASSERT(!aMatches || aMatches->IsEmpty(),
+             "Matches array, if provided, should be empty");
+
+  EffectSet* effects = EffectSet::GetEffectSet(aFrame);
+  if (!effects || effects->IsEmpty()) {
+    return false;
+  }
+
+  if (aFrame->RefusedAsyncAnimation()) {
+    return false;
+  }
 
   if (!nsLayoutUtils::AreAsyncAnimationsEnabled()) {
     if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
       nsCString message;
       message.AppendLiteral("Performance warning: Async animations are "
                             "disabled");
       AnimationUtils::LogAsyncAnimationFailure(message);
     }
-    return result;
+    return false;
   }
 
-  if (aFrame->RefusedAsyncAnimation()) {
-    return result;
-  }
-
-  EffectSet* effects = EffectSet::GetEffectSet(aFrame);
-  if (!effects) {
-    return result;
-  }
-
+  bool foundSome = false;
   for (KeyframeEffectReadOnly* effect : *effects) {
     MOZ_ASSERT(effect && effect->GetAnimation());
     Animation* animation = effect->GetAnimation();
 
     if (!animation->IsPlaying()) {
       continue;
     }
 
     if (effect->ShouldBlockCompositorAnimations(aFrame)) {
-      result.Clear();
-      return result;
+      if (aMatches) {
+        aMatches->Clear();
+      }
+      return false;
     }
 
     if (!effect->HasAnimationOfProperty(aProperty)) {
       continue;
     }
 
-    result.AppendElement(animation);
+    if (aMatches) {
+      aMatches->AppendElement(animation);
+    }
+    foundSome = true;
   }
 
+  MOZ_ASSERT(!foundSome || !aMatches || !aMatches->IsEmpty(),
+             "If return value is true, matches array should be non-empty");
+  return foundSome;
+}
+
+/* static */ bool
+EffectCompositor::HasAnimationsForCompositor(const nsIFrame* aFrame,
+                                             nsCSSProperty aProperty)
+{
+  return FindAnimationsForCompositor(aFrame, aProperty, nullptr);
+}
+
+/* static */ nsTArray<RefPtr<dom::Animation>>
+EffectCompositor::GetAnimationsForCompositor(const nsIFrame* aFrame,
+                                             nsCSSProperty aProperty)
+{
+  nsTArray<RefPtr<dom::Animation>> result;
+
+#ifdef DEBUG
+  bool foundSome =
+#endif
+    FindAnimationsForCompositor(aFrame, aProperty, &result);
+  MOZ_ASSERT(!foundSome || !result.IsEmpty(),
+             "If return value is true, matches array should be non-empty");
+
   return result;
 }
 
 } // namespace mozilla
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -14,16 +14,19 @@ namespace mozilla {
 
 namespace dom {
 class Animation;
 }
 
 class EffectCompositor
 {
 public:
+  static bool HasAnimationsForCompositor(const nsIFrame* aFrame,
+                                         nsCSSProperty aProperty);
+
   static nsTArray<RefPtr<dom::Animation>>
   GetAnimationsForCompositor(const nsIFrame* aFrame,
                              nsCSSProperty aProperty);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_EffectCompositor_h
--- a/dom/animation/EffectSet.h
+++ b/dom/animation/EffectSet.h
@@ -113,16 +113,17 @@ public:
     bool mIsEndIterator;
   };
 
   Iterator begin() { return Iterator(mEffects.Iter()); }
   Iterator end()
   {
     return Iterator::EndIterator(mEffects.Iter());
   }
+  bool IsEmpty() const { return mEffects.IsEmpty(); }
 
   static nsIAtom** GetEffectSetPropertyAtoms();
 
 private:
   static nsIAtom* GetEffectSetPropertyAtom(nsCSSPseudoElements::Type
                                              aPseudoType);
 
   OwningEffectSet mEffects;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -369,20 +369,17 @@ FloatLogicalValuesEnabledPrefChangeCallb
   nsCSSProps::kClearKTable[sIndexOfInlineEndInClearTable].mKeyword =
     isFloatLogicalValuesEnabled ? eCSSKeyword_inline_end : eCSSKeyword_UNKNOWN;
 }
 
 bool
 nsLayoutUtils::HasAnimationsForCompositor(const nsIFrame* aFrame,
                                           nsCSSProperty aProperty)
 {
-  // XXX Bug 1230056 - Add EffectCompositor::HasAnimationsForCompositor to
-  // avoid allocating an array here only to throw it away.
-  return !EffectCompositor::GetAnimationsForCompositor(aFrame,
-                                                       aProperty).IsEmpty();
+  return !EffectCompositor::HasAnimationsForCompositor(aFrame, aProperty);
 }
 
 template<typename TestType>
 static bool
 HasMatchingCurrentAnimations(const nsIFrame* aFrame, TestType&& aTest)
 {
   EffectSet* effects = EffectSet::GetEffectSet(aFrame);
   if (!effects) {