Bug 1203009 part 3 - Add mNeedsNewAnimationIndexWhenRun flag to CSSAnimation and CSSTransition; r=heycam
authorBrian Birtles <birtles@gmail.com>
Tue, 15 Sep 2015 11:20:33 +0900
changeset 297007 b7af8129961f8f9401923debb1de40d73c90ae72
parent 297006 5196bf0855ad3c9317f58faf727c0203d9963b0d
child 297008 37b6deedaab676639f504ad9c263486c0062da18
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1203009
milestone43.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 1203009 part 3 - Add mNeedsNewAnimationIndexWhenRun flag to CSSAnimation and CSSTransition; r=heycam In the new composite order arrangement CSSAnimations and CSSTransition have the following life-cycle: 1. Animation created by markup => composite order determined by markup (e.g. CSS animations use tree order and animation-name order; CSS transitions use transition trigger order) 2. Animation cancelled by changing markup => composite order is undefined 3. Animation is played again using the API => composite order is defined by when the animation is first played. Another way of saying this is that, at the point when the animation is played, it is appended to the "global animation list". 4. Animation is subsequently cancelled / played => no change We need a way to know when we are going from 2 to 3. It would seem like we could do that by setting mAnimationIndex to some sentinel value while it is in 2. However, even when in 2, although the spec doesn't define the composite order animations at this point (from an API point of view you can't access these objects and they don't contribute to style so it doesn't need to be defined), we sometimes will need to establish an order. This can happen, for example, when an animation queues events and then is later cancelled before the events are dispatched. Because we sort events based on their associated animation at the time of dispatch (for performance reasons) we need a deterministic order for these idle animations. We do that (in a subsequent patch in this series) by setting mAnimationIndex when we transition from 1 to 2. That is, these idle animations are effectively ordered by when they became idle (which always happens in a deterministic fashion).
layout/style/nsAnimationManager.h
layout/style/nsTransitionManager.h
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -58,16 +58,17 @@ class CSSAnimation final : public Animat
 {
 public:
  explicit CSSAnimation(nsIGlobalObject* aGlobal,
                        const nsSubstring& aAnimationName)
     : dom::Animation(aGlobal)
     , mAnimationName(aAnimationName)
     , mIsStylePaused(false)
     , mPauseShouldStick(false)
+    , mNeedsNewAnimationIndexWhenRun(false)
     , mPreviousPhaseOrIteration(PREVIOUS_PHASE_BEFORE)
   {
     // We might need to drop this assertion once we add a script-accessible
     // constructor but for animations generated from CSS markup the
     // animation-name should never be empty.
     MOZ_ASSERT(!mAnimationName.IsEmpty(), "animation-name should not be empty");
   }
 
@@ -218,16 +219,20 @@ protected:
   // E. Paused by animation-play-state
   //    (mIsPaused; mIsStylePaused; !mPauseShouldStick)
   //
   // (That leaves 3 combinations of the boolean values that we never set because
   // they don't represent valid states.)
   bool mIsStylePaused;
   bool mPauseShouldStick;
 
+  // When true, indicates that when this animation next leaves the idle state,
+  // its animation index should be updated.
+  bool mNeedsNewAnimationIndexWhenRun;
+
   enum {
     PREVIOUS_PHASE_BEFORE = uint64_t(-1),
     PREVIOUS_PHASE_AFTER = uint64_t(-2)
   };
   // One of the PREVIOUS_PHASE_* constants, or an integer for the iteration
   // whose start we last notified on.
   uint64_t mPreviousPhaseOrIteration;
 };
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -80,16 +80,17 @@ struct ElementPropertyTransition : publi
 namespace dom {
 
 class CSSTransition final : public Animation
 {
 public:
  explicit CSSTransition(nsIGlobalObject* aGlobal)
     : dom::Animation(aGlobal)
     , mWasFinishedOnLastTick(false)
+    , mNeedsNewAnimationIndexWhenRun(false)
   {
   }
 
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
 
   CSSTransition* AsCSSTransition() override { return this; }
   const CSSTransition* AsCSSTransition() const override { return this; }
@@ -170,16 +171,20 @@ protected:
   //    transition-property or removing the owning element from the document),
   // c) If this object is generated from script using the CSSTransition
   //    constructor.
   //
   // For (b) and (c) the owning element will return !IsSet().
   OwningElementRef mOwningElement;
 
   bool mWasFinishedOnLastTick;
+
+  // When true, indicates that when this transition next leaves the idle state,
+  // its animation index should be updated.
+  bool mNeedsNewAnimationIndexWhenRun;
 };
 
 } // namespace dom
 
 struct TransitionEventInfo {
   nsCOMPtr<nsIContent> mElement;
   InternalTransitionEvent mEvent;