mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
722dd73447
It's possible to change the timeline if the animation is in pending. So we still need an animation tracker to track the scroll-linked animations. Besides, per the spec, we should keep this animation in pending if its timeline is inactive. So in this patch, we always put the scroll-linked animations into ScrollTimelineAnimationTracker, and if we change the timeline but the animation is still in pending, we move the animation into the correct animation tracker if needed. Using two different animation trackers because we would like to trigger scroll-linked animations after frame construction and reflow, and don't want to ensure the paint is scheduled. Note: 1. All tests in scroll-timeline-dynamic.tentative.html are failed. We will fix them in Bug 1774275. 2. Drop `animation-duration: infinite` from progress-based-animation-animation-longhand-properties.tentative.html, because infinite is not defined in animation-duration in [css-animations-1]. Differential Revision: https://phabricator.services.mozilla.com/D159650
114 lines
3.9 KiB
C++
114 lines
3.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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/. */
|
|
|
|
#ifndef mozilla_PendingAnimationTracker_h
|
|
#define mozilla_PendingAnimationTracker_h
|
|
|
|
#include "mozilla/dom/Animation.h"
|
|
#include "mozilla/TypedEnumBits.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsTHashSet.h"
|
|
|
|
class nsIFrame;
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
class Document;
|
|
}
|
|
|
|
/**
|
|
* Handle the pending animations which use document-timeline or null-timeline
|
|
* while playing or pausing.
|
|
*/
|
|
class PendingAnimationTracker final {
|
|
public:
|
|
explicit PendingAnimationTracker(dom::Document* aDocument);
|
|
|
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PendingAnimationTracker)
|
|
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PendingAnimationTracker)
|
|
|
|
void AddPlayPending(dom::Animation& aAnimation) {
|
|
// We'd like to assert here that IsWaitingToPause(aAnimation) is false but
|
|
// if |aAnimation| was tracked here as a pause-pending animation when it was
|
|
// removed from |mDocument|, then re-attached to |mDocument|, and then
|
|
// played again, we could end up here with IsWaitingToPause returning true.
|
|
//
|
|
// However, that should be harmless since all it means is that we'll call
|
|
// Animation::TriggerOnNextTick or Animation::TriggerNow twice, both of
|
|
// which will handle the redundant call gracefully.
|
|
AddPending(aAnimation, mPlayPendingSet);
|
|
mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
|
|
}
|
|
void RemovePlayPending(dom::Animation& aAnimation) {
|
|
RemovePending(aAnimation, mPlayPendingSet);
|
|
mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
|
|
}
|
|
bool IsWaitingToPlay(const dom::Animation& aAnimation) const {
|
|
return IsWaiting(aAnimation, mPlayPendingSet);
|
|
}
|
|
|
|
void AddPausePending(dom::Animation& aAnimation) {
|
|
// As with AddPausePending, we'd like to assert that
|
|
// IsWaitingToPlay(aAnimation) is false but there are some circumstances
|
|
// where this can be true. Fortunately adding the animation to both pending
|
|
// sets should be harmless.
|
|
AddPending(aAnimation, mPausePendingSet);
|
|
}
|
|
void RemovePausePending(dom::Animation& aAnimation) {
|
|
RemovePending(aAnimation, mPausePendingSet);
|
|
}
|
|
bool IsWaitingToPause(const dom::Animation& aAnimation) const {
|
|
return IsWaiting(aAnimation, mPausePendingSet);
|
|
}
|
|
|
|
void TriggerPendingAnimationsOnNextTick(const TimeStamp& aReadyTime);
|
|
void TriggerPendingAnimationsNow();
|
|
bool HasPendingAnimations() const {
|
|
return mPlayPendingSet.Count() > 0 || mPausePendingSet.Count() > 0;
|
|
}
|
|
|
|
/**
|
|
* Looks amongst the set of play-pending animations, and, if there are
|
|
* animations that affect geometric properties, notifies all play-pending
|
|
* animations so that they can be synchronized, if needed.
|
|
*/
|
|
void MarkAnimationsThatMightNeedSynchronization();
|
|
|
|
private:
|
|
~PendingAnimationTracker() = default;
|
|
|
|
void EnsurePaintIsScheduled();
|
|
|
|
using AnimationSet = nsTHashSet<nsRefPtrHashKey<dom::Animation>>;
|
|
|
|
void AddPending(dom::Animation& aAnimation, AnimationSet& aSet);
|
|
void RemovePending(dom::Animation& aAnimation, AnimationSet& aSet);
|
|
bool IsWaiting(const dom::Animation& aAnimation,
|
|
const AnimationSet& aSet) const;
|
|
|
|
AnimationSet mPlayPendingSet;
|
|
AnimationSet mPausePendingSet;
|
|
RefPtr<dom::Document> mDocument;
|
|
|
|
public:
|
|
enum class CheckState {
|
|
Indeterminate = 0,
|
|
Absent = 1 << 0,
|
|
AnimationsPresent = 1 << 1,
|
|
TransitionsPresent = 1 << 2,
|
|
};
|
|
|
|
private:
|
|
CheckState mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
|
|
};
|
|
|
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PendingAnimationTracker::CheckState)
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_PendingAnimationTracker_h
|