Bug 1073336 part 16 - Factor out animation-layer related information to a common database; r=dbaron
authorBrian Birtles <birtles@gmail.com>
Mon, 17 Nov 2014 13:46:00 +0900
changeset 215964 de062f18d6e178aadc8f3ca864ca72c0cd9117c9
parent 215963 375663351ae7ad66b91e8ef91a1a52a41960bca9
child 215965 1be1a3bc5cb63bbffb670082d932b8d30dd948fe
push id51898
push userbbirtles@mozilla.com
push dateMon, 17 Nov 2014 04:46:32 +0000
treeherdermozilla-inbound@2748f3c6b225 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1073336
milestone36.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 1073336 part 16 - Factor out animation-layer related information to a common database; r=dbaron
layout/base/RestyleManager.cpp
layout/style/AnimationCommon.cpp
layout/style/AnimationCommon.h
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -7,16 +7,17 @@
  * Code responsible for managing style changes: tracking what style
  * changes need to happen, scheduling them, and doing them.
  */
 
 #include <algorithm> // For std::max
 #include "RestyleManager.h"
 #include "mozilla/EventStates.h"
 #include "nsLayoutUtils.h"
+#include "AnimationCommon.h" // For GetLayerAnimationInfo
 #include "FrameLayerBuilder.h"
 #include "GeckoProfiler.h"
 #include "nsStyleChangeList.h"
 #include "nsRuleProcessorData.h"
 #include "nsStyleUtil.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsSVGEffects.h"
 #include "nsCSSRendering.h"
@@ -2429,47 +2430,40 @@ ElementRestyler::ElementRestyler(ParentC
   , mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
 #endif
 {
 }
 
 void
 ElementRestyler::AddLayerChangesForAnimation()
 {
-  static const nsDisplayItem::Type sLayerTypes[] =
-                                       { nsDisplayItem::TYPE_TRANSFORM,
-                                         nsDisplayItem::TYPE_OPACITY };
-  static const nsChangeHint sHints[] = { nsChangeHint_UpdateTransformLayer,
-                                         nsChangeHint_UpdateOpacityLayer };
-  static_assert(MOZ_ARRAY_LENGTH(sLayerTypes) == MOZ_ARRAY_LENGTH(sHints),
-                "Parallel layer type and hint arrays should have same length");
-
   // Bug 847286 - We should have separate animation generation counters
   // on layers for transitions and animations and use != comparison below
   // rather than a > comparison.
   uint64_t frameGeneration =
     RestyleManager::GetMaxAnimationGenerationForFrame(mFrame);
 
   nsChangeHint hint = nsChangeHint(0);
-  for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sLayerTypes); i++) {
+  const auto& layerInfo = css::CommonAnimationManager::sLayerAnimationInfo;
+  for (size_t i = 0; i < ArrayLength(layerInfo); i++) {
     Layer* layer =
-      FrameLayerBuilder::GetDedicatedLayer(mFrame, sLayerTypes[i]);
+      FrameLayerBuilder::GetDedicatedLayer(mFrame, layerInfo[i].mLayerType);
     if (layer && frameGeneration > layer->GetAnimationGeneration()) {
       // If we have a transform layer but don't have any transform style, we
       // probably just removed the transform but haven't destroyed the layer
       // yet. In this case we will add the appropriate change hint
       // (nsChangeHint_AddOrRemoveTransform) when we compare style contexts
       // so we can skip adding any change hint here. (If we *were* to add
       // nsChangeHint_UpdateTransformLayer, ApplyRenderingChangeToTree would
       // complain that we're updating a transform layer without a transform).
-      if (sLayerTypes[i] == nsDisplayItem::TYPE_TRANSFORM &&
+      if (layerInfo[i].mLayerType == nsDisplayItem::TYPE_TRANSFORM &&
           !mFrame->StyleDisplay()->HasTransformStyle()) {
         continue;
       }
-      NS_UpdateHint(hint, sHints[i]);
+      NS_UpdateHint(hint, layerInfo[i].mChangeHint);
     }
   }
   if (hint) {
     mChangeList->AppendChange(mFrame, mContent, hint);
   }
 }
 
 void
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -133,20 +133,22 @@ CommonAnimationManager::GetAnimationsFor
         AnimationPlayerCollection::CanAnimate_AllowPartial)) {
     return nullptr;
   }
 
   // This animation can be done on the compositor.
   // Mark the frame as active, in case we are able to throttle this animation.
   nsIFrame* frame = nsLayoutUtils::GetStyleFrame(collection->mElement);
   if (frame) {
-    if (aProperty == eCSSProperty_opacity) {
-      ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_opacity);
-    } else if (aProperty == eCSSProperty_transform) {
-      ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_transform);
+    const auto& info = sLayerAnimationInfo;
+    for (size_t i = 0; i < ArrayLength(info); i++) {
+      if (aProperty == info[i].mProperty) {
+        ActiveLayerTracker::NotifyAnimated(frame, aProperty);
+        break;
+      }
     }
   }
 
   return collection;
 }
 
 /*
  * nsISupports implementation
@@ -250,16 +252,25 @@ CommonAnimationManager::ExtractComputedV
                         StyleAnimationValue::eUnit_Enumerated,
                       "unexpected unit");
     aComputedValue.SetIntValue(aComputedValue.GetIntValue(),
                                StyleAnimationValue::eUnit_Visibility);
   }
   return result;
 }
 
+/* static */ const CommonAnimationManager::LayerAnimationRecord
+  CommonAnimationManager::sLayerAnimationInfo[] =
+    { { eCSSProperty_transform,
+        nsDisplayItem::TYPE_TRANSFORM,
+        nsChangeHint_UpdateTransformLayer },
+      { eCSSProperty_opacity,
+        nsDisplayItem::TYPE_OPACITY,
+        nsChangeHint_UpdateOpacityLayer } };
+
 NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
 
 /* virtual */ void
 AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
 {
   nsStyleContext *contextParent = aRuleData->mStyleContext->GetParent();
   if (contextParent && contextParent->HasPseudoElementData()) {
     // Don't apply transitions or animations to things inside of
@@ -630,37 +641,37 @@ AnimationPlayerCollection::CanThrottleTr
 bool
 AnimationPlayerCollection::CanThrottleAnimation(TimeStamp aTime)
 {
   nsIFrame* frame = nsLayoutUtils::GetStyleFrame(mElement);
   if (!frame) {
     return false;
   }
 
-  bool hasTransform = HasAnimationOfProperty(eCSSProperty_transform);
-  bool hasOpacity = HasAnimationOfProperty(eCSSProperty_opacity);
-  if (hasOpacity) {
+
+  const auto& info = css::CommonAnimationManager::sLayerAnimationInfo;
+  for (size_t i = 0; i < ArrayLength(info); i++) {
+    auto record = info[i];
+    if (!HasAnimationOfProperty(record.mProperty)) {
+      continue;
+    }
+
     Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
-                     frame, nsDisplayItem::TYPE_OPACITY);
+                     frame, record.mLayerType);
     if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
       return false;
     }
+
+    if (record.mProperty == eCSSProperty_transform &&
+        !CanThrottleTransformChanges(aTime)) {
+      return false;
+    }
   }
 
-  if (!hasTransform) {
-    return true;
-  }
-
-  Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
-                   frame, nsDisplayItem::TYPE_TRANSFORM);
-  if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
-    return false;
-  }
-
-  return CanThrottleTransformChanges(aTime);
+  return true;
 }
 
 void
 AnimationPlayerCollection::UpdateAnimationGeneration(
   nsPresContext* aPresContext)
 {
   mAnimationGeneration =
     aPresContext->RestyleManager()->GetAnimationGeneration();
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -5,17 +5,19 @@
 
 #ifndef mozilla_css_AnimationCommon_h
 #define mozilla_css_AnimationCommon_h
 
 #include "nsIStyleRuleProcessor.h"
 #include "nsIStyleRule.h"
 #include "nsRefreshDriver.h"
 #include "prclist.h"
+#include "nsChangeHint.h"
 #include "nsCSSProperty.h"
+#include "nsDisplayList.h" // For nsDisplayItem::Type
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/AnimationPlayer.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Nullable.h"
 #include "nsStyleStruct.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Assertions.h"
@@ -80,16 +82,30 @@ public:
     Cannot_Throttle
   };
 
   static bool ExtractComputedValueForTransition(
                   nsCSSProperty aProperty,
                   nsStyleContext* aStyleContext,
                   mozilla::StyleAnimationValue& aComputedValue);
 
+  // For CSS properties that may be animated on a separate layer, represents
+  // a record of the corresponding layer type and change hint.
+  struct LayerAnimationRecord {
+    nsCSSProperty mProperty;
+    nsDisplayItem::Type mLayerType;
+    nsChangeHint mChangeHint;
+  };
+
+protected:
+  static const size_t kLayerRecords = 2;
+
+public:
+  static const LayerAnimationRecord sLayerAnimationInfo[kLayerRecords];
+
 protected:
   virtual ~CommonAnimationManager();
 
   // For ElementCollectionRemoved
   friend struct mozilla::AnimationPlayerCollection;
 
   void AddElementCollection(AnimationPlayerCollection* aCollection);
   void ElementCollectionRemoved() { CheckNeedsRefresh(); }