diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/animation/PendingAnimationTracker.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/animation/PendingAnimationTracker.h')
-rw-r--r-- | dom/animation/PendingAnimationTracker.h | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/dom/animation/PendingAnimationTracker.h b/dom/animation/PendingAnimationTracker.h new file mode 100644 index 0000000000..5fb277b7ef --- /dev/null +++ b/dom/animation/PendingAnimationTracker.h @@ -0,0 +1,113 @@ +/* -*- 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 |