Bug 1203009 part 4 - Implement new composite ordering; r=heycam

This commit is contained in:
Brian Birtles 2015-09-15 11:20:56 +09:00
parent e4d7fb9458
commit f7d6a90440
6 changed files with 65 additions and 23 deletions

View File

@ -517,11 +517,11 @@ Animation::UpdateRelevance()
bool
Animation::HasLowerCompositeOrderThan(const Animation& aOther) const
{
// We only ever sort non-idle animations so we don't ever expect
// mAnimationIndex to be set to kNoIndex
MOZ_ASSERT(mAnimationIndex != kNoIndex &&
aOther.mAnimationIndex != kNoIndex,
"Animations to compare should not be idle");
// Due to the way subclasses of this repurpose the mAnimationIndex to
// implement their own brand of composite ordering it is possible for
// two animations to have an identical mAnimationIndex member.
// However, these subclasses override this method so we shouldn't see
// identical animation indices here.
MOZ_ASSERT(mAnimationIndex != aOther.mAnimationIndex || &aOther == this,
"Animation indices should be unique");
@ -842,16 +842,6 @@ Animation::PauseAt(const TimeDuration& aReadyTime)
void
Animation::UpdateTiming(SeekFlag aSeekFlag, SyncNotifyFlag aSyncNotifyFlag)
{
// Update the animation index each time we transition in or out of the
// idle state
if (!IsUsingCustomCompositeOrder()) {
if (PlayState() == AnimationPlayState::Idle) {
mAnimationIndex = kNoIndex;
} else if (mAnimationIndex == kNoIndex) {
mAnimationIndex = sNextAnimationIndex++;
}
}
// We call UpdateFinishedState before UpdateEffect because the former
// can change the current time, which is used by the latter.
UpdateFinishedState(aSeekFlag, aSyncNotifyFlag);

View File

@ -57,7 +57,7 @@ public:
: DOMEventTargetHelper(aGlobal)
, mPlaybackRate(1.0)
, mPendingState(PendingState::NotPending)
, mAnimationIndex(kNoIndex)
, mAnimationIndex(sNextAnimationIndex++)
, mIsRunningOnCompositor(false)
, mFinishedAtLastComposeStyle(false)
, mIsRelevant(false)
@ -346,8 +346,8 @@ protected:
Async
};
void UpdateTiming(SeekFlag aSeekFlag,
SyncNotifyFlag aSyncNotifyFlag);
virtual void UpdateTiming(SeekFlag aSeekFlag,
SyncNotifyFlag aSyncNotifyFlag);
void UpdateFinishedState(SeekFlag aSeekFlag,
SyncNotifyFlag aSyncNotifyFlag);
void UpdateEffect();
@ -406,7 +406,6 @@ protected:
PendingState mPendingState;
static uint64_t sNextAnimationIndex;
static const uint64_t kNoIndex = UINT64_MAX;
// The relative position of this animation within the global animation list.
// This is kNoIndex while the animation is in the idle state and is updated

View File

@ -302,6 +302,18 @@ CSSAnimation::GetAnimationManager() const
return context->AnimationManager();
}
void
CSSAnimation::UpdateTiming(SeekFlag aSeekFlag, SyncNotifyFlag aSyncNotifyFlag)
{
if (mNeedsNewAnimationIndexWhenRun &&
PlayState() != AnimationPlayState::Idle) {
mAnimationIndex = sNextAnimationIndex++;
mNeedsNewAnimationIndexWhenRun = false;
}
Animation::UpdateTiming(aSeekFlag, aSyncNotifyFlag);
}
////////////////////////// nsAnimationManager ////////////////////////////
NS_IMPL_CYCLE_COLLECTION(nsAnimationManager, mEventDispatcher)

View File

@ -98,8 +98,21 @@ public:
void CancelFromStyle() override
{
mOwningElement = OwningElementRef();
// When an animation is disassociated with style it enters an odd state
// where its composite order is undefined until it first transitions
// out of the idle state.
//
// Even if the composite order isn't defined we don't want it to be random
// in case we need to determine the order to dispatch events associated
// with an animation in this state. To solve this we treat the animation as
// if it had been added to the end of the global animation list so that
// its sort order is defined. We'll update this index again once the
// animation leaves the idle state.
mAnimationIndex = sNextAnimationIndex++;
mNeedsNewAnimationIndexWhenRun = true;
Animation::CancelFromStyle();
MOZ_ASSERT(mAnimationIndex == kNoIndex);
}
void Tick() override;
@ -148,7 +161,11 @@ protected:
MOZ_ASSERT(!mOwningElement.IsSet(), "Owning element should be cleared "
"before a CSS animation is destroyed");
}
virtual CommonAnimationManager* GetAnimationManager() const override;
// Animation overrides
CommonAnimationManager* GetAnimationManager() const override;
void UpdateTiming(SeekFlag aSeekFlag,
SyncNotifyFlag aSyncNotifyFlag) override;
nsString mAnimationName;

View File

@ -112,6 +112,18 @@ CSSTransition::GetAnimationManager() const
return context->TransitionManager();
}
void
CSSTransition::UpdateTiming(SeekFlag aSeekFlag, SyncNotifyFlag aSyncNotifyFlag)
{
if (mNeedsNewAnimationIndexWhenRun &&
PlayState() != AnimationPlayState::Idle) {
mAnimationIndex = sNextAnimationIndex++;
mNeedsNewAnimationIndexWhenRun = false;
}
Animation::UpdateTiming(aSeekFlag, aSyncNotifyFlag);
}
void
CSSTransition::QueueEvents()
{

View File

@ -115,8 +115,17 @@ public:
void CancelFromStyle() override
{
mOwningElement = OwningElementRef();
// The animation index to use for compositing will be established when
// this transition next transitions out of the idle state but we still
// update it now so that the sort order of this transition remains
// defined until that moment.
//
// See longer explanation in CSSAnimation::CancelFromStyle.
mAnimationIndex = sNextAnimationIndex++;
mNeedsNewAnimationIndexWhenRun = true;
Animation::CancelFromStyle();
MOZ_ASSERT(mAnimationIndex == kNoIndex);
}
void Tick() override;
@ -151,7 +160,10 @@ protected:
"before a CSS transition is destroyed");
}
virtual CommonAnimationManager* GetAnimationManager() const override;
// Animation overrides
CommonAnimationManager* GetAnimationManager() const override;
void UpdateTiming(SeekFlag aSeekFlag,
SyncNotifyFlag aSyncNotifyFlag) override;
void QueueEvents();
bool HasEndEventToQueue() const override;